Use sorted array for indexed attrs instead of AVL tree

This commit is contained in:
Howard Chu 2005-10-26 08:31:38 +00:00
parent 08cc40317b
commit 888731e6c3
5 changed files with 95 additions and 78 deletions

View File

@ -25,26 +25,49 @@
#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;
for ( i=0; i<bdb->bi_nattrs; i++ )
bdb_attr_info_free( bdb->bi_attrs[i] );
free( bdb->bi_attrs );
}
void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad )
{
AttrInfo *ai;
unsigned i;
ai = avl_delete( &bdb->bi_attrs, ad, ainfo_type_cmp );
if ( ai )
bdb_attrinfo_free( ai );
}
/* 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 )
{
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;
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;
int i;
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 );
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--;
}
}
}

View 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;

View 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 );

View 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
*/

View 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 );