int partition(Item a[], int l, int r) { int i = l; /* left index */ int j = r-1; /* right index */ Item v = a[r]; /* v is the partitioning element */ do { /* pre-increment sets i to l on first iteration */ while (LESS(a[i], v)) /* scan until >= */ { ++i; } while (j>i && !(LESS(a[j],v))) { /* scan until <, or until end of array */ --j; } if (i < j) EXCH(a[i], a[j]); } while(i < j); /* after partition, exchange a[i] with partition element */ EXCH(a[i], a[r]); return i; }
static double find_ordered_entry_with_flags(double *x, int n, int index, int *flags) { int u, v, l, r; double temp; double piv; int pivind; assert(index >= 0); /* If this bit of the array is already sorted, simple! */ if (flags[index]) { return x[index]; } /* Find subrange to look at */ u = v = index; while (u > 0 && !flags[u]) u--; if (flags[u]) u++; while (v < (n-1) && !flags[v]) v++; if (flags[v]) v--; do { if (v - u < 2) { if (x[v] < x[u]) { EXCH(x[v], x[u]); } flags[v] = flags[u] = 1; return x[index]; } else { pivind = (u + v) >> 1; EXCH(x[u], x[pivind]); piv = x[u]; /* New value */ l = u + 1; r = v; do { while (l < v && x[l] < piv) l++; while (x[r] > piv) r--; if (r <= l) break; EXCH(x[l], x[r]); l++; r--; } while (1); EXCH(x[u], x[r]); flags[r] = 1; /* Pivot now in correct place */ if (index == r) { return x[r]; } else if (index < r) { v = r - 1; } else if (index > r) { u = l; } } } while (1); }
void camFPKdTreeFixUp(CamFPKdTreeBranch *pqueue, int k) { CamFPKdTreeBranch tmp; while (k > 0 && pqueue[(k-1)/2].distance > pqueue[k].distance) { EXCH((k-1)/2, k); k = (k-1)/2; } }
CamFPKdTreeBranch *camFPKdTreeGetmin(CamFPKdTreeBranch *pqueue, int *N) { CamFPKdTreeBranch tmp; if (*N == 0) return NULL; (*N)--; EXCH(0, *N); camFPKdTreeFixDown(pqueue, 0, *N); return &pqueue[*N]; }
void camFPKdTreeFixDown(CamFPKdTreeBranch *pqueue, int k, int N) { int j; CamFPKdTreeBranch tmp; while (2*k+1 < N) { j = 2*k+1; if (j < N-1 && pqueue[j].distance > pqueue[j+1].distance) j++; if (!(pqueue[k].distance > pqueue[j].distance)) break; EXCH(k, j); k = j; } }
void insertion_sort(Item a[], int left, int right) { int i, j; for(i=left; i<=right; i++) { j=i; while(j>left && LESS(a[j],a[j-1])) { EXCH(a[j-1],a[j]); j--; } } }
void selection_sort(Item a[], int left, int right) { int i, j; int min; for(i=left; i<right; i++) { min = i; for(j=i+1; j<=right; j++) { if( LESS(a[j],a[min]) ) min = j; } EXCH(a[i],a[min]); } }
int slap_sort_vals( Modifications *ml, const char **text, int *dup, void *ctx ) { AttributeDescription *ad; MatchingRule *mr; int istack[sizeof(int)*16]; int i, j, k, l, ir, jstack, match, *ix, itmp, nvals, rc = LDAP_SUCCESS; int is_norm; struct berval a, *cv; #define SMALL 8 #define SWAP(a,b,tmp) tmp=(a);(a)=(b);(b)=tmp #define COMP(a,b) match=0; rc = ordered_value_match( &match, \ ad, mr, SLAP_MR_EQUALITY \ | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX \ | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH \ | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, \ &(a), &(b), text ); #define IX(x) ix[x] #define EXCH(x,y) SWAP(ix[x],ix[y],itmp) #define SETA(x) itmp = ix[x]; a = cv[itmp] #define GETA(x) ix[x] = itmp; #define SET(x,y) ix[x] = ix[y] ad = ml->sml_desc; nvals = ml->sml_numvals; if ( nvals <= 1 ) goto ret; /* For Modifications, sml_nvalues is NULL if normalization wasn't needed. * For Attributes, sml_nvalues == sml_values when normalization isn't needed. */ if ( ml->sml_nvalues && ml->sml_nvalues != ml->sml_values ) { cv = ml->sml_nvalues; is_norm = 1; } else { cv = ml->sml_values; is_norm = 0; } if ( ad == slap_schema.si_ad_objectClass ) mr = NULL; /* shortcut matching */ else mr = ad->ad_type->sat_equality; /* record indices to preserve input ordering */ ix = slap_sl_malloc( nvals * sizeof(int), ctx ); for (i=0; i<nvals; i++) ix[i] = i; ir = nvals-1; l = 0; jstack = 0; for(;;) { if (ir - l < SMALL) { /* Insertion sort */ match=1; for (j=l+1;j<=ir;j++) { SETA(j); for (i=j-1;i>=0;i--) { COMP(cv[IX(i)], a); if ( match <= 0 ) break; SET(i+1,i); } GETA(i+1); if ( match == 0 ) goto done; } if ( jstack == 0 ) break; if ( match == 0 ) break; ir = istack[jstack--]; l = istack[jstack--]; } else { k = (l + ir) >> 1; /* Choose median of left, center, right */ EXCH(k, l+1); COMP( cv[IX(l)], cv[IX(ir)] ); if ( match > 0 ) { EXCH(l, ir); } else if ( match == 0 ) { i = ir; break; } COMP( cv[IX(l+1)], cv[IX(ir)] ); if ( match > 0 ) { EXCH(l+1, ir); } else if ( match == 0 ) { i = ir; break; } COMP( cv[IX(l)], cv[IX(l+1)] ); if ( match > 0 ) { EXCH(l, l+1); } else if ( match == 0 ) { i = l; break; } i = l+1; j = ir; a = cv[IX(i)]; for(;;) { do { i++; COMP( cv[IX(i)], a ); } while( match < 0 ); while( match > 0 ) { j--; COMP( cv[IX(j)], a ); } if (j < i) { match = 1; break; } if ( match == 0 ) { i = l+1; break; } EXCH(i,j); } if ( match == 0 ) break; EXCH(l+1,j); jstack += 2; if (ir-i+1 >= j) { istack[jstack] = ir; istack[jstack-1] = i; ir = j; } else { istack[jstack] = j; istack[jstack-1] = l; l = i; } } } done: if ( match == 0 && i >= 0 ) *dup = ix[i]; /* For sorted attributes, put the values in index order */ if ( rc == LDAP_SUCCESS && match && ( ad->ad_type->sat_flags & SLAP_AT_SORTED_VAL )) { BerVarray tmpv = slap_sl_malloc( sizeof( struct berval ) * nvals, ctx ); for ( i = 0; i<nvals; i++ ) tmpv[i] = cv[ix[i]]; for ( i = 0; i<nvals; i++ ) cv[i] = tmpv[i]; /* Check if the non-normalized array needs to move too */ if ( is_norm ) { cv = ml->sml_values; for ( i = 0; i<nvals; i++ ) tmpv[i] = cv[ix[i]]; for ( i = 0; i<nvals; i++ ) cv[i] = tmpv[i]; } slap_sl_free( tmpv, ctx ); } slap_sl_free( ix, ctx ); if ( rc == LDAP_SUCCESS && match == 0 ) { /* value exists already */ assert( i >= 0 ); assert( i < nvals ); rc = LDAP_TYPE_OR_VALUE_EXISTS; } ret: return rc; }