From 0f17fac37dbde13ab47898d07f6ebea710f79714 Mon Sep 17 00:00:00 2001
From: Kurt Zeilenga <kurt@openldap.org>
Date: Fri, 22 Jan 1999 02:26:19 +0000
Subject: [PATCH] Implement NEXTID chunking.  Obtain IDs in chunks of size
 SLAPD_NEXTID_CHUNK.  Code protects NEXTID file to ensure its equal to or
 greater than nextid.  Updated on close to actual nextid.  next_id_save()
 could be called periodically if desired.  Default chunk size is 32.  Define
 to 1 to disable chunking.

---
 servers/slapd/back-ldbm/back-ldbm.h       |  8 ++++++
 servers/slapd/back-ldbm/close.c           |  5 ++++
 servers/slapd/back-ldbm/init.c            |  4 +++
 servers/slapd/back-ldbm/nextid.c          | 35 ++++++++++++++++++++++-
 servers/slapd/back-ldbm/proto-back-ldbm.h |  1 +
 5 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/servers/slapd/back-ldbm/back-ldbm.h b/servers/slapd/back-ldbm/back-ldbm.h
index 227bde5a40..5f46374c79 100644
--- a/servers/slapd/back-ldbm/back-ldbm.h
+++ b/servers/slapd/back-ldbm/back-ldbm.h
@@ -104,8 +104,16 @@ struct attrinfo {
 
 #define MAXDBCACHE	10
 
+/* this could be made an option */
+#ifndef SLAPD_NEXTID_CHUNK
+#define SLAPD_NEXTID_CHUNK	32
+#endif
+
 struct ldbminfo {
 	ID			li_nextid;
+#if SLAPD_NEXTID_CHUNK > 1
+	ID			li_nextid_wrote;
+#endif
 	char		*li_nextid_file;
 	pthread_mutex_t		li_root_mutex;
 	pthread_mutex_t		li_add_mutex;
diff --git a/servers/slapd/back-ldbm/close.c b/servers/slapd/back-ldbm/close.c
index 4539163b2f..310f441b5d 100644
--- a/servers/slapd/back-ldbm/close.c
+++ b/servers/slapd/back-ldbm/close.c
@@ -12,6 +12,11 @@
 void
 ldbm_back_close( Backend *be )
 {
+	Debug( LDAP_DEBUG_TRACE, "ldbm backend saving nextid\n", 0, 0, 0 );
+	if ( next_id_save( be ) < 0 ) {
+		Debug( LDAP_DEBUG_ANY, "ldbm backend nextid save failed!\n", 0, 0, 0 );
+	}
+
 	Debug( LDAP_DEBUG_TRACE, "ldbm backend syncing\n", 0, 0, 0 );
 	ldbm_cache_flush_all( be );
 	Debug( LDAP_DEBUG_TRACE, "ldbm backend done syncing\n", 0, 0, 0 );
diff --git a/servers/slapd/back-ldbm/init.c b/servers/slapd/back-ldbm/init.c
index aecffaddc6..eccc6d2266 100644
--- a/servers/slapd/back-ldbm/init.c
+++ b/servers/slapd/back-ldbm/init.c
@@ -29,6 +29,10 @@ ldbm_back_init(
 	/* arrange to read nextid later (on first request for it) */
 	li->li_nextid = NOID;
 
+#if SLAPD_NEXTID_CHUNK > 1
+	li->li_nextid_wrote = NOID;
+#endif
+
 	/* default cache size */
 	li->li_cache.c_maxsize = DEFAULT_CACHE_SIZE;
 
diff --git a/servers/slapd/back-ldbm/nextid.c b/servers/slapd/back-ldbm/nextid.c
index ac899e05f7..e29d86b6ca 100644
--- a/servers/slapd/back-ldbm/nextid.c
+++ b/servers/slapd/back-ldbm/nextid.c
@@ -82,6 +82,20 @@ next_id_write( Backend *be, ID id )
 	return rc;
 }
 
+int
+next_id_save( Backend *be )
+{
+	struct ldbminfo	*li = (struct ldbminfo *) be->be_private;
+	ID id = next_id_get( be );
+	int rc = next_id_write( be, id );
+
+	if (rc == 0) {
+		li->li_nextid_wrote = id;
+	}
+
+	return rc;
+}
+
 ID
 next_id( Backend *be )
 {
@@ -97,10 +111,22 @@ next_id( Backend *be )
 		if ( li->li_nextid == NOID ) {
 			li->li_nextid = 1;
 		}
+
+#if SLAPD_NEXTID_CHUNK > 1
+		li->li_nextid_wrote = li->li_nextid;
+#endif
 	}
 
 	id = li->li_nextid++;
+
+#if SLAPD_NEXTID_CHUNK > 1
+	if ( li->li_nextid > li->li_nextid_wrote ) {
+		li->li_nextid_wrote += SLAPD_NEXTID_CHUNK;
+		(void) next_id_write( be, li->li_nextid_wrote );
+	}
+#else
 	(void) next_id_write( be, li->li_nextid );
+#endif
 
 	pthread_mutex_unlock( &li->li_nextid_mutex );
 	return( id );
@@ -109,7 +135,7 @@ next_id( Backend *be )
 void
 next_id_return( Backend *be, ID id )
 {
-#ifdef NEXT_ID_RETURN
+#ifdef SLAPD_NEXTID_RETURN
 	struct ldbminfo	*li = (struct ldbminfo *) be->be_private;
 
 	pthread_mutex_lock( &li->li_nextid_mutex );
@@ -120,7 +146,10 @@ next_id_return( Backend *be, ID id )
 	}
 
 	li->li_nextid--;
+
+#if !( SLAPD_NEXTID_CHUCK > 1 )
 	(void) next_id_write( be, li->li_nextid );
+#endif
 
 	pthread_mutex_unlock( &li->li_nextid_mutex );
 #endif
@@ -141,6 +170,10 @@ next_id_get( Backend *be )
 		if ( li->li_nextid == NOID ) {
 			li->li_nextid = 1;
 		}
+
+#if SLAPD_NEXTID_CHUNK > 1
+		li->li_nextid_wrote = li->li_nextid;
+#endif
 	}
 
 	id = li->li_nextid;
diff --git a/servers/slapd/back-ldbm/proto-back-ldbm.h b/servers/slapd/back-ldbm/proto-back-ldbm.h
index c5d8ce936a..e59388f73f 100644
--- a/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -128,6 +128,7 @@ int index_add_values LDAP_P(( Backend *be, char *type, struct berval **vals, ID
 ID next_id LDAP_P(( Backend *be ));
 void next_id_return LDAP_P(( Backend *be, ID id ));
 ID next_id_get LDAP_P(( Backend *be ));
+int next_id_save LDAP_P(( Backend *be ));
 
 LDAP_END_DECL
 #endif
-- 
GitLab