From 0c25783ceea79ab0365456e82a3f1f1f923154ad Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 8 Feb 2007 06:43:28 +0000 Subject: [PATCH] use dn2id index for extended filters using entryDN --- servers/slapd/back-bdb/dn2id.c | 24 ++++----- servers/slapd/back-bdb/filterindex.c | 73 ++++++++++++++++++++++++---- servers/slapd/back-bdb/proto-bdb.h | 3 +- servers/slapd/back-bdb/search.c | 12 ++--- 4 files changed, 84 insertions(+), 28 deletions(-) diff --git a/servers/slapd/back-bdb/dn2id.c b/servers/slapd/back-bdb/dn2id.c index c4f7cfac5e..eff601e38e 100644 --- a/servers/slapd/back-bdb/dn2id.c +++ b/servers/slapd/back-bdb/dn2id.c @@ -333,7 +333,8 @@ int bdb_dn2idl( Operation *op, u_int32_t locker, - Entry *e, + struct berval *ndn, + EntryInfo *ei, ID *ids, ID *stack ) { @@ -345,22 +346,22 @@ bdb_dn2idl( ? DN_ONE_PREFIX : DN_SUBTREE_PREFIX; Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2idl(\"%s\")\n", - e->e_nname.bv_val, 0, 0 ); + ndn->bv_val, 0, 0 ); #ifndef BDB_MULTIPLE_SUFFIXES - if ( prefix == DN_SUBTREE_PREFIX && BEI(e)->bei_parent->bei_id == 0 ) { + if ( prefix == DN_SUBTREE_PREFIX && ei->bei_parent->bei_id == 0 ) { BDB_IDL_ALL(bdb, ids); return 0; } #endif DBTzero( &key ); - key.size = e->e_nname.bv_len + 2; + key.size = ndn->bv_len + 2; key.ulen = key.size; key.flags = DB_DBT_USERMEM; key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx ); ((char *)key.data)[0] = prefix; - AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 ); + AC_MEMCPY( &((char *)key.data)[1], ndn->bv_val, key.size - 1 ); BDB_IDL_ZERO( ids ); rc = bdb_idl_fetch_key( op->o_bd, db, locker, &key, ids, NULL, 0 ); @@ -1063,7 +1064,8 @@ int hdb_dn2idl( Operation *op, u_int32_t locker, - Entry *e, + struct berval *ndn, + EntryInfo *ei, ID *ids, ID *stack ) { @@ -1071,20 +1073,20 @@ hdb_dn2idl( struct dn2id_cookie cx; Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2idl(\"%s\")\n", - e->e_nname.bv_val, 0, 0 ); + ndn->bv_val, 0, 0 ); #ifndef BDB_MULTIPLE_SUFFIXES if ( op->ors_scope != LDAP_SCOPE_ONELEVEL && - BEI(e)->bei_parent->bei_id == 0 ) + ei->bei_parent->bei_id == 0 ) { BDB_IDL_ALL( bdb, ids ); return 0; } #endif - cx.id = e->e_id; + cx.id = ei->bei_id; BDB_ID2DISK( cx.id, &cx.nid ); - cx.ei = e->e_id ? BEI(e) : &bdb->bi_cache.c_dntree; + cx.ei = ei; cx.bdb = bdb; cx.db = cx.bdb->bi_dn2id->bdi_db; cx.prefix = (op->ors_scope == LDAP_SCOPE_ONELEVEL) ? @@ -1121,7 +1123,7 @@ hdb_dn2idl( cx.key.data = ptr; cx.key.size = sizeof(ID)+1; *ptr = cx.prefix; - cx.id = e->e_id; + cx.id = ei->bei_id; if ( cx.bdb->bi_idl_cache_max_size ) bdb_idl_cache_put( cx.bdb, cx.db, &cx.key, cx.ids, cx.rc ); } diff --git a/servers/slapd/back-bdb/filterindex.c b/servers/slapd/back-bdb/filterindex.c index 07b269fb29..e88395f784 100644 --- a/servers/slapd/back-bdb/filterindex.c +++ b/servers/slapd/back-bdb/filterindex.c @@ -66,7 +66,6 @@ static int list_candidates( ID *tmp, ID *stack ); -#ifdef LDAP_COMP_MATCH static int ext_candidates( Operation *op, @@ -76,6 +75,7 @@ ext_candidates( ID *tmp, ID *stack); +#ifdef LDAP_COMP_MATCH static int comp_candidates ( Operation *op, @@ -204,12 +204,10 @@ bdb_filter_candidates( rc = list_candidates( op, locker, f->f_or, LDAP_FILTER_OR, ids, tmp, stack ); break; -#ifdef LDAP_COMP_MATCH case LDAP_FILTER_EXT: Debug( LDAP_DEBUG_FILTER, "\tEXT\n", 0, 0, 0 ); rc = ext_candidates( op, locker, f->f_mra, ids, tmp, stack ); break; -#endif default: Debug( LDAP_DEBUG_FILTER, "\tUNKNOWN %lu\n", (unsigned long) f->f_choice, 0, 0 ); @@ -480,6 +478,7 @@ comp_candidates ( return( rc ); } +#endif static int ext_candidates( @@ -490,19 +489,75 @@ ext_candidates( ID *tmp, ID *stack) { + struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; + +#ifdef LDAP_COMP_MATCH /* * Currently Only Component Indexing for componentFilterMatch is supported * Indexing for an extensible filter is not supported yet */ - if ( !mra->ma_cf ) { - struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; - BDB_IDL_ALL( bdb, ids ); - return 0; + if ( mra->ma_cf ) { + return comp_candidates ( op, locker, mra, mra->ma_cf, ids, tmp, stack); + } +#endif + if ( mra->ma_desc == slap_schema.si_ad_entryDN ) { + int rc; + EntryInfo *ei; + + BDB_IDL_ZERO( ids ); + if ( mra->ma_rule == slap_schema.si_mr_distinguishedNameMatch ) { + ei = NULL; + rc = bdb_cache_find_ndn( op, NULL, &mra->ma_value, &ei ); + if ( rc == LDAP_SUCCESS ) + bdb_idl_insert( ids, ei->bei_id ); + if ( ei ) + bdb_cache_entryinfo_unlock( ei ); + return 0; + } else if ( mra->ma_rule && mra->ma_rule->smr_match == + dnRelativeMatch && dnIsSuffix( &mra->ma_value, + op->o_bd->be_nsuffix )) { + int scope; + if ( mra->ma_rule == slap_schema.si_mr_dnSuperiorMatch ) { + struct berval pdn; + ei = NULL; + dnParent( &mra->ma_value, &pdn ); + bdb_cache_find_ndn( op, NULL, &pdn, &ei ); + if ( ei ) { + bdb_cache_entryinfo_unlock( ei ); + while ( ei && ei->bei_id ) { + bdb_idl_insert( ids, ei->bei_id ); + ei = ei->bei_parent; + } + } + return 0; + } + if ( mra->ma_rule == slap_schema.si_mr_dnSubtreeMatch ) + scope = LDAP_SCOPE_SUBTREE; + else if ( mra->ma_rule == slap_schema.si_mr_dnOneLevelMatch ) + scope = LDAP_SCOPE_ONELEVEL; + else if ( mra->ma_rule == slap_schema.si_mr_dnSubordinateMatch ) + scope = LDAP_SCOPE_SUBORDINATE; + else + scope = LDAP_SCOPE_BASE; + if ( scope > LDAP_SCOPE_BASE ) { + ei = NULL; + rc = bdb_cache_find_ndn( op, NULL, &mra->ma_value, &ei ); + if ( ei ) + bdb_cache_entryinfo_unlock( ei ); + if ( rc == LDAP_SUCCESS ) { + int sc = op->ors_scope; + op->ors_scope = scope; + rc = bdb_dn2idl( op, locker, &mra->ma_value, ei, ids, + stack ); + } + return 0; + } + } } - return comp_candidates ( op, locker, mra, mra->ma_cf, ids, tmp, stack); + BDB_IDL_ALL( bdb, ids ); + return 0; } -#endif static int list_candidates( diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index 5e28fddbff..77aaf6c688 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -121,7 +121,8 @@ int bdb_dn2id_children( int bdb_dn2idl( Operation *op, u_int32_t locker, - Entry *e, + struct berval *ndn, + EntryInfo *ei, ID *ids, ID *stack ); diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index 5ae4e887a3..0a42b63dca 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -206,7 +206,7 @@ static int search_aliases( * to the cumulative list of candidates. */ BDB_IDL_CPY( curscop, aliases ); - rs->sr_err = bdb_dn2idl( op, locker, e, subscop, + rs->sr_err = bdb_dn2idl( op, locker, &e->e_nname, BEI(e), subscop, subscop2+BDB_IDL_DB_SIZE ); if (first) { first = 0; @@ -313,7 +313,7 @@ bdb_search( Operation *op, SlapReply *rs ) ID scopes[BDB_IDL_DB_SIZE]; Entry *e = NULL, base, e_root = {0}; Entry *matched = NULL; - EntryInfo *ei, ei_root = {0}; + EntryInfo *ei; struct berval realbase = BER_BVNULL; slap_mask_t mask; int manageDSAit; @@ -350,13 +350,11 @@ bdb_search( Operation *op, SlapReply *rs ) if ( op->o_req_ndn.bv_len == 0 ) { /* DIT root special case */ - ei_root.bei_e = &e_root; - ei_root.bei_parent = &ei_root; - e_root.e_private = &ei_root; + ei = &bdb->bi_cache.c_dntree; + e_root.e_private = ei; e_root.e_id = 0; BER_BVSTR( &e_root.e_nname, "" ); BER_BVSTR( &e_root.e_name, "" ); - ei = &ei_root; rs->sr_err = LDAP_SUCCESS; } else { if ( op->ors_deref & LDAP_DEREF_FINDING ) { @@ -1100,7 +1098,7 @@ static int search_candidates( if( op->ors_deref & LDAP_DEREF_SEARCHING ) { rc = search_aliases( op, rs, e, locker, ids, scopes, stack ); } else { - rc = bdb_dn2idl( op, locker, e, ids, stack ); + rc = bdb_dn2idl( op, locker, &e->e_nname, BEI(e), ids, stack ); } if ( rc == LDAP_SUCCESS ) { -- 2.39.5