]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/pcache.c
Merge remote-tracking branch 'origin/mdb.master'
[openldap] / servers / slapd / overlays / pcache.c
index 63bb249aebe932789daf407244998cc4d9029412..6971694282bcf848b42882deb94b1a581245157c 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2003-2011 The OpenLDAP Foundation.
+ * Copyright 2003-2012 The OpenLDAP Foundation.
  * Portions Copyright 2003 IBM Corporation.
  * Portions Copyright 2003-2009 Symas Corporation.
  * All rights reserved.
@@ -922,38 +922,49 @@ static int pcache_filter_cmp( Filter *f1, Filter *f2 )
        int rc, weight1, weight2;
 
        switch( f1->f_choice ) {
-       case LDAP_FILTER_PRESENT:
+       case LDAP_FILTER_AND:
+       case LDAP_FILTER_OR:
                weight1 = 0;
                break;
+       case LDAP_FILTER_PRESENT:
+               weight1 = 1;
+               break;
        case LDAP_FILTER_EQUALITY:
        case LDAP_FILTER_GE:
        case LDAP_FILTER_LE:
-               weight1 = 1;
+               weight1 = 2;
                break;
        default:
-               weight1 = 2;
+               weight1 = 3;
        }
        switch( f2->f_choice ) {
-       case LDAP_FILTER_PRESENT:
+       case LDAP_FILTER_AND:
+       case LDAP_FILTER_OR:
                weight2 = 0;
                break;
+       case LDAP_FILTER_PRESENT:
+               weight2 = 1;
+               break;
        case LDAP_FILTER_EQUALITY:
        case LDAP_FILTER_GE:
        case LDAP_FILTER_LE:
-               weight2 = 1;
+               weight2 = 2;
                break;
        default:
-               weight2 = 2;
+               weight2 = 3;
        }
        rc = weight1 - weight2;
        if ( !rc ) {
                switch( weight1 ) {
                case 0:
+                       rc = pcache_filter_cmp( f1->f_and, f2->f_and );
                        break;
                case 1:
-                       rc = lex_bvcmp( &f1->f_av_value, &f2->f_av_value );
                        break;
                case 2:
+                       rc = lex_bvcmp( &f1->f_av_value, &f2->f_av_value );
+                       break;
+               case 3:
                        if ( f1->f_choice == LDAP_FILTER_SUBSTRINGS ) {
                                rc = 0;
                                if ( !BER_BVISNULL( &f1->f_sub_initial )) {
@@ -994,7 +1005,7 @@ static int pcache_filter_cmp( Filter *f1, Filter *f2 )
                        }
                        break;
                }
-               if ( !rc ) {
+               while ( !rc ) {
                        f1 = f1->f_next;
                        f2 = f2->f_next;
                        if ( f1 || f2 ) {
@@ -1003,12 +1014,10 @@ static int pcache_filter_cmp( Filter *f1, Filter *f2 )
                                else if ( !f2 )
                                        rc = 1;
                                else {
-                                       while ( f1->f_choice == LDAP_FILTER_AND || f1->f_choice == LDAP_FILTER_OR )
-                                               f1 = f1->f_and;
-                                       while ( f2->f_choice == LDAP_FILTER_AND || f2->f_choice == LDAP_FILTER_OR )
-                                               f2 = f2->f_and;
                                        rc = pcache_filter_cmp( f1, f2 );
                                }
+                       } else {
+                               break;
                        }
                }
        }
@@ -1019,7 +1028,7 @@ static int pcache_filter_cmp( Filter *f1, Filter *f2 )
 static int pcache_query_cmp( const void *v1, const void *v2 )
 {
        const CachedQuery *q1 = v1, *q2 =v2;
-       return pcache_filter_cmp( q1->first, q2->first );
+       return pcache_filter_cmp( q1->filter, q2->filter );
 }
 
 /* add query on top of LRU list */
@@ -1343,14 +1352,16 @@ nextpass:                       eqpass = 1;
                        switch (fs->f_choice) {
                        case LDAP_FILTER_OR:
                        case LDAP_FILTER_AND:
+                               if ( fs->f_next ) {
+                                       /* save our stack position */
+                                       fsp = op->o_tmpalloc(sizeof(fstack), op->o_tmpmemctx);
+                                       fsp->fs_next = stack;
+                                       fsp->fs_fs = fs->f_next;
+                                       fsp->fs_fi = fi->f_next;
+                                       stack = fsp;
+                               }
                                fs = fs->f_and;
                                fi = fi->f_and;
-                               /* save our stack position */
-                               fsp = op->o_tmpalloc(sizeof(fstack), op->o_tmpmemctx);
-                               fsp->fs_next = stack;
-                               fsp->fs_fs = fs->f_next;
-                               fsp->fs_fi = fi->f_next;
-                               stack = fsp;
                                res=1;
                                break;
                        case LDAP_FILTER_SUBSTRINGS:
@@ -1399,6 +1410,7 @@ nextpass:                 eqpass = 1;
                                break;
                        }
                        if (!fs && !fi && stack) {
+                               /* pop the stack */
                                fsp = stack;
                                stack = fsp->fs_next;
                                fs = fsp->fs_fs;
@@ -2331,62 +2343,6 @@ pcache_op_cleanup( Operation *op, SlapReply *rs ) {
        cache_manager *cm = on->on_bi.bi_private;
        query_manager*          qm = cm->qm;
 
-       if ( rs->sr_type == REP_SEARCH ) {
-               Entry *e;
-
-               /* don't return more entries than requested by the client */
-               if ( si->slimit > 0 && rs->sr_nentries >= si->slimit ) {
-                       si->slimit_exceeded = 1;
-               }
-
-               /* If we haven't exceeded the limit for this query,
-                * build a chain of answers to store. If we hit the
-                * limit, empty the chain and ignore the rest.
-                */
-               if ( !si->over ) {
-                       /* check if the entry contains undefined
-                        * attributes/objectClasses (ITS#5680) */
-                       if ( cm->check_cacheability && test_filter( op, rs->sr_entry, si->query.filter ) != LDAP_COMPARE_TRUE ) {
-                               Debug( pcache_debug, "%s: query not cacheable because of schema issues in DN \"%s\"\n",
-                                       op->o_log_prefix, rs->sr_entry->e_name.bv_val, 0 );
-                               goto over;
-                       }
-
-                       /* check for malformed entries: attrs with no values */
-                       {
-                               Attribute *a = rs->sr_entry->e_attrs;
-                               for (; a; a=a->a_next) {
-                                       if ( !a->a_numvals ) {
-                                               Debug( pcache_debug, "%s: query not cacheable because of attrs without values in DN \"%s\" (%s)\n",
-                                               op->o_log_prefix, rs->sr_entry->e_name.bv_val,
-                                               a->a_desc->ad_cname.bv_val );
-                                               goto over;
-                                       }
-                               }
-                       }
-
-                       if ( si->count < si->max ) {
-                               si->count++;
-                               e = entry_dup( rs->sr_entry );
-                               if ( !si->head ) si->head = e;
-                               if ( si->tail ) si->tail->e_private = e;
-                               si->tail = e;
-
-                       } else {
-over:;
-                               si->over = 1;
-                               si->count = 0;
-                               for (;si->head; si->head=e) {
-                                       e = si->head->e_private;
-                                       si->head->e_private = NULL;
-                                       entry_free(si->head);
-                               }
-                               si->tail = NULL;
-                       }
-               }
-
-       }
-
        if ( rs->sr_type == REP_RESULT || 
                op->o_abandon || rs->sr_err == SLAPD_ABANDON )
        {
@@ -2486,11 +2442,64 @@ pcache_response(
        }
 
        if ( rs->sr_type == REP_SEARCH ) {
+               Entry *e;
+
                /* don't return more entries than requested by the client */
+               if ( si->slimit > 0 && rs->sr_nentries >= si->slimit ) {
+                       si->slimit_exceeded = 1;
+               }
+
+               /* If we haven't exceeded the limit for this query,
+                * build a chain of answers to store. If we hit the
+                * limit, empty the chain and ignore the rest.
+                */
+               if ( !si->over ) {
+                       slap_overinst *on = si->on;
+                       cache_manager *cm = on->on_bi.bi_private;
+
+                       /* check if the entry contains undefined
+                        * attributes/objectClasses (ITS#5680) */
+                       if ( cm->check_cacheability && test_filter( op, rs->sr_entry, si->query.filter ) != LDAP_COMPARE_TRUE ) {
+                               Debug( pcache_debug, "%s: query not cacheable because of schema issues in DN \"%s\"\n",
+                                       op->o_log_prefix, rs->sr_entry->e_name.bv_val, 0 );
+                               goto over;
+                       }
+
+                       /* check for malformed entries: attrs with no values */
+                       {
+                               Attribute *a = rs->sr_entry->e_attrs;
+                               for (; a; a=a->a_next) {
+                                       if ( !a->a_numvals ) {
+                                               Debug( pcache_debug, "%s: query not cacheable because of attrs without values in DN \"%s\" (%s)\n",
+                                               op->o_log_prefix, rs->sr_entry->e_name.bv_val,
+                                               a->a_desc->ad_cname.bv_val );
+                                               goto over;
+                                       }
+                               }
+                       }
+
+                       if ( si->count < si->max ) {
+                               si->count++;
+                               e = entry_dup( rs->sr_entry );
+                               if ( !si->head ) si->head = e;
+                               if ( si->tail ) si->tail->e_private = e;
+                               si->tail = e;
+
+                       } else {
+over:;
+                               si->over = 1;
+                               si->count = 0;
+                               for (;si->head; si->head=e) {
+                                       e = si->head->e_private;
+                                       si->head->e_private = NULL;
+                                       entry_free(si->head);
+                               }
+                               si->tail = NULL;
+                       }
+               }
                if ( si->slimit_exceeded ) {
                        return 0;
                }
-
        } else if ( rs->sr_type == REP_RESULT ) {
 
                if ( si->count ) {
@@ -2896,9 +2905,9 @@ pcache_op_bind(
 
        /* OK, just bind locally */
        if ( bi.bi_flags & BI_HASHED ) {
+               int delete = 0;
                BackendDB *be = op->o_bd;
                op->o_bd = &cm->db;
-               int delete = 0;
 
                Debug( pcache_debug, "pcache_op_bind: CACHED BIND for %s\n",
                        op->o_req_dn.bv_val, 0, 0 );
@@ -3409,6 +3418,7 @@ refresh_query( Operation *op, CachedQuery *query, slap_overinst *on )
        op->o_req_dn = query->qbase->base;
        op->o_req_ndn = query->qbase->base;
        op->ors_scope = query->scope;
+       op->ors_deref = LDAP_DEREF_NEVER;
        op->ors_slimit = SLAP_NO_LIMIT;
        op->ors_tlimit = SLAP_NO_LIMIT;
        op->ors_limit = NULL;
@@ -5510,7 +5520,6 @@ pcache_monitor_db_open( BackendDB *be )
        int                     rc = 0;
        BackendInfo             *mi;
        monitor_extra_t         *mbe;
-       struct berval           dummy = BER_BVC( "" );
 
        if ( !SLAP_DBMONITORING( be ) ) {
                return 0;
@@ -5570,7 +5579,7 @@ pcache_monitor_db_open( BackendDB *be )
        rc = mbe->register_overlay( be, on, &cm->monitor_ndn );
        if ( rc == 0 ) {
                rc = mbe->register_entry_attrs( &cm->monitor_ndn, a, cb,
-                       &dummy, -1, &dummy);
+                       NULL, -1, NULL);
        }
 
 cleanup:;