]> git.sur5r.net Git - openldap/commitdiff
Use a single malloc'd block for all the temporary IDL storage in the
authorHoward Chu <hyc@openldap.org>
Mon, 18 Mar 2002 11:40:58 +0000 (11:40 +0000)
committerHoward Chu <hyc@openldap.org>
Mon, 18 Mar 2002 11:40:58 +0000 (11:40 +0000)
filter processing, to avoid runtime stack blowout. Also removes the
need for gigantic thread stacks.

servers/slapd/back-bdb/filterindex.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/search.c

index 8387a702ba3a3ff7d71776a503b54ee15ea019fa..4d973ce67d4addaf83a93893af43a29a5f366213 100644 (file)
@@ -39,14 +39,16 @@ static int list_candidates(
        Filter *flist,
        int ftype,
        ID *ids,
-       ID *tmp );
+       ID *tmp,
+       ID *stack );
 
 int
 bdb_filter_candidates(
        Backend *be,
        Filter  *f,
        ID *ids,
-       ID *tmp )
+       ID *tmp,
+       ID *stack )
 {
        int rc = -1;
 #ifdef NEW_LOGGING
@@ -146,7 +148,7 @@ bdb_filter_candidates(
                Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
 #endif
                rc = list_candidates( be, 
-                       f->f_and, LDAP_FILTER_AND, ids, tmp );
+                       f->f_and, LDAP_FILTER_AND, ids, tmp, stack );
                break;
 
        case LDAP_FILTER_OR:
@@ -156,7 +158,7 @@ bdb_filter_candidates(
                Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
 #endif
                rc = list_candidates( be, 
-                       f->f_or, LDAP_FILTER_OR, ids, tmp );
+                       f->f_or, LDAP_FILTER_OR, ids, tmp, stack );
                break;
 
        default:
@@ -187,20 +189,13 @@ list_candidates(
        Filter  *flist,
        int             ftype,
        ID *ids,
-       ID *tmp )
+       ID *tmp,
+       ID *save )
 {
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        int rc = 0;
        Filter  *f;
 
-/* Systems that can't increase thread stack size will die with these
- * structures allocated on the stack. */
-#if !defined(LDAP_PVT_THREAD_STACK_SIZE) || (LDAP_PVT_THREAD_STACK_SIZE == 0)
-       ID *save = ch_malloc(BDB_IDL_UM_SIZEOF);
-#else
-       ID save[BDB_IDL_UM_SIZE];
-#endif
-
 #ifdef NEW_LOGGING
        LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_list_candidates: 0x%x\n", ftype));
 #else
@@ -215,7 +210,8 @@ list_candidates(
        }
 
        for ( f = flist; f != NULL; f = f->f_next ) {
-               rc = bdb_filter_candidates( be, f, save, tmp );
+               rc = bdb_filter_candidates( be, f, save, tmp,
+                       save+BDB_IDL_UM_SIZE );
 
                if ( rc != 0 ) {
                        if ( ftype == LDAP_FILTER_AND ) {
@@ -235,10 +231,6 @@ list_candidates(
                }
        }
 
-#if !defined(LDAP_PVT_THREAD_STACK_SIZE) || (LDAP_PVT_THREAD_STACK_SIZE == 0)
-       free(save);
-#endif
-
        if( rc ) {
 #ifdef NEW_LOGGING
                LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_list_candidates: id=%ld first=%ld last=%ld\n", (long) ids[0], (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) ));
index d29256860e050e0b53fffc09a1fb411ff8c5addd..cdea9803e190411fc29f2d066bf0051eca884bc4 100644 (file)
@@ -120,7 +120,8 @@ int bdb_filter_candidates(
        Backend *be,
        Filter  *f,
        ID *ids,
-       ID *tmp );
+       ID *tmp,
+       ID *stack );
 
 /*
  * group.c
index df7ce17dd2e03f7694ee4364dcdad70ae9f51af9..af75427d2a6be4746f30e1ea3cd9260145571a58 100644 (file)
@@ -541,14 +541,19 @@ static int base_candidate(
 }
 
 /* Is "objectClass=xx" mentioned anywhere in this filter? Presence
- * doesn't count, we're looking for explicit values.
+ * doesn't count, we're looking for explicit values. Also count depth
+ * of filter tree while we're at it.
  */
 static int oc_filter(
-       Filter *f
+       Filter *f,
+       int cur,
+       int *max
 )
 {
        int rc = 0;
 
+       if( cur > *max ) *max = cur;
+
        switch(f->f_choice) {
        case LDAP_FILTER_EQUALITY:
        case LDAP_FILTER_APPROX:
@@ -563,8 +568,9 @@ static int oc_filter(
 
        case LDAP_FILTER_AND:
        case LDAP_FILTER_OR:
+               cur++;
                for (f=f->f_and; f; f=f->f_next)
-                       if ((rc = oc_filter(f)))
+                       if ((rc = oc_filter(f, cur, max)))
                                break;
                break;
        default:
@@ -582,9 +588,9 @@ static int search_candidates(
        int deref,
        ID      *ids )
 {
-       int rc;
+       int rc, depth = 1;
        Filter          f, scopef, rf, xf;
-       ID              tmp[BDB_IDL_UM_SIZE];
+       ID              *stack;
        AttributeAssertion aa_ref;
 #ifdef BDB_SUBENTRIES
        Filter  sf;
@@ -618,7 +624,7 @@ static int search_candidates(
        /* If the user's filter doesn't mention objectClass, or if
         * it just uses objectClass=*, these clauses are redundant.
         */
-       if (oc_filter(filter) && !get_subentries_visibility(op) ) {
+       if (oc_filter(filter, 1, &depth) && !get_subentries_visibility(op) ) {
                if( !get_manageDSAit(op) ) { /* match referrals */
                        struct berval bv_ref = { sizeof("REFERRAL")-1, "REFERRAL" };
                        rf.f_choice = LDAP_FILTER_EQUALITY;
@@ -640,6 +646,8 @@ static int search_candidates(
                        xf.f_or = &af;
                }
 #endif
+               /* We added one of these clauses, filter depth increased */
+               if( xf.f_or != filter ) depth++;
        }
 
        f.f_next = NULL;
@@ -650,6 +658,8 @@ static int search_candidates(
                : SLAPD_FILTER_DN_ONE;
        scopef.f_dn = &e->e_nname;
        scopef.f_next = xf.f_or == filter ? filter : &xf ;
+       /* Filter depth increased again, adding scope clause */
+       depth++;
 
 #ifdef BDB_SUBENTRIES
        if( get_subentries_visibility( op ) ) {
@@ -663,7 +673,12 @@ static int search_candidates(
        }
 #endif
 
-       rc = bdb_filter_candidates( be, &f, ids, tmp );
+       /* Allocate IDL stack, plus 1 more for former tmp */
+       stack = malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
+
+       rc = bdb_filter_candidates( be, &f, ids, stack, stack+BDB_IDL_UM_SIZE );
+
+       free( stack );
 
        if( rc ) {
 #ifdef NEW_LOGGING