From b45133c9580a692ebeb8bd81552a60ba406e0f24 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 27 Nov 2001 10:15:23 +0000 Subject: [PATCH] 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. --- servers/slapd/back-bdb/back-bdb.h | 9 +- servers/slapd/back-bdb/init.c | 19 +++- servers/slapd/back-bdb/nextid.c | 153 +++++------------------------- 3 files changed, 45 insertions(+), 136 deletions(-) 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; } -- 2.39.5