From: Howard Chu Date: Tue, 27 Nov 2001 10:15:23 +0000 (+0000) Subject: Eliminated nextid database. id2entry database is now maintained in numerical X-Git-Tag: LDBM_PRE_GIANT_RWLOCK~830 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=b45133c9580a692ebeb8bd81552a60ba406e0f24;p=openldap Eliminated nextid database. id2entry database is now maintained in numerical order, so the lastid is always the same as the last entry's ID. This is an incompatible db file change. --- diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h index 9fd5028113..9932bfb8bb 100644 --- a/servers/slapd/back-bdb/back-bdb.h +++ b/servers/slapd/back-bdb/back-bdb.h @@ -40,10 +40,9 @@ LDAP_BEGIN_DECL #endif #define BDB_SUFFIX ".bdb" -#define BDB_NEXTID 0 -#define BDB_ID2ENTRY 1 -#define BDB_DN2ID 2 -#define BDB_NDB 3 +#define BDB_ID2ENTRY 0 +#define BDB_DN2ID 1 +#define BDB_NDB 2 #define BDB_INDICES 128 @@ -80,9 +79,9 @@ struct bdb_info { #endif ID bi_lastid; + ldap_pvt_thread_mutex_t bi_lastid_mutex; }; -#define bi_nextid bi_databases[BDB_NEXTID] #define bi_id2entry bi_databases[BDB_ID2ENTRY] #define bi_dn2id bi_databases[BDB_DN2ID] diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index 73dbb384ef..ac97844cbe 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -19,7 +19,6 @@ static struct bdbi_database { int type; int flags; } bdbi_databases[] = { - { "nextid" BDB_SUFFIX, "nextid", DB_BTREE, 0 }, { "id2entry" BDB_SUFFIX, "id2entry", DB_BTREE, 0 }, { "dn2id" BDB_SUFFIX, "dn2id", DB_BTREE, 0 }, { NULL, NULL, 0, 0 } @@ -73,6 +72,7 @@ bdb_db_init( BackendDB *be ) #endif ldap_pvt_thread_mutex_init( &bdb->bi_database_mutex ); + ldap_pvt_thread_mutex_init( &bdb->bi_lastid_mutex ); be->be_private = bdb; return 0; @@ -99,6 +99,19 @@ static void *lock_detect_task( void *arg ) } #endif +int +bdb_bt_compare( + DB *db, + DBT *usrkey, + DBT *curkey +) +{ + ID usr, cur; + memcpy(&usr, usrkey->data, sizeof(ID)); + memcpy(&cur, curkey->data, sizeof(ID)); + return usr - cur; +} + static int bdb_db_open( BackendDB *be ) { @@ -216,6 +229,10 @@ bdb_db_open( BackendDB *be ) return rc; } + if( i == BDB_ID2ENTRY ) { + rc = db->bdi_db->set_bt_compare( db->bdi_db, + bdb_bt_compare ); + } rc = db->bdi_db->open( db->bdi_db, bdbi_databases[i].file, bdbi_databases[i].name, diff --git a/servers/slapd/back-bdb/nextid.c b/servers/slapd/back-bdb/nextid.c index f7a3e6dfba..5f2b6e30a5 100644 --- a/servers/slapd/back-bdb/nextid.c +++ b/servers/slapd/back-bdb/nextid.c @@ -15,160 +15,53 @@ int bdb_next_id( BackendDB *be, DB_TXN *tid, ID *out ) { struct bdb_info *bdb = (struct bdb_info *) be->be_private; - int rc; - ID kid = NOID; - ID id; - DBT key, data; - DB_TXN *ltid = NULL; - - DBTzero( &key ); - key.data = (char *) &kid; - key.size = sizeof( kid ); - - DBTzero( &data ); - data.data = (char *) &id; - data.ulen = sizeof( id ); - data.flags = DB_DBT_USERMEM; - - if( 0 ) { -retry: if( tid != NULL ) { - /* nested transaction, abort and return */ - (void) txn_abort( ltid ); - Debug( LDAP_DEBUG_ANY, - "=> bdb_next_id: aborted!\n", - 0, 0, 0 ); - return rc; - } - rc = txn_abort( ltid ); - if( rc != 0 ) { - Debug( LDAP_DEBUG_ANY, - "=> bdb_next_id: txn_abort failed: %s (%d)\n", - db_strerror(rc), rc, 0 ); - return rc; - } - } - - if( bdb->bi_txn ) { - rc = txn_begin( bdb->bi_dbenv, tid, <id, 0 ); - if( rc != 0 ) { - Debug( LDAP_DEBUG_ANY, - "=> bdb_next_id: txn_begin failed: %s (%d)\n", - db_strerror(rc), rc, 0 ); - return rc; - } - } - - /* get existing value for read/modify/write */ - rc = bdb->bi_nextid->bdi_db->get( bdb->bi_nextid->bdi_db, - ltid, &key, &data, DB_RMW ); - - switch(rc) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - - case DB_NOTFOUND: - id = 0; - break; - case 0: - if ( data.size != sizeof( id ) ) { - Debug( LDAP_DEBUG_ANY, - "=> bdb_next_id: get size mismatch: expected %ld, got %ld\n", - (long) sizeof( id ), (long) data.size, 0 ); - rc = -1; - goto done; - } - break; + ldap_pvt_thread_mutex_lock( &bdb->bi_lastid_mutex ); + *out = ++bdb->bi_lastid; + ldap_pvt_thread_mutex_unlock( &bdb->bi_lastid_mutex ); - default: - Debug( LDAP_DEBUG_ANY, - "=> bdb_next_id: get failed: %s (%d)\n", - db_strerror(rc), rc, 0 ); - goto done; - } - - if( bdb->bi_lastid > id ) id = bdb->bi_lastid; - - id++; - data.size = sizeof( id ); - - /* put new value */ - rc = bdb->bi_nextid->bdi_db->put( bdb->bi_nextid->bdi_db, - ltid, &key, &data, 0 ); - - switch(rc) { - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto retry; - - case 0: - *out = id; - - bdb->bi_lastid = id; - - if (bdb->bi_txn) { - rc = txn_commit( ltid, 0 ); - ltid = NULL; - } - - if( rc != 0 ) { - Debug( LDAP_DEBUG_ANY, - "=> bdb_next_id: commit failed: %s (%d)\n", - db_strerror(rc), rc, 0 ); - } - break; - - default: - Debug( LDAP_DEBUG_ANY, - "=> bdb_next_id: put failed: %s (%d)\n", - db_strerror(rc), rc, 0 ); -done: (void) txn_abort( ltid ); - } - - return rc; + return 0; } int bdb_last_id( BackendDB *be, DB_TXN *tid ) { struct bdb_info *bdb = (struct bdb_info *) be->be_private; int rc; - ID kid = NOID; - ID id; + ID id = 0; DBT key, data; + DBC *cursor; DBTzero( &key ); - key.data = (char *) &kid; - key.size = sizeof( kid ); + key.flags = DB_DBT_USERMEM; + key.data = (char *) &id; + key.ulen = sizeof( id ); DBTzero( &data ); - data.data = (char *) &id; - data.ulen = sizeof( id ); - data.flags = DB_DBT_USERMEM; + data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; - /* get existing value for read/modify/write */ - rc = bdb->bi_nextid->bdi_db->get( bdb->bi_nextid->bdi_db, - tid, &key, &data, 0 ); + /* Get a read cursor */ + rc = bdb->bi_id2entry->bdi_db->cursor( bdb->bi_id2entry->bdi_db, + tid, &cursor, 0 ); + + while (rc == 0) { + rc = cursor->c_get(cursor, &key, &data, DB_LAST); + cursor->c_close(cursor); + if (rc != 0) + break; + break; + } switch(rc) { case DB_NOTFOUND: id = 0; rc = 0; - break; - + /* FALLTHROUGH */ case 0: - if ( data.size != sizeof( id ) ) { - Debug( LDAP_DEBUG_ANY, - "=> bdb_last_id: get size mismatch: expected %ld, got %ld\n", - (long) sizeof( id ), (long) data.size, 0 ); - rc = -1; - goto done; - } break; default: Debug( LDAP_DEBUG_ANY, - "=> bdb_next_id: get failed: %s (%d)\n", + "=> bdb_last_id: get failed: %s (%d)\n", db_strerror(rc), rc, 0 ); goto done; }