Revert to original code

This commit is contained in:
Howard Chu 2004-03-06 19:15:39 +00:00
parent 5c6ec10f48
commit 113870c194
8 changed files with 321 additions and 251 deletions

View file

@ -73,6 +73,10 @@ LDAP_BEGIN_DECL
/* The minimum we can function with */
#define MINIMUM_SEARCH_STACK_DEPTH 8
/* for the IDL cache */
#define SLAP_IDL_CACHE 1
#ifdef SLAP_IDL_CACHE
typedef struct bdb_idl_cache_entry_s {
struct berval kstr;
ldap_pvt_thread_rdwr_t idl_entry_rwlock;
@ -81,6 +85,7 @@ typedef struct bdb_idl_cache_entry_s {
struct bdb_idl_cache_entry_s* idl_lru_prev;
struct bdb_idl_cache_entry_s* idl_lru_next;
} bdb_idl_cache_entry_t;
#endif
/* BDB backend specific entry info */
typedef struct bdb_entry_info {
@ -168,6 +173,7 @@ struct bdb_info {
LDAP_LIST_HEAD(pl, slap_op) bi_psearch_list;
ldap_pvt_thread_rdwr_t bi_pslist_rwlock;
LDAP_LIST_HEAD(se, slap_session_entry) bi_session_list;
#ifdef SLAP_IDL_CACHE
int bi_idl_cache_max_size;
int bi_idl_cache_size;
Avlnode *bi_idl_tree;
@ -175,6 +181,7 @@ struct bdb_info {
bdb_idl_cache_entry_t *bi_idl_lru_tail;
ldap_pvt_thread_rdwr_t bi_idl_tree_rwlock;
ldap_pvt_thread_mutex_t bi_idl_tree_lrulock;
#endif
};
#define bi_id2entry bi_databases[BDB_ID2ENTRY]

View file

@ -172,6 +172,7 @@ bdb_db_config(
bdb->bi_search_stack_depth = MINIMUM_SEARCH_STACK_DEPTH;
}
#ifdef SLAP_IDL_CACHE
/* size of the IDL cache in entries */
} else if ( strcasecmp( argv[0], "idlcachesize" ) == 0 ) {
if ( argc < 2 ) {
@ -180,7 +181,9 @@ bdb_db_config(
fname, lineno );
return( 1 );
}
bdb->bi_idl_cache_max_size = atoi( argv[1] );
if ( !( slapMode & SLAP_TOOL_MODE ) )
bdb->bi_idl_cache_max_size = atoi( argv[1] );
#endif
} else if ( strcasecmp( argv[0], "sessionlog" ) == 0 ) {
int se_id = 0, se_size = 0;

View file

@ -118,6 +118,7 @@ bdb_db_cache(
rc = db->bdi_db->set_h_hash( db->bdi_db, bdb_db_hash );
#endif
rc = db->bdi_db->set_flags( db->bdi_db, DB_DUP | DB_DUPSORT );
rc = db->bdi_db->set_dup_compare( db->bdi_db, bdb_bt_compare );
file = ch_malloc( strlen( name ) + sizeof(BDB_SUFFIX) );
sprintf( file, "%s" BDB_SUFFIX, name );

View file

@ -382,6 +382,7 @@ bdb_dn2id_children(
((char *)key.data)[0] = DN_ONE_PREFIX;
AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 );
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_size ) {
rc = bdb_idl_cache_get( bdb, db, &key, NULL );
if ( rc != LDAP_NO_SUCH_OBJECT ) {
@ -389,7 +390,7 @@ bdb_dn2id_children(
return rc;
}
}
#endif
/* we actually could do a empty get... */
DBTzero( &data );
data.data = &id;
@ -629,10 +630,11 @@ hdb_dn2id_add(
key.size = sizeof(ID);
key.flags = DB_DBT_USERMEM;
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_size ) {
bdb_idl_cache_del( bdb, db, &key );
}
#endif
data.data = d;
data.size = sizeof(diskNode) + rlen + nrlen;
data.flags = DB_DBT_USERMEM;
@ -678,10 +680,11 @@ hdb_dn2id_delete(
data.dlen = data.size;
data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_size ) {
bdb_idl_cache_del( bdb, db, &key );
}
#endif
rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
if ( rc ) return rc;
@ -848,13 +851,14 @@ hdb_dn2id_children(
key.data = &e->e_id;
key.flags = DB_DBT_USERMEM;
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_size ) {
rc = bdb_idl_cache_get( bdb, db, &key, NULL );
if ( rc != LDAP_NO_SUCH_OBJECT ) {
return rc;
}
}
#endif
DBTzero(&data);
data.data = &d;
data.ulen = sizeof(d);
@ -922,6 +926,7 @@ hdb_dn2idl_internal(
struct dn2id_cookie *cx
)
{
#ifdef SLAP_IDL_CACHE
if ( cx->bdb->bi_idl_cache_size ) {
cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, cx->tmp);
if ( cx->rc == DB_NOTFOUND ) {
@ -931,7 +936,7 @@ hdb_dn2idl_internal(
goto gotit;
}
}
#endif
BDB_IDL_ZERO( cx->tmp );
if ( !cx->ei ) {
@ -1027,10 +1032,11 @@ hdb_dn2idl_internal(
}
saveit:
#ifdef SLAP_IDL_CACHE
if ( cx->bdb->bi_idl_cache_max_size ) {
bdb_idl_cache_put( cx->bdb, cx->db, &cx->key, cx->tmp, cx->rc );
}
#endif
;
gotit:
if ( !BDB_IDL_IS_ZERO( cx->tmp )) {

View file

@ -32,9 +32,7 @@ static int bdb_id2entry_put(
DB *db = bdb->bi_id2entry->bdi_db;
DBT key, data;
struct berval bv;
char buf[sizeof(ID)];
ID tmp;
int i, rc;
int rc;
#ifdef BDB_HIER
struct berval odn, ondn;
@ -46,16 +44,9 @@ static int bdb_id2entry_put(
e->e_nname = slap_empty_bv;
#endif
DBTzero( &key );
key.data = buf;
key.data = (char *) &e->e_id;
key.size = sizeof(ID);
/* Set key in BigEndian order */
tmp = e->e_id;
for ( i=sizeof(ID)-1; i>=0; i-- ) {
buf[i] = tmp & 0xff;
tmp >>= 8;
}
rc = entry_encode( e, &bv );
#ifdef BDB_HIER
e->e_name = odn; e->e_nname = ondn;
@ -105,20 +96,13 @@ int bdb_id2entry(
DB *db = bdb->bi_id2entry->bdi_db;
DBT key, data;
struct berval bv;
char buf[sizeof(ID)];
ID tmp;
int i, rc = 0, ret = 0;
int rc = 0, ret = 0;
*e = NULL;
DBTzero( &key );
key.data = buf;
key.data = (char *) &id;
key.size = sizeof(ID);
tmp = id;
for ( i=sizeof(ID)-1; i>=0; i-- ) {
buf[i] = tmp & 0xff;
tmp >>= 8;
}
DBTzero( &data );
data.flags = DB_DBT_MALLOC;
@ -154,18 +138,11 @@ int bdb_id2entry_delete(
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
DB *db = bdb->bi_id2entry->bdi_db;
DBT key;
char buf[sizeof(ID)];
ID tmp;
int i, rc;
int rc;
DBTzero( &key );
key.data = buf;
key.data = (char *) &e->e_id;
key.size = sizeof(ID);
tmp = e->e_id;
for ( i=sizeof(ID)-1; i>=0; i-- ) {
buf[i] = tmp & 0xff;
tmp >>= 8;
}
/* delete from database */
rc = db->del( db, tid, &key, 0 );

View file

@ -27,6 +27,7 @@
#define IDL_CMP(x,y) ( x < y ? -1 : ( x > y ? 1 : 0 ) )
#ifdef SLAP_IDL_CACHE
#define IDL_LRU_DELETE( bdb, e ) do { \
if ( e->idl_lru_prev != NULL ) { \
e->idl_lru_prev->idl_lru_next = e->idl_lru_next; \
@ -58,10 +59,11 @@ bdb_idl_entry_cmp( const void *v_idl1, const void *v_idl2 )
const bdb_idl_cache_entry_t *idl1 = v_idl1, *idl2 = v_idl2;
int rc;
if ((rc = SLAP_PTRCMP( idl1->db, idl2->db ))) return rc;
if ((rc = idl1->db - idl2->db )) return rc;
if ((rc = idl1->kstr.bv_len - idl2->kstr.bv_len )) return rc;
return ( memcmp ( idl1->kstr.bv_val, idl2->kstr.bv_val , idl1->kstr.bv_len ) );
}
#endif
#if IDL_DEBUG > 0
static void idl_check( ID *ids )
@ -242,9 +244,10 @@ int bdb_idl_insert( ID *ids, ID id )
return 0;
}
static int bdb_idl_delete( ID *ids, ID id )
#if 0 /* unused */
static int idl_delete( ID *ids, ID id )
{
unsigned x;
unsigned x = bdb_idl_search( ids, id );
#if IDL_DEBUG > 1
#ifdef NEW_LOGGING
@ -257,21 +260,6 @@ static int bdb_idl_delete( ID *ids, ID id )
idl_check( ids );
#endif
if (BDB_IDL_IS_RANGE( ids )) {
/* if in range, treat as a noop */
if (id > BDB_IDL_FIRST(ids) && id < BDB_IDL_LAST(ids))
return -1;
if (id == BDB_IDL_FIRST(ids))
ids[1] = id+1;
else if (id == BDB_IDL_LAST(ids))
ids[2] = id-1;
/* range collapsed to a single item */
if ( ids[1] == ids[2] )
ids[0] = 1;
return 0;
}
x = bdb_idl_search( ids, id );
assert( x > 0 );
if( x <= 0 ) {
@ -300,6 +288,7 @@ static int bdb_idl_delete( ID *ids, ID id )
return 0;
}
#endif /* unused */
static char *
bdb_show_key(
@ -315,6 +304,8 @@ bdb_show_key(
}
}
#ifdef SLAP_IDL_CACHE
/* Find a db/key pair in the IDL cache. If ids is non-NULL,
* copy the cached IDL into it, otherwise just return the status.
*/
@ -351,19 +342,6 @@ bdb_idl_cache_get(
return LDAP_NO_SUCH_OBJECT;
}
/* Replace existing cached IDL with new one, tell caller it was a dup */
static int
idl_cache_dup( void *left, void *right )
{
bdb_idl_cache_entry_t *le = left, *re = right;
ch_free( le->idl );
le->idl = re->idl;
re->idl = NULL;
return -1;
}
/* add or replace cache entries */
void
bdb_idl_cache_put(
struct bdb_info *bdb,
@ -391,10 +369,10 @@ bdb_idl_cache_put(
ber_dupbv( &ee->kstr, &idl_tmp.kstr );
ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
if ( avl_insert( &bdb->bi_idl_tree, (caddr_t) ee,
bdb_idl_entry_cmp, idl_cache_dup ))
bdb_idl_entry_cmp, avl_dup_error ))
{
/* ee->idl has been stored in the tree */
ch_free( ee->kstr.bv_val );
ch_free( ee->idl );
ch_free( ee );
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
return;
@ -466,6 +444,7 @@ bdb_idl_cache_del(
}
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
}
#endif
int
bdb_idl_fetch_key(
@ -516,10 +495,12 @@ bdb_idl_fetch_key(
assert( ids != NULL );
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_size ) {
rc = bdb_idl_cache_get( bdb, db, key, ids );
if ( rc != LDAP_NO_SUCH_OBJECT ) return rc;
}
#endif
DBTzero( &data );
@ -552,13 +533,8 @@ bdb_idl_fetch_key(
while (ptr) {
DB_MULTIPLE_NEXT(ptr, &data, j, len);
if (j) {
int k;
ID tmp = 0;
for (k=0; k<sizeof(ID); k++) {
tmp <<= 8;
tmp |= *j++;
}
*++i = tmp;
++i;
AC_MEMCPY( i, j, sizeof(ID) );
}
}
rc = cursor->c_get( cursor, key, &data, flags | DB_NEXT_DUP );
@ -599,8 +575,11 @@ bdb_idl_fetch_key(
return rc2;
}
if ( rc == DB_NOTFOUND ) {
/* no-op */
if( rc == DB_NOTFOUND ) {
#ifndef SLAP_IDL_CACHE
return rc;
#endif
} else if( rc != 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG( INDEX, ERR,
@ -640,9 +619,11 @@ bdb_idl_fetch_key(
return -1;
}
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_max_size ) {
bdb_idl_cache_put( bdb, db, key, ids, rc );
}
#endif
return rc;
}
@ -657,11 +638,11 @@ bdb_idl_insert_key(
ID id )
{
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
int i, rc;
int rc;
DBT data;
ID lo, hi, tmp, idl[BDB_IDL_DB_SIZE];
char *err, buf[sizeof(ID)];
int wasrange = 0, isrange = 0;
DBC *cursor;
ID lo, hi, tmp;
char *err;
{
char buf[16];
@ -678,122 +659,148 @@ bdb_idl_insert_key(
assert( id != NOID );
BDB_IDL_ZERO( idl );
rc = bdb_idl_fetch_key( be, db, tid, key, idl );
if ( rc != DB_NOTFOUND ) {
wasrange = BDB_IDL_IS_RANGE( idl );
if ( wasrange ) {
lo = idl[1];
hi = idl[2];
}
rc = bdb_idl_insert( idl, id );
/* Don't need to do anything */
if ( rc == -1 ) return 0;
isrange = BDB_IDL_IS_RANGE( idl );
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_size ) {
bdb_idl_cache_del( bdb, db, key );
}
#endif
DBTzero( &data );
data.size = sizeof( ID );
data.ulen = data.size;
data.flags = DB_DBT_USERMEM;
data.data = buf;
if ( isrange ) {
while ( !wasrange ) {
/* Delete vector, rewrite as range */
rc = db->del( db, tid, key, 0 );
rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
if ( rc != 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG( INDEX, ERR,
"bdb_idl_insert_key: cursor failed: %s (%d)\n",
db_strerror(rc), rc, 0 );
#else
Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: "
"cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 );
#endif
return rc;
}
data.data = &tmp;
/* Fetch the first data item for this key, to see if it
* exists and if it's a range.
*/
rc = cursor->c_get( cursor, key, &data, DB_SET | DB_RMW );
err = "c_get";
if ( rc == 0 ) {
if ( tmp != 0 ) {
/* not a range, count the number of items */
db_recno_t count;
rc = cursor->c_count( cursor, &count, 0 );
if ( rc != 0 ) {
err = "del";
break;
err = "c_count";
goto fail;
}
tmp = 0;
for (i=sizeof(ID)-1; i>=0; i--) {
buf[i] = 0;
if ( count >= BDB_IDL_DB_MAX ) {
/* No room, convert to a range */
DBT key2 = *key;
key2.dlen = key2.ulen;
key2.flags |= DB_DBT_PARTIAL;
lo = tmp;
data.data = &hi;
rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_NODUP );
if ( rc != 0 && rc != DB_NOTFOUND ) {
err = "c_get next_nodup";
goto fail;
}
if ( rc == DB_NOTFOUND ) {
rc = cursor->c_get( cursor, key, &data, DB_LAST );
if ( rc != 0 ) {
err = "c_get last";
goto fail;
}
} else {
rc = cursor->c_get( cursor, key, &data, DB_PREV );
if ( rc != 0 ) {
err = "c_get prev";
goto fail;
}
}
if ( id < lo )
lo = id;
else if ( id > hi )
hi = id;
rc = db->del( db, tid, key, 0 );
if ( rc != 0 ) {
err = "del";
goto fail;
}
data.data = &id;
id = 0;
rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );
if ( rc != 0 ) {
err = "c_put 0";
goto fail;
}
id = lo;
rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );
if ( rc != 0 ) {
err = "c_put lo";
goto fail;
}
id = hi;
rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );
if ( rc != 0 ) {
err = "c_put hi";
goto fail;
}
} else {
/* There's room, just store it */
goto put1;
}
rc = db->put( db, tid, key, &data, 0 );
} else {
/* It's a range, see if we need to rewrite
* the boundaries
*/
hi = id;
data.data = &lo;
rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );
if ( rc != 0 ) {
err = "put1";
break;
err = "c_get lo";
goto fail;
}
tmp = idl[1];
for (i=sizeof(ID)-1; i>=0; i--) {
buf[i] = tmp & 0xff;
tmp >>= 8;
if ( id > lo ) {
data.data = &hi;
rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );
if ( rc != 0 ) {
err = "c_get hi";
goto fail;
}
}
rc = db->put( db, tid, key, &data, 0 );
if ( rc != 0 ) {
err = "put2";
break;
if ( id < lo || id > hi ) {
/* Delete the current lo/hi */
rc = cursor->c_del( cursor, 0 );
if ( rc != 0 ) {
err = "c_del";
goto fail;
}
data.data = &id;
rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );
if ( rc != 0 ) {
err = "c_put lo/hi";
goto fail;
}
}
tmp = idl[2];
for (i=sizeof(ID)-1; i>=0; i--) {
buf[i] = tmp & 0xff;
tmp >>= 8;
}
rc = db->put( db, tid, key, &data, 0 );
if ( rc != 0 ) {
err = "put3";
break;
}
break;
}
while( wasrange ) {
DBC *cursor;
/* Update range boundaries */
rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
if ( rc != 0 ) {
err = "cursor";
break;
}
tmp = (id == idl[1]) ? lo : hi;
for (i=sizeof(ID)-1; i>=0; i--) {
buf[i] = tmp & 0xff;
tmp >>= 8;
}
rc = cursor->c_get( cursor, key, &data, DB_GET_BOTH );
if ( rc != 0 ) {
cursor->c_close( cursor );
err = "c_get";
break;
}
rc = cursor->c_del( cursor, 0 );
if ( rc != 0 ) {
cursor->c_close( cursor );
err = "c_del";
break;
}
tmp = id;
for (i=sizeof(ID)-1; i>=0; i--) {
buf[i] = tmp & 0xff;
tmp >>= 8;
}
rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );
if ( rc != 0 ) {
cursor->c_close( cursor );
err = "c_put";
break;
}
rc = cursor->c_close( cursor );
if ( rc != 0 ) {
err = "c_close";
break;
}
break;
} else if ( rc == DB_NOTFOUND ) {
put1: data.data = &id;
rc = cursor->c_put( cursor, key, &data, DB_NODUPDATA );
/* Don't worry if it's already there */
if ( rc != 0 && rc != DB_KEYEXIST ) {
err = "c_put id";
goto fail;
}
} else {
tmp = id;
for (i=sizeof(ID)-1; i>=0; i--) {
buf[i] = tmp & 0xff;
tmp >>= 8;
}
rc = db->put( db, tid, key, &data, DB_NODUPDATA );
if ( rc != 0 ) {
err = "put4";
}
}
if ( rc && rc != DB_KEYEXIST ) {
/* initial c_get failed, nothing was done */
fail:
#ifdef NEW_LOGGING
LDAP_LOG( INDEX, ERR,
"bdb_idl_insert_key: %s failed: %s (%d)\n",
@ -802,11 +809,20 @@ bdb_idl_insert_key(
Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: "
"%s failed: %s (%d)\n", err, db_strerror(rc), rc );
#endif
cursor->c_close( cursor );
return rc;
}
if ( bdb->bi_idl_cache_max_size ) {
bdb_idl_cache_put( bdb, db, key, idl, 0 );
rc = cursor->c_close( cursor );
if( rc != 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG( INDEX, ERR,
"bdb_idl_insert_key: c_close failed: %s (%d)\n",
db_strerror(rc), rc, 0 );
#else
Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: "
"c_close failed: %s (%d)\n",
db_strerror(rc), rc, 0 );
#endif
}
return rc;
}
@ -820,12 +836,11 @@ bdb_idl_delete_key(
ID id )
{
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
int i, rc;
int rc;
DBT data;
DBC *cursor;
ID lo, hi, tmp, idl[BDB_IDL_DB_SIZE];
int wasrange, isrange;
char *err, buf[sizeof(ID)];
ID lo, hi, tmp;
char *err;
{
char buf[16];
@ -841,24 +856,14 @@ bdb_idl_delete_key(
}
assert( id != NOID );
BDB_IDL_ZERO( idl );
rc = bdb_idl_fetch_key( be, db, tid, key, idl );
if ( rc != DB_NOTFOUND ) {
wasrange = BDB_IDL_IS_RANGE( idl );
if ( wasrange ) {
lo = idl[1];
hi = idl[2];
}
rc = bdb_idl_delete( idl, id );
/* Don't need to do anything */
if ( rc == -1 ) return 0;
isrange = BDB_IDL_IS_RANGE( idl );
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_max_size ) {
bdb_idl_cache_del( bdb, db, key );
}
#endif
DBTzero( &data );
data.data = buf;
data.data = &tmp;
data.size = sizeof( id );
data.ulen = data.size;
data.flags = DB_DBT_USERMEM;
@ -875,50 +880,87 @@ bdb_idl_delete_key(
#endif
return rc;
}
if ( wasrange && !isrange ) {
rc = db->del( db, tid, key, 0 );
if ( rc != 0 ) {
err = "del";
} else {
tmp = idl[1];
for (i=sizeof(ID)-1; i>=0; i--) {
buf[i] = tmp & 0xff;
tmp >>= 8;
/* Fetch the first data item for this key, to see if it
* exists and if it's a range.
*/
rc = cursor->c_get( cursor, key, &data, DB_SET | DB_RMW );
err = "c_get";
if ( rc == 0 ) {
if ( tmp != 0 ) {
/* Not a range, just delete it */
if (tmp != id) {
/* position to correct item */
tmp = id;
rc = cursor->c_get( cursor, key, &data,
DB_GET_BOTH | DB_RMW );
if ( rc != 0 ) {
err = "c_get id";
goto fail;
}
}
rc = db->put( db, tid, key, &data, 0 );
rc = cursor->c_del( cursor, 0 );
if ( rc != 0 ) {
err = "put";
err = "c_del id";
goto fail;
}
} else {
/* It's a range, see if we need to rewrite
* the boundaries
*/
data.data = &lo;
rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );
if ( rc != 0 ) {
err = "c_get lo";
goto fail;
}
data.data = &hi;
rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );
if ( rc != 0 ) {
err = "c_get hi";
goto fail;
}
if ( id == lo || id == hi ) {
if ( id == lo ) {
id++;
lo = id;
} else if ( id == hi ) {
id--;
hi = id;
}
if ( lo >= hi ) {
/* The range has collapsed... */
rc = db->del( db, tid, key, 0 );
if ( rc != 0 ) {
err = "del";
goto fail;
}
} else {
if ( id == lo ) {
/* reposition on lo slot */
data.data = &lo;
cursor->c_get( cursor, key, &data, DB_PREV );
lo = id;
}
rc = cursor->c_del( cursor, 0 );
if ( rc != 0 ) {
err = "c_del";
goto fail;
}
}
if ( lo <= hi ) {
data.data = &id;
rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );
if ( rc != 0 ) {
err = "c_put lo/hi";
goto fail;
}
}
}
}
} else {
tmp = id;
for (i=sizeof(ID)-1; i>=0; i--) {
buf[i] = tmp & 0xff;
tmp >>= 8;
}
rc = cursor->c_get( cursor, key, &data, DB_GET_BOTH );
if ( rc != 0 ) {
err = "c_get";
} else {
rc = cursor->c_del( cursor, 0 );
if ( rc != 0 ) {
err = "c_del";
}
}
}
if ( isrange && rc == 0 ) {
tmp = ( id == lo ) ? idl[1] : idl[2];
for (i=sizeof(ID)-1; i>=0; i--) {
buf[i] = tmp & 0xff;
tmp >>= 8;
}
rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );
if ( rc != 0 ) {
err = "c_put";
}
}
if ( rc && rc != DB_NOTFOUND ) {
/* initial c_get failed, nothing was done */
fail:
if ( rc != DB_NOTFOUND ) {
#ifdef NEW_LOGGING
LDAP_LOG( INDEX, ERR,
"bdb_idl_delete_key: %s failed: %s (%d)\n",
@ -927,6 +969,7 @@ bdb_idl_delete_key(
Debug( LDAP_DEBUG_ANY, "=> bdb_idl_delete_key: "
"%s failed: %s (%d)\n", err, db_strerror(rc), rc );
#endif
}
cursor->c_close( cursor );
return rc;
}
@ -940,10 +983,6 @@ bdb_idl_delete_key(
"=> bdb_idl_delete_key: c_close failed: %s (%d)\n",
db_strerror(rc), rc, 0 );
#endif
return rc;
}
if ( bdb->bi_idl_cache_max_size ) {
bdb_idl_cache_put( bdb, db, key, idl, 0 );
}
return rc;

View file

@ -114,6 +114,32 @@ bdb_db_init( BackendDB *be )
return 0;
}
int
bdb_bt_compare(
DB *db,
const DBT *usrkey,
const DBT *curkey
)
{
unsigned char *u, *c;
int i, x;
u = usrkey->data;
c = curkey->data;
#ifdef WORDS_BIGENDIAN
for( i = 0; i < (int)sizeof(ID); i++)
#else
for( i = sizeof(ID)-1; i >= 0; i--)
#endif
{
x = u[i] - c[i];
if( x ) return x;
}
return 0;
}
static int
bdb_db_open( BackendDB *be )
{
@ -182,16 +208,14 @@ bdb_db_open( BackendDB *be )
bdb->bi_dbenv->set_errcall( bdb->bi_dbenv, bdb_errcall );
bdb->bi_dbenv->set_lk_detect( bdb->bi_dbenv, bdb->bi_lock_detect );
/* default IDL cache to 10x entry cache */
if ( bdb->bi_idl_cache_max_size == 0 )
bdb->bi_idl_cache_max_size = 10 * bdb->bi_cache.c_maxsize;
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_max_size ) {
bdb->bi_idl_tree = NULL;
ldap_pvt_thread_rdwr_init( &bdb->bi_idl_tree_rwlock );
ldap_pvt_thread_mutex_init( &bdb->bi_idl_tree_lrulock );
bdb->bi_idl_cache_size = 0;
}
#endif
#ifdef BDB_SUBDIRS
{
@ -346,6 +370,8 @@ bdb_db_open( BackendDB *be )
}
if( i == BDB_ID2ENTRY ) {
rc = db->bdi_db->set_bt_compare( db->bdi_db,
bdb_bt_compare );
rc = db->bdi_db->set_pagesize( db->bdi_db,
BDB_ID2ENTRY_PAGESIZE );
if ( slapMode & SLAP_TOOL_READMAIN ) {
@ -357,6 +383,8 @@ bdb_db_open( BackendDB *be )
rc = db->bdi_db->set_flags( db->bdi_db,
DB_DUP | DB_DUPSORT );
#ifndef BDB_HIER
rc = db->bdi_db->set_dup_compare( db->bdi_db,
bdb_bt_compare );
if ( slapMode & SLAP_TOOL_READONLY ) {
flags |= DB_RDONLY;
} else {
@ -365,6 +393,8 @@ bdb_db_open( BackendDB *be )
#else
rc = db->bdi_db->set_dup_compare( db->bdi_db,
bdb_dup_compare );
rc = db->bdi_db->set_bt_compare( db->bdi_db,
bdb_bt_compare );
if ( slapMode & (SLAP_TOOL_READONLY|SLAP_TOOL_READMAIN) ) {
flags |= DB_RDONLY;
} else {
@ -439,7 +469,9 @@ bdb_db_close( BackendDB *be )
int rc;
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
struct bdb_db_info *db;
#ifdef SLAP_IDL_CACHE
bdb_idl_cache_entry_t *entry, *next_entry;
#endif
while( bdb->bi_ndatabases-- ) {
db = bdb->bi_databases[bdb->bi_ndatabases];
@ -454,6 +486,7 @@ bdb_db_close( BackendDB *be )
bdb_cache_release_all (&bdb->bi_cache);
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_max_size ) {
ldap_pvt_thread_rdwr_wlock ( &bdb->bi_idl_tree_rwlock );
avl_free( bdb->bi_idl_tree, NULL );
@ -468,6 +501,7 @@ bdb_db_close( BackendDB *be )
}
ldap_pvt_thread_rdwr_wunlock ( &bdb->bi_idl_tree_rwlock );
}
#endif
return 0;
}
@ -518,11 +552,12 @@ bdb_db_destroy( BackendDB *be )
ldap_pvt_thread_rdwr_destroy ( &bdb->bi_pslist_rwlock );
ldap_pvt_thread_mutex_destroy( &bdb->bi_lastid_mutex );
ldap_pvt_thread_mutex_destroy( &bdb->bi_database_mutex );
#ifdef SLAP_IDL_CACHE
if ( bdb->bi_idl_cache_max_size ) {
ldap_pvt_thread_rdwr_destroy( &bdb->bi_idl_tree_rwlock );
ldap_pvt_thread_mutex_destroy( &bdb->bi_idl_tree_lrulock );
}
#endif
ch_free( bdb );
be->be_private = NULL;

View file

@ -203,6 +203,7 @@ BI_entry_get_rw bdb_entry_get;
/*
* idl.c
*/
#ifdef SLAP_IDL_CACHE
#define bdb_idl_cache_get BDB_SYMBOL(idl_cache_get)
#define bdb_idl_cache_put BDB_SYMBOL(idl_cache_put)
@ -227,6 +228,7 @@ bdb_idl_cache_del(
struct bdb_info *bdb,
DB *db,
DBT *key );
#endif
#define bdb_idl_first BDB_SYMBOL(idl_first)
#define bdb_idl_next BDB_SYMBOL(idl_next)