From 9f1fc4865957d0fb1ff0e914ea0b79a968bb7bce Mon Sep 17 00:00:00 2001
From: Kurt Zeilenga <kurt@openldap.org>
Date: Fri, 5 Oct 2001 17:00:21 +0000
Subject: [PATCH] Another round.  BDB_INDEX almost ready for functional
 testing.

---
 servers/slapd/back-bdb/back-bdb.h  |  6 +++-
 servers/slapd/back-bdb/dbcache.c   | 56 ++++++++++++++++++++++++++++--
 servers/slapd/back-bdb/index.c     | 47 +++++++++++++++++++------
 servers/slapd/back-bdb/init.c      |  9 +++--
 servers/slapd/back-bdb/key.c       |  6 ++--
 servers/slapd/back-bdb/proto-bdb.h | 12 ++++---
 servers/slapd/back-bdb/tools.c     | 40 +++++++++++++++------
 7 files changed, 142 insertions(+), 34 deletions(-)

diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h
index d3191f5209..47bc9fb67e 100644
--- a/servers/slapd/back-bdb/back-bdb.h
+++ b/servers/slapd/back-bdb/back-bdb.h
@@ -19,6 +19,7 @@ LDAP_BEGIN_DECL
 /* #define BDB_REINDEX 1 */
 /* #define BDB_FILTER_INDICES 1 */
 #define BDB_CONFIG_INDICES 1
+/* #define SLAPD_USE_AD 1 */
 
 #define DN_BASE_PREFIX		SLAP_INDEX_EQUALITY_PREFIX
 #define DN_ONE_PREFIX	 	'%'
@@ -46,9 +47,12 @@ LDAP_BEGIN_DECL
 #define BDB_NEXTID		0
 #define BDB_DN2ID		1
 #define BDB_ID2ENTRY	2
-#define BDB_INDICES		3
+#define BDB_NDB			3
+
+#define BDB_INDICES		128
 
 struct bdb_db_info {
+	char		*bdi_name;
 	DB			*bdi_db;
 };
 
diff --git a/servers/slapd/back-bdb/dbcache.c b/servers/slapd/back-bdb/dbcache.c
index 1837ed4e1b..7387b2e6f6 100644
--- a/servers/slapd/back-bdb/dbcache.c
+++ b/servers/slapd/back-bdb/dbcache.c
@@ -22,7 +22,59 @@ int
 bdb_db_cache(
     Backend	*be,
     const char *name,
-	DB *db )
+	DB **dbout )
 {
-	return -1;
+	int i;
+	int rc;
+	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+	struct bdb_db_info *db;
+	char *file;
+
+	*dbout = NULL;
+
+	for( i=BDB_NDB; bdb->bi_databases[i]->bdi_name; i++ ) {
+		if( !strcmp( bdb->bi_databases[i]->bdi_name, name) ) {
+			*dbout = bdb->bi_databases[i]->bdi_db;
+			return 0;
+		}
+	}
+
+	if( i >= BDB_INDICES ) {
+		return -1;
+	}
+
+	db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info));
+
+	db->bdi_name = ch_strdup( name );
+
+	rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 );
+	if( rc != 0 ) {
+		Debug( LDAP_DEBUG_ANY,
+			"bdb_db_cache: db_create(%s) failed: %s (%d)\n",
+			bdb->bi_dbenv_home, db_strerror(rc), rc );
+		return rc;
+	}
+
+	file = ch_malloc( strlen( name ) + sizeof(BDB_SUFFIX) );
+	sprintf( file, "%s" BDB_SUFFIX, name );
+
+	rc = db->bdi_db->open( db->bdi_db,
+		file, name,
+		DB_BTREE, DB_CREATE|DB_THREAD,
+		bdb->bi_dbenv_mode );
+
+	ch_free( file );
+
+	if( rc != 0 ) {
+		Debug( LDAP_DEBUG_ANY,
+			"bdb_db_cache: db_open(%s) failed: %s (%d)\n",
+			name, db_strerror(rc), rc );
+		return rc;
+	}
+
+	bdb->bi_databases[i] = db;
+
+	*dbout = db->bdi_db;
+
+	return 0;
 }
diff --git a/servers/slapd/back-bdb/index.c b/servers/slapd/back-bdb/index.c
index 3ce26c7e28..6b7c16c7b9 100644
--- a/servers/slapd/back-bdb/index.c
+++ b/servers/slapd/back-bdb/index.c
@@ -149,13 +149,6 @@ static int indexer(
 
 	assert( mask );
 
-	rc = slap_str2ad( atname, &ad, &text );
-
-	if( rc != LDAP_SUCCESS ) return rc;
-
-	prefix.bv_val = atname;
-	prefix.bv_len = strlen( atname );
-
 	rc = bdb_db_cache( be, dbname, &db );
 	
 	if ( rc != LDAP_SUCCESS ) {
@@ -167,13 +160,20 @@ static int indexer(
 			"<= bdb_index_read NULL (could not open %s)\n",
 			dbname, 0, 0 );
 #endif
-
-		ad_free( ad, 1 );
 		return LDAP_OTHER;
 	}
 
+	rc = slap_str2ad( atname, &ad, &text );
+	if( rc != LDAP_SUCCESS ) return rc;
+
+	prefix.bv_val = atname;
+	prefix.bv_len = strlen( atname );
+
 	if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
 		rc = bdb_key_change( be, db, txn, &prefix, id, op );
+		if( rc ) {
+			goto done;
+		}
 	}
 
 	if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
@@ -187,9 +187,14 @@ static int indexer(
 		if( rc == LDAP_SUCCESS && keys != NULL ) {
 			for( i=0; keys[i] != NULL; i++ ) {
 				rc = bdb_key_change( be, db, txn, keys[i], id, op );
+				if( rc ) {
+					ber_bvecfree( keys );
+					goto done;
+				}
 			}
 			ber_bvecfree( keys );
 		}
+		rc = LDAP_SUCCESS;
 	}
 
 	if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
@@ -203,9 +208,15 @@ static int indexer(
 		if( rc == LDAP_SUCCESS && keys != NULL ) {
 			for( i=0; keys[i] != NULL; i++ ) {
 				rc = bdb_key_change( be, db, txn, keys[i], id, op );
+				if( rc ) {
+					ber_bvecfree( keys );
+					goto done;
+				}
 			}
 			ber_bvecfree( keys );
 		}
+
+		rc = LDAP_SUCCESS;
 	}
 
 	if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
@@ -219,13 +230,20 @@ static int indexer(
 		if( rc == LDAP_SUCCESS && keys != NULL ) {
 			for( i=0; keys[i] != NULL; i++ ) {
 				bdb_key_change( be, db, txn, keys[i], id, op );
+				if( rc ) {
+					ber_bvecfree( keys );
+					goto done;
+				}
 			}
 			ber_bvecfree( keys );
 		}
+
+		rc = LDAP_SUCCESS;
 	}
 
+done:
 	ad_free( ad, 1 );
-	return LDAP_SUCCESS;
+	return rc;
 }
 
 static int index_at_values(
@@ -250,6 +268,8 @@ static int index_at_values(
 			type->sat_sup, lang,
 			vals, id, op,
 			dbnamep, &tmpmask );
+
+		if( rc ) return rc;
 	}
 
 	bdb_attr_mask( be->be_private, type->sat_cname, &mask );
@@ -265,6 +285,8 @@ static int index_at_values(
 			type->sat_cname,
 			vals, id, op,
 			mask );
+
+		if( rc ) return rc;
 	}
 
 	if( lang ) {
@@ -288,6 +310,11 @@ static int index_at_values(
 			rc = indexer( be, txn, dbname, lname,
 				vals, id, op,
 				tmpmask );
+
+			if( rc ) {
+				ch_free( lname );
+				return rc;
+			}
 		}
 
 		ch_free( lname );
diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c
index 1e002c218d..ed28d77a31 100644
--- a/servers/slapd/back-bdb/init.c
+++ b/servers/slapd/back-bdb/init.c
@@ -18,10 +18,11 @@ static struct bdbi_database {
 	char *name;
 	int type;
 	int flags;
-} bdbi_databases[BDB_INDICES] = {
+} bdbi_databases[] = {
 	{ "nextid" BDB_SUFFIX, "nextid", DB_BTREE, 0 },
 	{ "dn2entry" BDB_SUFFIX, "dn2entry", DB_BTREE, 0 },
 	{ "id2entry" BDB_SUFFIX, "id2entry", DB_BTREE, 0 },
+	{ NULL, NULL, 0, 0 }
 };
 
 #if 0
@@ -181,7 +182,7 @@ bdb_db_open( BackendDB *be )
 		BDB_INDICES * sizeof(struct bdb_db_info *) );
 
 	/* open (and create) main database */
-	for( i = 0; i < BDB_INDICES; i++ ) {
+	for( i = 0; bdbi_databases[i].name; i++ ) {
 		struct bdb_db_info *db;
 
 		db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info));
@@ -208,9 +209,13 @@ bdb_db_open( BackendDB *be )
 			return rc;
 		}
 
+		db->bdi_name = bdbi_databases[i].name;
 		bdb->bi_databases[i] = db;
 	}
 
+	bdb->bi_databases[i] = NULL;
+	bdb->bi_ndatabases = i;
+
 	/* get nextid */
 	rc = bdb_last_id( be, NULL );
 	if( rc != 0 ) {
diff --git a/servers/slapd/back-bdb/key.c b/servers/slapd/back-bdb/key.c
index f5b877e5a2..f2d0eed586 100644
--- a/servers/slapd/back-bdb/key.c
+++ b/servers/slapd/back-bdb/key.c
@@ -36,8 +36,7 @@ bdb_key_read(
 #endif
 
 	DBzero( &key );
-	key.data = k->bv_val;
-	key.size = k->bv_len;
+	bv2DBT(k,&key);
 
 	rc = bdb_idl_fetch_key( be, db, txn, key, ids );
 
@@ -90,8 +89,7 @@ bdb_key_change(
 #endif
 
 	DBTzero( &key );
-	key.data = k->bv_val;
-	key.size = k->bv_len;
+	bv2DBT(k,&key);
 
 	if (op == SLAP_INDEX_ADD_OP) {
 	    /* Add values */
diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h
index 7e641bf9d5..6ecab7c789 100644
--- a/servers/slapd/back-bdb/proto-bdb.h
+++ b/servers/slapd/back-bdb/proto-bdb.h
@@ -29,9 +29,13 @@ Entry *bdb_deref_internal_r LDAP_P((
  * attr.c
  */
 
-void bdb_attr_mask LDAP_P(( struct bdb_info *bdb,
-	const char *desc,
-	slap_mask_t *indexmask ));
+void bdb_attr_mask( struct bdb_info *bdb,
+#ifdef SLAPD_USE_AD
+	AttributeDescription *desc,
+#else
+    const char *desc,
+#endif
+	slap_mask_t *indexmask );
 
 int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb,
 	const char *fname, int lineno,
@@ -46,7 +50,7 @@ int
 bdb_db_cache(
     Backend	*be,
     const char *name,
-	DB *db );
+	DB **db );
 
 /*
  * dn2entry.c
diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c
index 2f62e09a2a..853746447b 100644
--- a/servers/slapd/back-bdb/tools.c
+++ b/servers/slapd/back-bdb/tools.c
@@ -177,10 +177,10 @@ done:
 		}
 
 	} else {
-		Debug( LDAP_DEBUG_ANY,
-			"=> bdb_tool_entry_put: txn_aborted!\n",
-			0, 0, 0 );
 		txn_abort( tid );
+		Debug( LDAP_DEBUG_ANY,
+			"=> bdb_tool_entry_put: txn_aborted! %s (%d)\n",
+			db_strerror(rc), rc, 0 );
 		e->e_id = NOID;
 	}
 
@@ -200,22 +200,23 @@ int bdb_tool_entry_reindex(
 	Debug( LDAP_DEBUG_ARGS, "=> bdb_tool_entry_reindex( %ld )\n",
 		(long) id, 0, 0 );
 
-#if 0
-	rc = txn_begin( bi->bi_dbenv, NULL, &tid, 0 );
-#endif
- 	
 	e = bdb_tool_entry_get( be, id );
 
 	if( e == NULL ) {
 		Debug( LDAP_DEBUG_ANY,
 			"bdb_tool_entry_reindex:: could not locate id=%ld\n",
 			(long) id, 0, 0 );
-#if 0
-		txn_abort( tid );
-#endif
 		return -1;
 	}
 
+	rc = txn_begin( bi->bi_dbenv, NULL, &tid, 0 );
+	if( rc != 0 ) {
+		Debug( LDAP_DEBUG_ANY,
+			"=> bdb_tool_entry_reindex: txn_begin failed: %s (%d)\n",
+			db_strerror(rc), rc, 0 );
+		goto done;
+	}
+ 	
 	/*
 	 * just (re)add them for now
 	 * assume that some other routine (not yet implemented)
@@ -228,8 +229,25 @@ int bdb_tool_entry_reindex(
 
 	rc = bdb_index_entry_add( be, tid, e, e->e_attrs );
 
-	entry_free( e );
+	if( rc == 0 ) {
+		rc = txn_commit( tid, 0 );
+		if( rc != 0 ) {
+			Debug( LDAP_DEBUG_ANY,
+				"=> bdb_tool_entry_reindex: txn_commit failed: %s (%d)\n",
+				db_strerror(rc), rc, 0 );
+			e->e_id = NOID;
+		}
+
+	} else {
+		txn_abort( tid );
+		Debug( LDAP_DEBUG_ANY,
+			"=> bdb_tool_entry_reindex: txn_aborted! %s (%d)\n",
+			db_strerror(rc), rc, 0 );
+		e->e_id = NOID;
+	}
 
+done:
+	entry_free( e );
 	return rc;
 }
 #endif
-- 
GitLab