#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 *
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
#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
}
}
#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 */
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
}
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--;
+ }
}
}
#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
*/
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)
return 0;
}
-static int bdb_reindex_cmp(const void *a, const void *b) { return 0; }
-
ID bdb_tool_entry_next(
BackendDB *be )
{
/* 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 {
}
/* 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 );