ID2 id2;
char *ptr;
int rc = 0;
- unsigned int x;
+ unsigned int x, y;
unsigned int nrlen, rlen;
diskNode *d;
return MDB_SUCCESS;
}
+ isc->sctmp[0].mid = 0;
while (id) {
if ( !rc ) {
key.mv_data = &id;
isc->numrdns++;
if (!rc && id != isc->id) {
+ /* remember our chain of parents */
id2.mid = id;
id2.mval = data;
- mdb_id2l_insert( isc->scopes, &id2 );
+ mdb_id2l_insert( isc->sctmp, &id2 );
}
ptr = data.mv_data;
ptr += data.mv_size - sizeof(ID);
memcpy( &id, ptr, sizeof(ID) );
+ y = x;
x = mdb_id2l_search( isc->scopes, id );
if ( x <= isc->scopes[0].mid && isc->scopes[x].mid == id ) {
if ( !isc->scopes[x].mval.mv_data ) {
+ /* This node is in scope, add parent chain to scope */
+ int i = isc->sctmp[0].mid;
+ for ( i = 1; i <= isc->sctmp[0].mid; i++ )
+ mdb_id2l_insert( isc->scopes, &isc->sctmp[i] );
+ /* check id again since inserts may have changed its position */
+ if ( isc->scopes[x].mid != id )
+ x = mdb_id2l_search( isc->scopes, id );
isc->nscope = x;
return MDB_SUCCESS;
}
data = isc->scopes[x].mval;
rc = 1;
+ } else {
+ /* If we didn't advance, some parent is missing */
+ if ( x == y )
+ return MDB_NOTFOUND;
}
if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
break;
MDB_txn *txn,
MDB_cursor *mci,
ID *ids,
- ID2L scopes );
+ ID2L scopes,
+ ID *stack );
static int parse_paged_cookie( Operation *op, SlapReply *rs );
(void *)scopes, scope_chunk_free, NULL, NULL );
}
+static void *search_stack( Operation *op );
+
int
mdb_search( Operation *op, SlapReply *rs )
{
ID candidates[MDB_IDL_UM_SIZE];
ID iscopes[MDB_IDL_DB_SIZE];
ID2 *scopes;
+ void *stack;
Entry *e = NULL, *base = NULL;
Entry *matched = NULL;
AttributeName *attrs;
}
scopes = scope_chunk_get( op );
+ stack = search_stack( op );
isc.mt = ltid;
isc.mc = mcd;
isc.scopes = scopes;
isc.oscope = op->ors_scope;
+ isc.sctmp = stack;
if ( op->ors_deref & LDAP_DEREF_FINDING ) {
MDB_IDL_ZERO(candidates);
scopes[1].mid = base->e_id;
scopes[1].mval.mv_data = NULL;
rs->sr_err = search_candidates( op, rs, base,
- ltid, mci, candidates, scopes );
+ ltid, mci, candidates, scopes, stack );
ncand = MDB_IDL_N( candidates );
if ( !base->e_id || ncand == NOID ) {
/* grab entry count from id2entry stat
MDB_txn *txn,
MDB_cursor *mci,
ID *ids,
- ID2L scopes )
+ ID2L scopes,
+ ID *stack )
{
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
int rc, depth = 1;
Filter *f, rf, xf, nf, sf;
- ID *stack;
AttributeAssertion aa_ref = ATTRIBUTEASSERTION_INIT;
AttributeAssertion aa_subentry = ATTRIBUTEASSERTION_INIT;
/* Allocate IDL stack, plus 1 more for former tmp */
if ( depth+1 > mdb->mi_search_stack_depth ) {
stack = ch_malloc( (depth + 1) * MDB_IDL_UM_SIZE * sizeof( ID ) );
- } else {
- stack = search_stack( op );
}
if( op->ors_deref & LDAP_DEREF_SEARCHING ) {