Skip to content
Snippets Groups Projects
Commit 888731e6 authored by Howard Chu's avatar Howard Chu
Browse files

Use sorted array for indexed attrs instead of AVL tree

parent 08cc4031
No related branches found
No related tags found
No related merge requests found
......@@ -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;
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--;
}
}
}
......@@ -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;
......
......@@ -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 );
......
......@@ -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
*/
......
......@@ -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 );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment