X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Fpcache.c;h=d27dcb7a0a7e176279f2e84aef65f980d8aec045;hb=2dd578221b3dbaf7ba2308b63c3cc46154323cae;hp=fb5f8eebfc6eb4daca364dd8530da084931144ca;hpb=ea228495148cf585dab9755bd2438e12068eb624;p=openldap diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c index fb5f8eebfc..d27dcb7a0a 100644 --- a/servers/slapd/overlays/pcache.c +++ b/servers/slapd/overlays/pcache.c @@ -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 */ @@ -1251,6 +1260,11 @@ filter_first( Filter *f ) return f; } +typedef struct fstack { + struct fstack *fs_next; + Filter *fs_fs; + Filter *fs_fi; +} fstack; static CachedQuery * find_filter( Operation *op, Avlnode *root, Filter *inputf, Filter *first ) @@ -1262,6 +1276,7 @@ find_filter( Operation *op, Avlnode *root, Filter *inputf, Filter *first ) int ret, rc, dir; Avlnode *ptr; CachedQuery cq, *qc; + fstack *stack = NULL, *fsp; cq.filter = inputf; cq.first = first; @@ -1337,6 +1352,14 @@ 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; res=1; @@ -1386,6 +1409,14 @@ nextpass: eqpass = 1; default: break; } + if (!fs && !fi && stack) { + /* pop the stack */ + fsp = stack; + stack = fsp->fs_next; + fs = fsp->fs_fs; + fi = fsp->fs_fi; + op->o_tmpfree(fsp, op->o_tmpmemctx); + } } while((res) && (fi != NULL) && (fs != NULL)); if ( res ) @@ -2877,9 +2908,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 );