mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-01 20:49:35 -05:00
Use quicksort instead of heapsort for hdb_idl_sort
This commit is contained in:
parent
52cf1f5f0a
commit
2dd87ed9e6
2 changed files with 60 additions and 31 deletions
|
|
@ -1297,43 +1297,71 @@ int bdb_idl_append( ID *a, ID *b )
|
|||
|
||||
}
|
||||
|
||||
/* Sort an IDL using HeapSort */
|
||||
static void
|
||||
siftDown(ID *ids, int root, int bottom)
|
||||
{
|
||||
int child;
|
||||
ID temp;
|
||||
/* Quicksort + Insertion sort for small arrays */
|
||||
|
||||
temp = ids[root];
|
||||
while ((child=root*2) <= bottom) {
|
||||
if (child < bottom && ids[child] < ids[child + 1])
|
||||
child++;
|
||||
|
||||
if (temp >= ids[child])
|
||||
break;
|
||||
ids[root] = ids[child];
|
||||
root = child;
|
||||
}
|
||||
ids[root] = temp;
|
||||
}
|
||||
#define SMALL 8
|
||||
#define SWAP(a,b) a^=b;b^=a;a^=b /* Swap integers without temp var */
|
||||
|
||||
void
|
||||
bdb_idl_sort( ID *ids )
|
||||
{
|
||||
int i;
|
||||
ID temp;
|
||||
int istack[BDB_IDL_LOGN*4];
|
||||
int i,j,k,l,ir,jstack;
|
||||
ID a;
|
||||
|
||||
if ( BDB_IDL_IS_RANGE( ids ))
|
||||
return;
|
||||
|
||||
for (i = ids[0] / 2; i >= 1; i--)
|
||||
siftDown(ids, i, ids[0]);
|
||||
|
||||
for (i = ids[0]; i > 1; i--)
|
||||
{
|
||||
temp = ids[i];
|
||||
ids[i] = ids[1];
|
||||
ids[1] = temp;
|
||||
siftDown(ids, 1, i-1);
|
||||
ir = ids[0];
|
||||
l = 1;
|
||||
jstack = 0;
|
||||
for(;;) {
|
||||
if (ir - l < SMALL) { /* Insertion sort */
|
||||
for (j=l+1;j<=ir;j++) {
|
||||
a = ids[j];
|
||||
for (i=j-1;i>=1;i--) {
|
||||
if (ids[i] <= a) break;
|
||||
ids[i+1] = ids[i];
|
||||
}
|
||||
ids[i+1] = a;
|
||||
}
|
||||
if (jstack == 0) break;
|
||||
ir = istack[jstack--];
|
||||
l = istack[jstack--];
|
||||
} else {
|
||||
k = (l + ir) >> 1; /* Choose median of left, center, right */
|
||||
SWAP(ids[k], ids[l+1]);
|
||||
if (ids[l] > ids[ir]) {
|
||||
SWAP(ids[l], ids[ir]);
|
||||
}
|
||||
if (ids[l+1] > ids[ir]) {
|
||||
SWAP(ids[l+1], ids[ir]);
|
||||
}
|
||||
if (ids[l] > ids[l+1]) {
|
||||
SWAP(ids[l], ids[l+1]);
|
||||
}
|
||||
i = l+1;
|
||||
j = ir;
|
||||
a = ids[l+1];
|
||||
for(;;) {
|
||||
do i++; while(ids[i] < a);
|
||||
do j--; while(ids[j] > a);
|
||||
if (j < i) break;
|
||||
SWAP(ids[i],ids[j]);
|
||||
}
|
||||
ids[l+1] = ids[j];
|
||||
ids[j] = a;
|
||||
jstack += 2;
|
||||
assert(jstack <= BDB_IDL_LOGN*4);
|
||||
if (ir-i+1 >= j-1) {
|
||||
istack[jstack] = ir;
|
||||
istack[jstack-1] = i;
|
||||
ir = j-1;
|
||||
} else {
|
||||
istack[jstack] = j-1;
|
||||
istack[jstack-1] = l;
|
||||
l = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@
|
|||
/* IDL sizes - likely should be even bigger
|
||||
* limiting factors: sizeof(ID), thread stack size
|
||||
*/
|
||||
#define BDB_IDL_DB_SIZE (1<<16) /* 64K IDL on disk */
|
||||
#define BDB_IDL_UM_SIZE (1<<17) /* 128K IDL in memory */
|
||||
#define BDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */
|
||||
#define BDB_IDL_DB_SIZE (1<<BDB_IDL_LOGN)
|
||||
#define BDB_IDL_UM_SIZE (1<<(BDB_IDL_LOGN+1))
|
||||
#define BDB_IDL_UM_SIZEOF (BDB_IDL_UM_SIZE * sizeof(ID))
|
||||
|
||||
#define BDB_IDL_DB_MAX (BDB_IDL_DB_SIZE-1)
|
||||
|
|
|
|||
Loading…
Reference in a new issue