]> git.sur5r.net Git - openldap/commitdiff
Use sorted array for indexed attrs instead of AVL tree
authorHoward Chu <hyc@openldap.org>
Wed, 26 Oct 2005 08:31:38 +0000 (08:31 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 26 Oct 2005 08:31:38 +0000 (08:31 +0000)
servers/slapd/back-bdb/attr.c
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/tools.c

index f058c1f59672ddcda65b19638977d5d8ee64b923..bad6c11d2b2b7d5518e2f396e378fc26fab8a359 100644 (file)
 #include "back-bdb.h"
 #include "lutil.h"
 
-
-static int
-ainfo_type_cmp(
-       const void *v_desc,
-       const void *v_a
-)
+unsigned
+bdb_attr_slot( struct bdb_info *bdb, AttributeDescription *ad )
 {
-       const AttributeDescription *desc = v_desc;
-       const AttrInfo  *a = v_a;
-       return SLAP_PTRCMP(desc, a->ai_desc);
+       unsigned base = 0, cursor = 0;
+       unsigned n = bdb->bi_nattrs;
+       int val;
+       
+       while ( 0 < n ) {
+               int pivot = n >> 1;
+               cursor = base + pivot;
+
+               val = SLAP_PTRCMP( ad, bdb->bi_attrs[cursor]->ai_desc );
+               if ( val < 0 ) {
+                       n = pivot;
+               } else if ( val > 0 ) {
+                       base = cursor + 1;
+                       n -= pivot + 1;
+               } else {
+                       return cursor;
+               }
+       }
+       if ( val > 0 )
+               ++cursor;
+       return cursor;
 }
 
 static int
-ainfo_cmp(
-       const void      *v_a,
-       const void      *v_b
-)
+ainfo_insert( struct bdb_info *bdb, AttrInfo *a )
 {
-       const AttrInfo *a = v_a, *b = v_b;
-       return SLAP_PTRCMP(a->ai_desc, b->ai_desc);
+       unsigned x = bdb_attr_slot( bdb, a->ai_desc );
+
+       /* Is it a dup? */
+       if ( x < bdb->bi_nattrs && bdb->bi_attrs[x]->ai_desc == a->ai_desc )
+               return -1;
+
+       bdb->bi_attrs = ch_realloc( bdb->bi_attrs, ( bdb->bi_nattrs+1 ) * 
+               sizeof( AttrInfo * ));
+       if ( x < bdb->bi_nattrs )
+               AC_MEMCPY( &bdb->bi_attrs[x+1], &bdb->bi_attrs[x],
+                       ( bdb->bi_nattrs - x ) * sizeof( AttrInfo *));
+       bdb->bi_attrs[x] = a;
+       bdb->bi_nattrs++;
+       return 0;
 }
 
 AttrInfo *
@@ -52,8 +75,9 @@ bdb_attr_mask(
        struct bdb_info *bdb,
        AttributeDescription *desc )
 {
-
-       return avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
+       unsigned i = bdb_attr_slot( bdb, desc );
+       return ( i < bdb->bi_nattrs && bdb->bi_attrs[i]->ai_desc == desc ) ?
+               bdb->bi_attrs[i] : NULL;
 }
 
 int
@@ -220,7 +244,7 @@ bdb_attr_index_config(
 
 #ifdef LDAP_COMP_MATCH
                if ( cr ) {
-                       a_cr = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
+                       a_cr = bdb_attr_mask( bdb, ad );
                        if ( a_cr ) {
                                /*
                                 * AttrInfo is already in AVL
@@ -242,12 +266,10 @@ bdb_attr_index_config(
                        }
                }
 #endif
-               rc = avl_insert( &bdb->bi_attrs, (caddr_t) a,
-                                ainfo_cmp, avl_dup_error );
-
+               rc = ainfo_insert( bdb, a );
                if( rc ) {
                        if ( bdb->bi_flags & BDB_IS_OPEN ) {
-                               AttrInfo *b = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
+                               AttrInfo *b = bdb_attr_mask( bdb, ad );
                                /* If we were editing this attr, reset it */
                                b->ai_indexmask &= ~BDB_INDEX_DELETING;
                                /* If this is leftover from a previous add, commit it */
@@ -298,17 +320,19 @@ static AttrInfo aidef = { &addef };
 void
 bdb_attr_index_unparse( struct bdb_info *bdb, BerVarray *bva )
 {
+       int i;
+
        if ( bdb->bi_defaultmask ) {
                aidef.ai_indexmask = bdb->bi_defaultmask;
                bdb_attr_index_unparser( &aidef, bva );
        }
-       avl_apply( bdb->bi_attrs, bdb_attr_index_unparser, bva, -1, AVL_INORDER );
+       for ( i=0; i<bdb->bi_nattrs; i++ )
+               bdb_attr_index_unparser( bdb->bi_attrs[i], bva );
 }
 
-static void
-bdb_attrinfo_free( void *v )
+void
+bdb_attr_info_free( AttrInfo *ai )
 {
-       AttrInfo *ai = v;
 #ifdef LDAP_COMP_MATCH
        free( ai->ai_cr );
 #endif
@@ -316,52 +340,41 @@ bdb_attrinfo_free( void *v )
 }
 
 void
-bdb_attr_index_destroy( Avlnode *tree )
+bdb_attr_index_destroy( struct bdb_info *bdb )
 {
-       avl_free( tree, bdb_attrinfo_free );
-}
+       int i;
 
-void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad )
-{
-       AttrInfo *ai;
+       for ( i=0; i<bdb->bi_nattrs; i++ ) 
+               bdb_attr_info_free( bdb->bi_attrs[i] );
 
-       ai = avl_delete( &bdb->bi_attrs, ad, ainfo_type_cmp );
-       if ( ai )
-               bdb_attrinfo_free( ai );
+       free( bdb->bi_attrs );
 }
 
-/* Get a list of AttrInfo's to delete */
-
-typedef struct Alist {
-       struct Alist *next;
-       AttrInfo *ptr;
-} Alist;
-
-static int
-bdb_attrinfo_flush( void *v1, void *arg )
+void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad )
 {
-       AttrInfo *ai = v1;
-
-       if ( ai->ai_indexmask & BDB_INDEX_DELETING ) {
-               Alist **al = arg;
-               Alist *a = ch_malloc( sizeof( Alist ));
-               a->ptr = ai;
-               a->next = *al;
-               *al = a;
+       unsigned i;
+
+       i = bdb_attr_slot( bdb, ad );
+       if ( i < bdb->bi_nattrs && bdb->bi_attrs[i]->ai_desc == ad ) {
+               bdb_attr_info_free( bdb->bi_attrs[i] );
+               bdb->bi_nattrs--;
+               for (; i<bdb->bi_nattrs; i++)
+                       bdb->bi_attrs[i] = bdb->bi_attrs[i+1];
        }
-       return 0;
 }
 
 void bdb_attr_flush( struct bdb_info *bdb )
 {
-       Alist *al = NULL, *a2;
-
-       avl_apply( bdb->bi_attrs, bdb_attrinfo_flush, &al, -1, AVL_INORDER );
-
-       while (( a2 = al )) {
-               al = al->next;
-               avl_delete( &bdb->bi_attrs, a2->ptr, ainfo_cmp );
-               bdb_attrinfo_free( a2->ptr );
-               ch_free( a2 );
+       int i;
+
+       for ( i=0; i<bdb->bi_nattrs; i++ ) {
+               if ( bdb->bi_attrs[i]->ai_indexmask & BDB_INDEX_DELETING ) {
+                       int j;
+                       bdb_attr_info_free( bdb->bi_attrs[i] );
+                       bdb->bi_nattrs--;
+                       for (j=i; j<bdb->bi_nattrs; j++)
+                               bdb->bi_attrs[j] = bdb->bi_attrs[j+1];
+                       i--;
+               }
        }
 }
index 7091d343db863181cb43951e063aac023692c598..2992b95511e768164cafaa40cde1a28fa465040d 100644 (file)
@@ -166,7 +166,8 @@ struct bdb_info {
 
        slap_mask_t     bi_defaultmask;
        Cache           bi_cache;
-       Avlnode         *bi_attrs;
+       struct bdb_attrinfo             **bi_attrs;
+       int                     bi_nattrs;
        void            *bi_search_stack;
        int             bi_search_stack_depth;
        int             bi_linear_index;
index a982d23bbdbaf90b759e74b68a2aae5c8f34ec4b..3fbf91bf6d262b49bb3acb8f5b7377e86ed28132 100644 (file)
@@ -606,7 +606,7 @@ bdb_db_destroy( BackendDB *be )
        if( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home );
        if( bdb->bi_db_config_path ) ch_free( bdb->bi_db_config_path );
 
-       bdb_attr_index_destroy( bdb->bi_attrs );
+       bdb_attr_index_destroy( bdb );
 
        ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock );
        ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_mutex );
index b6555523e9f4f12bc21710173befc03d88f8c989..8b47f977e99870afc60ad1a367c3db4684c8e5f5 100644 (file)
@@ -32,25 +32,32 @@ LDAP_BEGIN_DECL
 
 #define bdb_attr_mask                          BDB_SYMBOL(attr_mask)
 #define bdb_attr_flush                         BDB_SYMBOL(attr_flush)
+#define bdb_attr_slot                          BDB_SYMBOL(attr_slot)
 #define bdb_attr_index_config          BDB_SYMBOL(attr_index_config)
 #define bdb_attr_index_destroy         BDB_SYMBOL(attr_index_destroy)
 #define bdb_attr_index_free                    BDB_SYMBOL(attr_index_free)
 #define bdb_attr_index_unparse         BDB_SYMBOL(attr_index_unparse)
+#define bdb_attr_info_free                     BDB_SYMBOL(attr_info_free)
 
 AttrInfo *bdb_attr_mask( struct bdb_info *bdb,
        AttributeDescription *desc );
 
 void bdb_attr_flush( struct bdb_info *bdb );
 
+unsigned bdb_attr_slot( struct bdb_info *bdb,
+       AttributeDescription *desc );
+
 int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb,
        const char *fname, int lineno,
        int argc, char **argv ));
 
 void bdb_attr_index_unparse LDAP_P(( struct bdb_info *bdb, BerVarray *bva ));
-void bdb_attr_index_destroy LDAP_P(( Avlnode *tree ));
+void bdb_attr_index_destroy LDAP_P(( struct bdb_info *bdb ));
 void bdb_attr_index_free LDAP_P(( struct bdb_info *bdb,
        AttributeDescription *ad ));
 
+void bdb_attr_info_free( AttrInfo *ai );
+
 /*
  * config.c
  */
index e49fa8d27dfc3c2368bf2d64ce453818049f23d9..24bff1427b8081f72b816d7c11935cbb5a464506 100644 (file)
@@ -36,7 +36,7 @@ static dn_id hbuf[HOLE_SIZE], *holes = hbuf;
 static unsigned nhmax = HOLE_SIZE;
 static unsigned nholes;
 
-static Avlnode *index_attrs, index_dummy;
+static int index_nattrs;
 
 #define bdb_tool_idl_cmp               BDB_SYMBOL(tool_idl_cmp)
 #define bdb_tool_idl_flush_one         BDB_SYMBOL(tool_idl_flush_one)
@@ -115,8 +115,6 @@ int bdb_tool_entry_close(
        return 0;
 }
 
-static int bdb_reindex_cmp(const void *a, const void *b) { return 0; }
-
 ID bdb_tool_entry_next(
        BackendDB *be )
 {
@@ -134,14 +132,13 @@ ID bdb_tool_entry_next(
                /* If we're doing linear indexing and there are more attrs to
                 * index, and we're at the end of the database, start over.
                 */
-               if ( bdb->bi_attrs == &index_dummy ) {
-                       if ( index_attrs && rc == DB_NOTFOUND ) {
-                               /* optional - do a checkpoint here? */
-                               index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
-                               rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
-                       }
+               if ( index_nattrs && rc == DB_NOTFOUND ) {
+                       /* optional - do a checkpoint here? */
+                       bdb_attr_info_free( bdb->bi_attrs[0] );
+                       bdb->bi_attrs[0] = bdb->bi_attrs[index_nattrs];
+                       index_nattrs--;
+                       rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
                        if ( rc ) {
-                               bdb->bi_attrs = NULL;
                                return NOID;
                        }
                } else {
@@ -468,10 +465,9 @@ int bdb_tool_entry_reindex(
        }
 
        /* Get the first attribute to index */
-       if (bi->bi_linear_index && !index_attrs && bi->bi_attrs != &index_dummy) {
-               index_attrs = bi->bi_attrs;
-               bi->bi_attrs = &index_dummy;
-               index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
+       if (bi->bi_linear_index && !index_nattrs) {
+               index_nattrs = bi->bi_nattrs - 1;
+               bi->bi_nattrs = 1;
        }
 
        e = bdb_tool_entry_get( be, id );