mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-30 13:30:57 +08:00
Optimizations for containment checks
This commit is contained in:
parent
a393b68656
commit
13fdab9509
@ -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);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
if ( position == 3 ) {
|
||||
invert_string(ber1);
|
||||
invert_string(ber2);
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user