From d4a422329b3105c72435ddae3d0de1b5168b44d5 Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Tue, 10 Dec 2002 17:59:21 +0000
Subject: [PATCH] From ITS#2183, use a long-lived IDL stack per thread.

---
 servers/slapd/back-bdb/back-bdb.h |  1 +
 servers/slapd/back-bdb/search.c   | 44 +++++++++++++++++++++++++++++--
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h
index b896191e27..b41aed3a3e 100644
--- a/servers/slapd/back-bdb/back-bdb.h
+++ b/servers/slapd/back-bdb/back-bdb.h
@@ -99,6 +99,7 @@ struct bdb_info {
 	slap_mask_t	bi_defaultmask;
 	Cache		bi_cache;
 	Avlnode		*bi_attrs;
+	void		*bi_search_stack;
 #ifdef BDB_HIER
 	Avlnode		*bi_tree;
 	ldap_pvt_thread_rdwr_t	bi_tree_rdwr;
diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c
index 2ad1e96689..bd9ac9590a 100644
--- a/servers/slapd/back-bdb/search.c
+++ b/servers/slapd/back-bdb/search.c
@@ -957,6 +957,40 @@ static int oc_filter(
 	return rc;
 }
 
+#define SRCH_STACK_SIZE	16
+
+static void search_stack_free( void *key, void *data)
+{
+	ch_free(data);
+}
+
+static void *search_stack(
+	BackendDB *be,
+	Operation *op
+)
+{
+	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+	void *ret = NULL;
+
+	if ( op->o_threadctx ) {
+		ldap_pvt_thread_pool_getkey( op->o_threadctx, search_stack,
+			&ret, NULL );
+	} else {
+		ret = bdb->bi_search_stack;
+	}
+
+	if ( !ret ) {
+		ret = ch_malloc( SRCH_STACK_SIZE * BDB_IDL_UM_SIZE * sizeof( ID ) );
+		if ( op->o_threadctx ) {
+			ldap_pvt_thread_pool_setkey( op->o_threadctx, search_stack,
+				ret, search_stack_free );
+		} else {
+			bdb->bi_search_stack = ret;
+		}
+	}
+	return ret;
+}
+
 static int search_candidates(
 	BackendDB *be,
 	Operation *op,
@@ -1053,11 +1087,17 @@ static int search_candidates(
 #endif
 
 	/* Allocate IDL stack, plus 1 more for former tmp */
-	stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
+	if ( depth+1 > SRCH_STACK_SIZE ) {
+		stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
+	} else {
+		stack = search_stack( be, op );
+	}
 
 	rc = bdb_filter_candidates( be, &f, ids, stack, stack+BDB_IDL_UM_SIZE );
 
-	ch_free( stack );
+	if ( depth+1 > SRCH_STACK_SIZE ) {
+		ch_free( stack );
+	}
 
 	if( rc ) {
 #ifdef NEW_LOGGING
-- 
GitLab