]> git.sur5r.net Git - openldap/commitdiff
Mem context tweaks for bdb_dn2idl
authorHoward Chu <hyc@openldap.org>
Tue, 22 Apr 2003 06:29:13 +0000 (06:29 +0000)
committerHoward Chu <hyc@openldap.org>
Tue, 22 Apr 2003 06:29:13 +0000 (06:29 +0000)
servers/slapd/back-bdb/dn2id.c
servers/slapd/back-bdb/filterindex.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/search.c

index 72178a6fe2b0ce53b1658f60e7504cec184a721b..32511ce863c82d137ab3c37cb840f957b4ffb8f0 100644 (file)
@@ -416,7 +416,8 @@ bdb_dn2idl(
        BackendDB       *be,
        struct berval   *dn,
        int prefix,
-       ID *ids )
+       ID *ids,
+       void *ctx )
 {
        int             rc;
        DBT             key;
@@ -442,7 +443,7 @@ bdb_dn2idl(
        key.size = dn->bv_len + 2;
        key.ulen = key.size;
        key.flags = DB_DBT_USERMEM;
-       key.data = ch_malloc( key.size );
+       key.data = sl_malloc( key.size, ctx );
        ((char *)key.data)[0] = prefix;
        AC_MEMCPY( &((char *)key.data)[1], dn->bv_val, key.size - 1 );
 
@@ -472,7 +473,7 @@ bdb_dn2idl(
 #endif
        }
 
-       ch_free( key.data );
+       sl_free( key.data, ctx );
        return rc;
 }
 #else  /* BDB_HIER */
@@ -480,6 +481,7 @@ bdb_dn2idl(
 /* Experimental management routines for a hierarchically structured database.
  *
  * Unsupported! Use at your own risk!
+ * -- Howard Chu, Symas Corp. 2003.
  *
  * Instead of a ldbm-style dn2id database, we use a hierarchical one. Each
  * entry in this database is a struct diskNode, keyed by entryID and with
@@ -581,7 +583,8 @@ bdb_dn2id_add(
        if (nrlen) {
                rlen = dn_rdnlen( be, &e->e_name );
        } else {
-               rlen = 0;
+               nrlen = e->e_nname.bv_len;
+               rlen = e->e_name.bv_len;
        }
 
        d = sl_malloc(sizeof(diskNode) + rlen + nrlen, ctx);
@@ -693,6 +696,7 @@ bdb_dn2id(
        char    *ptr;
 
        nrlen = dn_rdnlen( be, &in );
+       if (!nrlen) nrlen = in->bv_len;
 
        DBTzero(&key);
        key.size = sizeof(ID);
@@ -768,41 +772,100 @@ bdb_dn2id_children(
        return rc;
 }
 
+struct dn2id_cookie {
+       struct bdb_info *bdb;
+       DB *db;
+       int prefix;
+       int rc;
+       ID id;
+       ID dbuf;
+       ID *ids;
+       ID tmp[BDB_IDL_DB_SIZE];
+       ID buf[BDB_IDL_UM_SIZE];
+       DBT key;
+       DBT data;
+       DBC dbc;
+       void *ptr;
+       void *ctx;
+};
+
+/* We can't just use bdb_idl_fetch_key because
+ * 1 - our data items are longer than just an entry ID
+ * 2 - our data items are sorted alphabetically by nrdn, not by ID.
+ */
+int
+bdb_dn2idl_internal(
+       struct dn2id_cookie *cx
+)
+{
+       ID *save, *i;
+
+#ifdef SLAP_IDL_CACHE
+       if ( cx->bdb->bi_idl_cache_size ) {
+               cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, cx->tmp);
+               if ( cx->rc == DB_NOTFOUND ) {
+                       return cx->rc;
+               }
+               if ( cx->rc == LDAP_SUCCESS ) {
+                       readit = 0;
+               }
+       }
+#endif
+       
+       cx->data.data = &cx->dbuf;
+       cx->data.ulen = sizeof(ID);
+       cx->data.dlen = sizeof(ID);
+       cx->data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
+
+       cx->rc = db->cursor( cx->db, NULL, &cx->dbc, cx->bdb->bi_db_opflags );
+       if ( cx->rc ) return cx->rc;
+       BDB_IDL_ZERO( cx->tmp );
+
+       cx->rc = dbc->c_get( dbc, &cx->key, &cx->data, DB_FIRST );
+       cx->data.data = &cx->buf;
+       cx->data.ulen = sizeof(cx->buf);
+       while ( cx->rc == 0 ) {
+               u_int8_t *j;
+               size_t len;
+               cx->rc = dbc->c_get( dbc, &cx->key, &cx->data, DB_MULTIPLE |
+                       DB_NEXT_DUP );
+               DB_MULTIPLE_INIT( cx->ptr, &cx->data );
+               while (cx->ptr) {
+                       DB_MULTIPLE_NEXT( cx->ptr, &cx->data, j, len );
+                       if (j) {
+                               AC_MEMCPY( &cx->dbuf, j, sizeof(ID) );
+                               bdb_idl_insert( cx->tmp, cx->dbuf );
+                       }
+               }
+       }
+       dbc->c_close( dbc );
+       
+}
+
 int
 bdb_dn2idl(
        BackendDB       *be,
        struct berval   *dn,
        int prefix,
-       ID *ids )
+       ID *ids,
+       void *ctx )
 {
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       int             rc;
-       ID              id;
-       idNode          *n;
+       struct dn2id_cookie cx;
 
-       if (prefix == DN_SUBTREE_PREFIX && be_issuffix(be, dn)) {
-               BDB_IDL_ALL(bdb, ids);
-               return 0;
-       }
+       cx.id = *(ID *)dn;
 
-       rc = bdb_dn2id(be, NULL, dn, &id, 0);
-       if (rc) return rc;
+       cx.bdb = (struct bdb_info *)be->be_private;
+       cx.db = cx.bdb->bi_dn2id->bdi_db;
+       cx.prefix = prefix;
+       cx.ids = ids;
+       cx.ctx = ctx;
 
-       ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr);
-       n = bdb_find_id_node(id, bdb->bi_tree);
-       ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);
+       DBTzero(&cx.key);
+       cx.key.data = &cx.id;
+       cx.key.size = sizeof(ID);
+       cx.key.flags = DB_DBT_USERMEM;
+       DBTzero(&cx.data);
 
-       ids[0] = 0;
-       ldap_pvt_thread_rdwr_rlock(&n->i_kids_rdwr);
-       if (prefix == DN_ONE_PREFIX) {
-               rc = avl_apply(n->i_kids, insert_one, ids, -1, AVL_INORDER);
-       } else {
-               ids[0] = 1;
-               ids[1] = id;
-               if (n->i_kids)
-                       rc = avl_apply(n->i_kids, insert_sub, ids, -1, AVL_INORDER);
-       }
-       ldap_pvt_thread_rdwr_runlock(&n->i_kids_rdwr);
-       return rc;
+       return bdb_dn2idl_internal(&cx);
 }
 #endif /* BDB_HIER */
index 791d8769fcbe569193e74205690fa8246fa8c4c8..24b2cbe843c407fc2a012078d56455337711394a 100644 (file)
@@ -67,7 +67,8 @@ bdb_filter_candidates(
 #else
                Debug( LDAP_DEBUG_FILTER, "\tDN ONE\n", 0, 0, 0 );
 #endif
-               rc = bdb_dn2idl( op->o_bd, f->f_dn, DN_ONE_PREFIX, ids );
+               rc = bdb_dn2idl( op->o_bd, f->f_dn, DN_ONE_PREFIX, ids,
+                       op->o_tmpmemctx );
                if( rc == DB_NOTFOUND ) {
                        BDB_IDL_ZERO( ids );
                        rc = 0;
@@ -80,7 +81,8 @@ bdb_filter_candidates(
 #else
                Debug( LDAP_DEBUG_FILTER, "\tDN SUBTREE\n", 0, 0, 0 );
 #endif
-               rc = bdb_dn2idl( op->o_bd, f->f_dn, DN_SUBTREE_PREFIX, ids );
+               rc = bdb_dn2idl( op->o_bd, f->f_dn, DN_SUBTREE_PREFIX, ids,
+                       op->o_tmpmemctx );
                break;
 
        case LDAP_FILTER_PRESENT:
index 43a6f5486966f936100ec5315f7ccf0d7e21ffc4..91c8a883f4c04e13b69b424970e09ff5ca600f5c 100644 (file)
@@ -90,7 +90,8 @@ bdb_dn2idl(
        BackendDB       *be,
        struct berval   *dn,
        int prefix,
-       ID *ids );
+       ID *ids,
+       void *ctx );
 
 /*
  * entry.c
index 4d8710d9b36e7bd582783614ad097a4674db4873..614a642b58c1fb1374261d6821e3c3476d11aa09 100644 (file)
@@ -268,12 +268,17 @@ nextido:
                 * we should never see the ID of an entry that doesn't exist.
                 * Set the name so that the scope's IDL can be retrieved.
                 */
+#ifndef BDB_HIER
                ei = NULL;
                rs->sr_err = bdb_cache_find_entry_id(op->o_bd, NULL, ido, &ei,
                        0, locker, &locka, op->o_tmpmemctx );
                if (rs->sr_err != LDAP_SUCCESS) goto nextido;
                e = ei->bei_e;
                sf->f_dn = &e->e_nname;
+#else
+               /* bdb_dn2idl uses IDs for keys, not DNs */
+               sf->f_dn = (struct berval *)&ido;
+#endif
        }
        return rs->sr_err;
 }
@@ -1514,7 +1519,11 @@ static int search_candidates(
        scopef.f_choice = op->oq_search.rs_scope == LDAP_SCOPE_SUBTREE
                ? SLAPD_FILTER_DN_SUBTREE
                : SLAPD_FILTER_DN_ONE;
+#ifdef BDB_HIER
+       scopef.f_dn = (struct berval *)&e->e_id;
+#else
        scopef.f_dn = &e->e_nname;
+#endif
        scopef.f_next = NULL;
 
        f.f_next = NULL;