ID dbuf;
ID *ids;
void *ptr;
- ID tmp[BDB_IDL_UM_SIZE];
+ ID *tmp;
ID *buf;
DBT key;
DBT data;
DBC *dbc;
Operation *op;
+ int need_sort;
};
static int
saveit:
if ( !BDB_IDL_IS_RANGE( cx->tmp ) && cx->tmp[0] > 1 )
- bdb_idl_sort( cx->tmp );
+ bdb_idl_sort( cx->tmp, cx->buf );
if ( cx->bdb->bi_idl_cache_max_size ) {
cx->key.data = &cx->id;
bdb_idl_cache_put( cx->bdb, cx->db, &cx->key, cx->tmp, cx->rc );
gotit:
if ( !BDB_IDL_IS_ZERO( cx->tmp )) {
if ( cx->prefix == DN_SUBTREE_PREFIX ) {
- bdb_idl_merge( cx->ids, cx->tmp );
+ bdb_idl_append( cx->ids, cx->tmp );
+ cx->need_sort = 1;
if ( !(cx->ei->bei_state & CACHE_ENTRY_NO_GRANDKIDS)) {
ID *save, idcurs;
EntryInfo *ei = cx->ei;
cx.prefix = (op->ors_scope == LDAP_SCOPE_ONELEVEL) ?
DN_ONE_PREFIX : DN_SUBTREE_PREFIX;
cx.ids = ids;
- cx.buf = stack;
+ cx.tmp = stack;
+ cx.buf = stack + BDB_IDL_UM_SIZE;
cx.op = op;
+ cx.need_sort = 0;
BDB_IDL_ZERO( ids );
if ( cx.prefix == DN_SUBTREE_PREFIX ) {
DBTzero(&cx.data);
hdb_dn2idl_internal(&cx);
+ if ( cx.need_sort && !BDB_IDL_IS_RANGE( cx.ids ) && cx.ids[0] > 1 )
+ bdb_idl_sort( cx.ids, cx.tmp );
return cx.rc;
}
return 0;
}
-/* Merge sorted list b to sorted list a. There are no common values
- * in list a and b.
+/* Append sorted list b to sorted list a. The result is unsorted but
+ * a[1] is the min of the result and a[a[0]] is the max.
*/
-int bdb_idl_merge( ID *a, ID *b )
+int bdb_idl_append( ID *a, ID *b )
{
- ID ida, idb;
- ID cursora, cursorb, cursorc;
+ ID ida, idb, tmp;
if ( BDB_IDL_IS_ZERO( b ) ) {
return 0;
return 0;
}
+ ida = BDB_IDL_LAST( a );
+ idb = BDB_IDL_LAST( b );
if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) ||
a[0] + b[0] >= BDB_IDL_UM_MAX ) {
- ida = BDB_IDL_LAST( a );
- idb = BDB_IDL_LAST( b );
a[2] = IDL_MAX( ida, idb );
a[1] = IDL_MIN( a[1], b[1] );
a[0] = NOID;
return 0;
}
- cursora = a[0];
- cursorb = b[0];
- cursorc = cursora + cursorb;
- a[0] = cursorc;
+ if ( b[0] > 1 && ida > idb ) {
+ a[a[0]] = idb;
+ b[b[0]] = ida;
+ }
- while ( cursorc > 0 ) {
- if ( b[cursorb] > a[cursora] ) {
- a[cursorc] = b[cursorb];
- cursorb--;
- if ( !cursorb )
- break;
- } else {
- if ( cursora == cursorc )
- break;
- a[cursorc] = a[cursora];
- cursora --;
- }
- cursorc--;
+ if ( b[1] < a[1] ) {
+ tmp = a[1];
+ a[1] = b[1];
+ } else {
+ tmp = b[1];
+ }
+ a[0]++;
+ a[a[0]] = tmp;
+
+ if ( b[0] > 1 ) {
+ int i = b[0] - 1;
+ AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID));
+ a[0] += i;
}
return 0;
}
#define SMALL 8
#define SWAP(a,b) a^=b;b^=a;a^=b /* Swap integers without temp var */
-#define ISTACK ((BDB_IDL_LOGN+1)*4)
-
void
-bdb_idl_sort( ID *ids )
+bdb_idl_sort( ID *ids, ID *tmp )
{
- int istack[ISTACK];
+ int *istack = (int *)tmp;
int i,j,k,l,ir,jstack;
ID a;
ids[l+1] = ids[j];
ids[j] = a;
jstack += 2;
- assert(jstack <= ISTACK);
if (ir-i+1 >= j-1) {
istack[jstack] = ir;
istack[jstack-1] = i;
#define bdb_idl_intersection BDB_SYMBOL(idl_intersection)
#define bdb_idl_union BDB_SYMBOL(idl_union)
#define bdb_idl_sort BDB_SYMBOL(idl_sort)
-#define bdb_idl_merge BDB_SYMBOL(idl_merge)
+#define bdb_idl_append BDB_SYMBOL(idl_append)
#define bdb_idl_append_one BDB_SYMBOL(idl_append_one)
#define bdb_idl_fetch_key BDB_SYMBOL(idl_fetch_key)
ID bdb_idl_first( ID *ids, ID *cursor );
ID bdb_idl_next( ID *ids, ID *cursor );
-void bdb_idl_sort( ID *ids );
+void bdb_idl_sort( ID *ids, ID *tmp );
int bdb_idl_append( ID *a, ID *b );
int bdb_idl_append_one( ID *ids, ID id );