mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-10 08:53:27 -05:00
Revert to original code
This commit is contained in:
parent
5c6ec10f48
commit
113870c194
8 changed files with 321 additions and 251 deletions
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 )) {
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue