@@ -1671,10 +1671,14 @@ zvect_retval vect_sem_post(ivector v) {
1671
1671
}
1672
1672
1673
1673
/*
1674
+ TODO: Implement this function:
1675
+
1674
1676
static inline zvect_retval p_vect_wait_for_signal(const vector v) {
1675
1677
return (locking_disabled || (v->flags & ZV_NOLOCKING)) ? 1 : wait_for_signal(v, 3);
1676
1678
}
1677
1679
1680
+ and also:
1681
+
1678
1682
inline zvect_retval vect_wait_for_signal(const vector v) {
1679
1683
return p_vect_wait_for_signal(v);
1680
1684
}
@@ -2468,6 +2472,90 @@ void vect_qsort(ivector v, int (*compare_func)(const void *, const void *)) {
2468
2472
p_throw_error (rval , NULL );
2469
2473
}
2470
2474
2475
+ #ifdef TRADITIONAL_BINARY_SEARCH
2476
+ static bool p_standard_binary_search (vector v , const void * key ,
2477
+ zvect_index * item_index ,
2478
+ int (* f1 )(const void * , const void * ));
2479
+ #else
2480
+ static bool p_adaptive_binary_search (ivector v , const void * key ,
2481
+ zvect_index * item_index ,
2482
+ int (* f1 )(const void * , const void * ));
2483
+ #endif
2484
+
2485
+ /*
2486
+ * Although if the vect_add_* doesn't belong to this group of
2487
+ * functions, the vect_add_ordered is an exception because it
2488
+ * requires vect_bserach and vect_qsort to be available.
2489
+ */
2490
+ void vect_add_ordered (ivector v , const void * value ,
2491
+ int (* f1 )(const void * , const void * )) {
2492
+ // Check parameters:
2493
+ if (value == NULL )
2494
+ return ;
2495
+
2496
+ // check if the vector exists:
2497
+ zvect_retval rval = p_vect_check (v );
2498
+ if (rval )
2499
+ goto VECT_ADD_ORD_JOB_DONE ;
2500
+
2501
+ #if (ZVECT_THREAD_SAFE == 1 )
2502
+ zvect_retval lock_owner = (locking_disabled || (v -> flags & ZV_NOLOCKING )) ? 0 : get_mutex_lock (v , 2 );
2503
+ #endif
2504
+
2505
+ // Few tricks to make it faster:
2506
+ zvect_index vsize = p_vect_size (v );
2507
+ if (vsize == 0 ) {
2508
+ // If the vector is empty clearly we can just
2509
+ // use vect_add and add the value normally!
2510
+ vect_add (v , value );
2511
+ goto VECT_ADD_ORD_DONE_PROCESSING ;
2512
+ }
2513
+
2514
+ if ((* f1 )(value , v -> data [v -> begin + (vsize - 1 )]) > 0 ) {
2515
+ // If the compare function returns that
2516
+ // the value passed should go after the
2517
+ // last value in the vector, just do so!
2518
+ vect_add (v , value );
2519
+ goto VECT_ADD_ORD_DONE_PROCESSING ;
2520
+ }
2521
+
2522
+ // Ok previous checks didn't help us, so we need
2523
+ // to get "heavy weapons" out and find where in
2524
+ // the vector we should add "value":
2525
+ zvect_index item_index = 0 ;
2526
+
2527
+ // Here is another trick:
2528
+ // I improved adaptive binary search to ALWAYS
2529
+ // return an index (even when it doesn't find a
2530
+ // searched item), this works for both: regular
2531
+ // searches which will also use the bool to
2532
+ // know if we actually found the item in that
2533
+ // item_index or not and the vect_add_ordered
2534
+ // which will use item_index (which will be the
2535
+ // place where value should have been) to insert
2536
+ // value as an ordered item :)
2537
+ #ifdef TRADITIONAL_BINARY_SEARCH
2538
+ p_standard_binary_search (v , value , & item_index , f1 );
2539
+ #else
2540
+ p_adaptive_binary_search (v , value , & item_index , f1 );
2541
+ #endif
2542
+
2543
+ vect_add_at (v , value , item_index );
2544
+
2545
+ VECT_ADD_ORD_DONE_PROCESSING :
2546
+ #if (ZVECT_THREAD_SAFE == 1 )
2547
+ if (lock_owner )
2548
+ get_mutex_unlock (v , 2 );
2549
+ #endif
2550
+
2551
+ VECT_ADD_ORD_JOB_DONE :
2552
+ if (rval )
2553
+ p_throw_error (rval , NULL );
2554
+ }
2555
+
2556
+
2557
+ // Searching Algorithms:
2558
+
2471
2559
#ifdef TRADITIONAL_BINARY_SEARCH
2472
2560
static bool p_standard_binary_search (vector v , const void * key ,
2473
2561
zvect_index * item_index ,
@@ -2521,7 +2609,7 @@ static bool p_adaptive_binary_search(ivector v, const void *key,
2521
2609
bot = v -> bottom ;
2522
2610
top = 32 ;
2523
2611
2524
- // key >= array[bot]
2612
+ // the following evaluation correspond to: key >= array[bot]
2525
2613
if ((* f1 )(key , v -> data [v -> begin + bot ]) >= 0 ) {
2526
2614
while (1 ) {
2527
2615
if ((bot + top ) >= p_vect_size (v )) {
@@ -2530,7 +2618,7 @@ static bool p_adaptive_binary_search(ivector v, const void *key,
2530
2618
}
2531
2619
bot += top ;
2532
2620
2533
- // the meaning of the line below is key < array[bot]
2621
+ // the meaning of the line below is: key < array[bot]
2534
2622
if ((* f1 )(key , v -> data [v -> begin + bot ]) < 0 ) {
2535
2623
bot -= top ;
2536
2624
break ;
@@ -2546,7 +2634,7 @@ static bool p_adaptive_binary_search(ivector v, const void *key,
2546
2634
}
2547
2635
bot -= top ;
2548
2636
2549
- // the meaning of the line below is key >= array[bot]
2637
+ // the meaning of the line below is: key >= array[bot]
2550
2638
if ((* f1 )(key , v -> data [v -> begin + bot ]) >= 0 )
2551
2639
break ;
2552
2640
top *= 2 ;
@@ -2556,7 +2644,7 @@ static bool p_adaptive_binary_search(ivector v, const void *key,
2556
2644
P_ADP_BSEARCH_MONOBOUND :
2557
2645
while (top > 3 ) {
2558
2646
mid = top / 2 ;
2559
- // key >= array[bot + mid]
2647
+ // the meaning of the following statement is: key >= array[bot + mid]
2560
2648
if ((* f1 )(key , v -> data [v -> begin + (bot + mid )]) >= 0 )
2561
2649
bot += mid ;
2562
2650
top -= mid ;
@@ -2566,7 +2654,7 @@ static bool p_adaptive_binary_search(ivector v, const void *key,
2566
2654
v -> bottom = bot ;
2567
2655
2568
2656
while (top ) {
2569
- // key == array[bot + --top]
2657
+ // the meaning of the following statement is: key == array[bot + --top]
2570
2658
int test = (* f1 )(key , v -> data [v -> begin + (bot + (-- top ))]);
2571
2659
if (test == 0 ) {
2572
2660
* item_index = bot + top ;
@@ -2580,16 +2668,17 @@ static bool p_adaptive_binary_search(ivector v, const void *key,
2580
2668
* item_index = bot + top ;
2581
2669
return false;
2582
2670
}
2583
- #endif // ! TRADITIONAL_BINARY_SEARCH
2671
+ #endif // ADAPTIVE TRADITIONAL_BINARY_SEARCH
2584
2672
2585
2673
bool vect_bsearch (ivector v , const void * key ,
2586
2674
int (* f1 )(const void * , const void * ),
2587
2675
zvect_index * item_index ) {
2676
+ * item_index = 0 ;
2677
+
2588
2678
// Check parameters:
2589
2679
if ((key == NULL ) || (f1 == NULL ) || (p_vect_size (v ) == 0 ))
2590
2680
return false;
2591
2681
2592
- * item_index = 0 ;
2593
2682
// check if the vector exists:
2594
2683
zvect_retval rval = p_vect_check (v );
2595
2684
if (rval )
@@ -2612,7 +2701,7 @@ bool vect_bsearch(ivector v, const void *key,
2612
2701
* item_index = 0 ;
2613
2702
return false;
2614
2703
}
2615
- #endif // ! TRADITIONAL_BINARY_SEARCH
2704
+ #endif // ADAPTIVE TRADITIONAL_BINARY_SEARCH
2616
2705
2617
2706
// VECT_BSEARCH_DONE_PROCESSING:
2618
2707
// TODO: Add mutex unlock
@@ -2624,71 +2713,58 @@ bool vect_bsearch(ivector v, const void *key,
2624
2713
return false;
2625
2714
}
2626
2715
2627
- /*
2628
- * Although if the vect_add_* doesn't belong to this group of
2629
- * functions, the vect_add_ordered is an exception because it
2630
- * requires vect_bserach and vect_qsort to be available.
2631
- */
2632
- void vect_add_ordered ( ivector v , const void * value ,
2633
- int ( * f1 )( const void * , const void * )) {
2716
+ // Traditional Linear Search Algorithm,
2717
+ // useful with non sorted vectors:
2718
+ bool vect_lsearch ( ivector v , const void * key ,
2719
+ int ( * f1 )( const void * , const void * ),
2720
+ zvect_index * item_index ) {
2721
+ * item_index = 0 ;
2722
+
2634
2723
// Check parameters:
2635
- if (value == NULL )
2636
- return ;
2724
+ if (( key == NULL ) || ( f1 == NULL ) || ( p_vect_size ( v ) == 0 ) )
2725
+ return false ;
2637
2726
2638
2727
// check if the vector exists:
2639
2728
zvect_retval rval = p_vect_check (v );
2640
2729
if (rval )
2641
- goto VECT_ADD_ORD_JOB_DONE ;
2642
-
2643
- #if (ZVECT_THREAD_SAFE == 1 )
2644
- zvect_retval lock_owner = (locking_disabled || (v -> flags & ZV_NOLOCKING )) ? 0 : get_mutex_lock (v , 2 );
2645
- #endif
2730
+ goto VECT_LSEARCH_JOB_DONE ;
2646
2731
2647
- // Few tricks to make it faster:
2732
+ // TODO: Add mutex locking
2648
2733
zvect_index vsize = p_vect_size (v );
2649
- if (vsize == 0 ) {
2650
- // If the vector is empty clearly we can just
2651
- // use vect_add and add the value normally!
2652
- vect_add (v , value );
2653
- goto VECT_ADD_ORD_DONE_PROCESSING ;
2654
- }
2655
-
2656
- if ((* f1 )(value , v -> data [v -> begin + (vsize - 1 )]) > 0 ) {
2657
- // If the compare function returns that
2658
- // the value passed should go after the
2659
- // last value in the vector, just do so!
2660
- vect_add (v , value );
2661
- goto VECT_ADD_ORD_DONE_PROCESSING ;
2734
+ if ((vsize & (1 <<0 ))== 0 && (vsize > 4 )) {
2735
+ for (register zvect_index x = 0 ; x < vsize ; x += 4 ) {
2736
+ if ((* f1 )(key , v -> data [v -> begin + x ]) != 0 ) {
2737
+ * item_index = x ;
2738
+ return true;
2739
+ }
2740
+ if ((* f1 )(key , v -> data [v -> begin + (x + 1 )]) != 0 ) {
2741
+ * item_index = x ;
2742
+ return true;
2743
+ }
2744
+ if ((* f1 )(key , v -> data [v -> begin + (x + 2 )]) != 0 ) {
2745
+ * item_index = x ;
2746
+ return true;
2747
+ }
2748
+ if ((* f1 )(key , v -> data [v -> begin + (x + 3 )]) != 0 ) {
2749
+ * item_index = x ;
2750
+ return true;
2751
+ }
2752
+ }
2753
+ } else {
2754
+ for (register zvect_index x = 0 ; x < vsize ; x ++ ) {
2755
+ if ((* f1 )(key , v -> data [v -> begin + x ]) != 0 ) {
2756
+ * item_index = x ;
2757
+ return true;
2758
+ }
2759
+ }
2662
2760
}
2663
2761
2664
- // Ok previous checks didn't help us, so we need
2665
- // to get "heavy weapons" out and find where in
2666
- // the vector we should add "value":
2667
- zvect_index item_index = 0 ;
2668
-
2669
- // Here is another trick:
2670
- // I improved adaptive binary search to ALWAYS
2671
- // return an index (even when it doesn't find a
2672
- // searched item), this works for both: regular
2673
- // searches which will also use the bool to
2674
- // know if we actually found the item in that
2675
- // item_index or not and the vect_add_ordered
2676
- // which will use item_index (which will be the
2677
- // place where value should have been) to insert
2678
- // value as an ordered item :)
2679
- p_adaptive_binary_search (v , value , & item_index , f1 );
2680
-
2681
- vect_add_at (v , value , item_index );
2682
-
2683
- VECT_ADD_ORD_DONE_PROCESSING :
2684
- #if (ZVECT_THREAD_SAFE == 1 )
2685
- if (lock_owner )
2686
- get_mutex_unlock (v , 2 );
2687
- #endif
2688
-
2689
- VECT_ADD_ORD_JOB_DONE :
2690
- if (rval )
2762
+ VECT_LSEARCH_JOB_DONE :
2763
+ if (rval )
2691
2764
p_throw_error (rval , NULL );
2765
+
2766
+ * item_index = 0 ;
2767
+ return false;
2692
2768
}
2693
2769
2694
2770
#endif // ZVECT_DMF_EXTENSIONS
0 commit comments