]> git.sur5r.net Git - openldap/commitdiff
Optimizations for containment checks
authorHoward Chu <hyc@openldap.org>
Mon, 9 Jan 2006 19:35:03 +0000 (19:35 +0000)
committerHoward Chu <hyc@openldap.org>
Mon, 9 Jan 2006 19:35:03 +0000 (19:35 +0000)
servers/slapd/overlays/pcache.c

index 2900f254b501d6229476be9c62096ad99be070a1..9998372ad79f56b2fbbea71100f3d954b3cd76a2 100644 (file)
@@ -90,7 +90,7 @@ struct query_manager_s;
 /* prototypes for functions for 1) query containment
  * 2) query addition, 3) cache replacement
  */
-typedef int    (QCfunc)(struct query_manager_s*, Query*, int );
+typedef int    (QCfunc)(Operation *op, struct query_manager_s*, Query*, int );
 typedef void   (AddQueryfunc)(struct query_manager_s*, Query*, int, struct berval*);
 typedef void   (CRfunc)(struct query_manager_s*, struct berval * );
 
@@ -296,69 +296,59 @@ remove_query (query_manager* qm, CachedQuery* qc)
        qc->lru_up = qc->lru_down = NULL;
 }
 
-static void
-invert_string( struct berval *bv )
-{
-       int i;
-       char c;
-
-       for (i=0; i<bv->bv_len/2; i++) {
-               c = bv->bv_val[i];
-               bv->bv_val[i] = bv->bv_val[bv->bv_len-i-1];
-               bv->bv_val[bv->bv_len-i-1] = c;
-       }
-}
-
 /* find and remove string2 from string1
  * from start if position = 1,
  * from end if position = 3,
  * from anywhere if position = 2
+ * string1 is overwritten if position = 2.
  */
 
 static int
 find_and_remove(struct berval* ber1, struct berval* ber2, int position)
 {
-       char* temp;
-       int len;
        int ret=0;
 
-       char* arg1, *arg2;
-       char* string1=ber1->bv_val;
-       char* string2=ber2->bv_val;
-
-       if (string2 == NULL)
+       if ( !ber2->bv_val )
                return 1;
-       if (string1 == NULL)
+       if ( !ber1->bv_val )
                return 0;
 
-       if (position == 3) {
-               invert_string(ber1);
-               invert_string(ber2);
-       }
-
-       arg1 = string1;
-       arg2 = string2;
-
-       temp = strstr(arg1, arg2);
-
-       len = ber2->bv_len;
-
-       if ( temp && (position == 2 || temp == arg1) ) {
-               string1 = temp+len;
-               strcpy( arg1, string1 );
-               ber1->bv_len -= len;
-               ret = 1;
-       }
-       if ( position == 3 ) {
-               invert_string(ber1);
-               invert_string(ber2);
+       switch( position ) {
+       case 1:
+               if ( ber1->bv_len >= ber2->bv_len && !memcmp( ber1->bv_val,
+                       ber2->bv_val, ber2->bv_len )) {
+                       ret = 1;
+                       ber1->bv_val += ber2->bv_len;
+                       ber1->bv_len -= ber2->bv_len;
+               }
+               break;
+       case 2: {
+               char *temp;
+               ber1->bv_val[ber1->bv_len] = '\0';
+               temp = strstr( ber1->bv_val, ber2->bv_val );
+               if ( temp ) {
+                       strcpy( temp, temp+ber2->bv_len );
+                       ber1->bv_len -= ber2->bv_len;
+                       ret = 1;
+               }
+               break;
+               }
+       case 3:
+               if ( ber1->bv_len >= ber2->bv_len &&
+                       !memcmp( ber1->bv_val+ber1->bv_len-ber2->bv_len, ber2->bv_val,
+                               ber2->bv_len )) {
+                       ret = 1;
+                       ber1->bv_len -= ber2->bv_len;
+               }
+               break;
        }
        return ret;
 }
 
 
 static struct berval*
-merge_init_final(struct berval* init, struct berval* any, struct berval* final)
+merge_init_final(Operation *op, struct berval* init, struct berval* any,
+       struct berval* final)
 {
        struct berval* merged, *temp;
        int i, any_count, count;
@@ -373,25 +363,30 @@ merge_init_final(struct berval* init, struct berval* any, struct berval* final)
        if (final->bv_val)
                count++;
 
-       merged = (struct berval*)(ch_malloc((count+1)*sizeof(struct berval)));
+       merged = (struct berval*)op->o_tmpalloc( (count+1)*sizeof(struct berval),
+               op->o_tmpmemctx );
        temp = merged;
 
        if (init->bv_val) {
-               *temp++ = *init;
+               ber_dupbv_x( temp, init, op->o_tmpmemctx );
+               temp++;
        }
 
        for (i=0; i<any_count; i++) {
-               *temp++ = *any++;
+               ber_dupbv_x( temp, any, op->o_tmpmemctx );
+               temp++; any++;
        }
 
        if (final->bv_val){
-               *temp++ = *final;
+               ber_dupbv_x( temp, final, op->o_tmpmemctx );
+               temp++;
        }
-       temp->bv_val = NULL;
-       temp->bv_len = 0;
+       BER_BVZERO( temp );
        return merged;
 }
 
+/* Each element in stored must be found in incoming. Incoming is overwritten.
+ */
 static int
 strings_containment(struct berval* stored, struct berval* incoming)
 {
@@ -418,39 +413,21 @@ strings_containment(struct berval* stored, struct berval* incoming)
 }
 
 static int
-substr_containment_substr(Filter* stored, Filter* incoming)
+substr_containment_substr(Operation *op, Filter* stored, Filter* incoming)
 {
        int i;
        int rc = 0;
-       int any_count = 0;
 
        struct berval init_incoming;
        struct berval final_incoming;
-       struct berval *any_incoming = NULL;
        struct berval *remaining_incoming = NULL;
 
        if ((!(incoming->f_sub_initial.bv_val) && (stored->f_sub_initial.bv_val))
           || (!(incoming->f_sub_final.bv_val) && (stored->f_sub_final.bv_val)))
                return 0;
 
-
-       ber_dupbv(&init_incoming, &(incoming->f_sub_initial));
-       ber_dupbv(&final_incoming, &(incoming->f_sub_final));
-
-       if (incoming->f_sub_any) {
-               for ( any_count=0; incoming->f_sub_any[any_count].bv_val != NULL;
-                               any_count++ )
-                       ;
-
-               any_incoming = (struct berval*)ch_malloc((any_count+1) *
-                                               sizeof(struct berval));
-
-               for (i=0; i<any_count; i++) {
-                       ber_dupbv(&(any_incoming[i]), &(incoming->f_sub_any[i]));
-               }
-               any_incoming[any_count].bv_val = NULL;
-               any_incoming[any_count].bv_len = 0;
-       }
+       init_incoming = incoming->f_sub_initial;
+       final_incoming =  incoming->f_sub_final;
 
        if (find_and_remove(&init_incoming,
                        &(stored->f_sub_initial), 1) && find_and_remove(&final_incoming,
@@ -460,40 +437,36 @@ substr_containment_substr(Filter* stored, Filter* incoming)
                        rc = 1;
                        goto final;
                }
-               remaining_incoming = merge_init_final(&init_incoming,
-                                               any_incoming, &final_incoming);
+               remaining_incoming = merge_init_final(op, &init_incoming,
+                                               incoming->f_sub_any, &final_incoming);
                rc = strings_containment(stored->f_sub_any, remaining_incoming);
+               ber_bvarray_free_x( remaining_incoming, op->o_tmpmemctx );
        }
 final:
-       free(init_incoming.bv_val);
-       free(final_incoming.bv_val);
-       if (any_incoming) ber_bvarray_free( any_incoming );
-       free(remaining_incoming);
-
        return rc;
 }
 
 static int
-substr_containment_equality(Filter* stored, Filter* incoming)
+substr_containment_equality(Operation *op, Filter* stored, Filter* incoming)
 {
        struct berval incoming_val[2];
        int rc = 0;
 
-       ber_dupbv(incoming_val, &(incoming->f_av_value));
-       incoming_val[1].bv_val = NULL;
-       incoming_val[1].bv_len = 0;
+       incoming_val[1] = incoming->f_av_value;
 
-       if (find_and_remove(incoming_val,
-                       &(stored->f_sub_initial), 1) && find_and_remove(incoming_val,
+       if (find_and_remove(incoming_val+1,
+                       &(stored->f_sub_initial), 1) && find_and_remove(incoming_val+1,
                        &(stored->f_sub_final), 3)) {
                if (stored->f_sub_any == NULL){
                        rc = 1;
                        goto final;
                }
+               ber_dupbv_x( incoming_val, incoming_val+1, op->o_tmpmemctx );
+               BER_BVZERO( incoming_val+1 );
                rc = strings_containment(stored->f_sub_any, incoming_val);
+               op->o_tmpfree( incoming_val[0].bv_val, op->o_tmpmemctx );
        }
 final:
-       free(incoming_val[0].bv_val);
        return rc;
 }
 
@@ -501,7 +474,7 @@ final:
  * the cached queries in template template_index
  */
 static int
-query_containment(query_manager *qm,
+query_containment(Operation *op, query_manager *qm,
                  Query *query,
                  int template_index)
 {
@@ -567,13 +540,13 @@ query_containment(query_manager *qm,
                                                /* check if the equality query can be
                                                * answered with cached substring query */
                                                if ((fi->f_choice == LDAP_FILTER_EQUALITY)
-                                                       && substr_containment_equality(
+                                                       && substr_containment_equality( op,
                                                        fs, fi))
                                                        res=1;
                                                /* check if the substring query can be
                                                * answered with cached substring query */
                                                if ((fi->f_choice ==LDAP_FILTER_SUBSTRINGS
-                                                       ) && substr_containment_substr(
+                                                       ) && substr_containment_substr( op,
                                                        fs, fi))
                                                        res= 1;
                                                fs=fs->f_next;
@@ -1276,7 +1249,7 @@ pcache_op_search(
                        template_id = i;
                        Debug( LDAP_DEBUG_NONE, "Entering QC, querystr = %s\n",
                                        op->ors_filterstr.bv_val, 0, 0 );
-                       answerable = (*(qm->qcfunc))(qm, &query, i);
+                       answerable = (*(qm->qcfunc))(op, qm, &query, i);
 
                        if (answerable)
                                break;