]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/dn2id.c
ITS#4040 move initialization
[openldap] / servers / slapd / back-bdb / dn2id.c
index 2d362830ae58a963fda955bb60a3073bcc20a7dd..5131fd1a9fe20df68e6d9375533b4cce5f00d5ce 100644 (file)
@@ -381,10 +381,7 @@ bdb_dn2idl(
 }
 
 #else  /* BDB_HIER */
-/* Experimental management routines for a hierarchically structured database.
- *
- * Unsupported! Use at your own risk!
- * -- Howard Chu, Symas Corp. 2003.
+/* Management routines for a hierarchically structured database.
  *
  * 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
@@ -402,9 +399,9 @@ bdb_dn2idl(
  */
 typedef struct diskNode {
        unsigned char nrdnlen[2];
-       unsigned char nrdn[1];
-       unsigned char rdn[1];
-       unsigned char entryID[sizeof(ID)];
+       char nrdn[1];
+       char rdn[1];                        /* variable placement */
+       unsigned char entryID[sizeof(ID)];  /* variable placement */
 } diskNode;
 
 /* This function constructs a full DN for a given entry.
@@ -516,7 +513,7 @@ hdb_dn2id_add(
         * will fail harmlessly.
         */
        if ( eip->bei_id == 0 ) {
-               diskNode dummy = {0};
+               diskNode dummy = {{0, 0}, "", "", ""};
                data.data = &dummy;
                data.size = sizeof(diskNode);
                data.flags = DB_DBT_USERMEM;
@@ -676,7 +673,7 @@ hdb_dn2id(
                ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - nrlen;
                ptr = d->nrdn + nrlen + 1;
                ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn );
-               if ( !ei->bei_parent->bei_dkids ) {
+               if ( ei->bei_parent != NULL && !ei->bei_parent->bei_dkids ) {
                        db_recno_t dkids;
                        /* How many children does the parent have? */
                        /* FIXME: do we need to lock the parent
@@ -821,12 +818,13 @@ struct dn2id_cookie {
        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
@@ -954,15 +952,18 @@ hdb_dn2idl_internal(
        }
 
 saveit:
+       if ( !BDB_IDL_IS_RANGE( cx->tmp ) && cx->tmp[0] > 3 )
+               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_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;
@@ -1025,8 +1026,10 @@ hdb_dn2idl(
        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 ) {
@@ -1041,8 +1044,8 @@ hdb_dn2idl(
        DBTzero(&cx.data);
 
        hdb_dn2idl_internal(&cx);
-       if ( !BDB_IDL_IS_ZERO( ids ) && !BDB_IDL_IS_RANGE( ids ))
-               bdb_idl_sort( ids );
+       if ( cx.need_sort && !BDB_IDL_IS_RANGE( cx.ids ) && cx.ids[0] > 3 )
+               bdb_idl_sort( cx.ids, cx.tmp );
 
        return cx.rc;
 }