X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Fpcache.c;h=6971694282bcf848b42882deb94b1a581245157c;hb=c6b5abbfd20567116846ebc38f0005c429284c98;hp=63bb249aebe932789daf407244998cc4d9029412;hpb=aaac401dc87cbc20d181ceedefeecefd308c8976;p=openldap diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c index 63bb249aeb..6971694282 100644 --- a/servers/slapd/overlays/pcache.c +++ b/servers/slapd/overlays/pcache.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * 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:;