version 1.41.2.14, 2006/01/23 23:52:17
|
version 1.41.2.15, 2006/02/17 02:07:35
|
Line 1
|
Line 1
|
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/pcache.c,v 1.41.2.13 2006/01/17 19:09:51 kurt Exp $ */ |
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/pcache.c,v 1.41.2.14 2006/01/23 23:52:17 kurt Exp $ */ |
/* This work is part of OpenLDAP Software <http://www.openldap.org/>. |
/* This work is part of OpenLDAP Software <http://www.openldap.org/>. |
* |
* |
* Copyright 2003-2006 The OpenLDAP Foundation. |
* Copyright 2003-2006 The OpenLDAP Foundation. |
Line 69 typedef struct query_template_s {
|
Line 69 typedef struct query_template_s {
|
|
|
int no_of_queries; /* Total number of queries in the template */ |
int no_of_queries; /* Total number of queries in the template */ |
time_t ttl; /* TTL for the queries of this template */ |
time_t ttl; /* TTL for the queries of this template */ |
|
time_t negttl; /* TTL for negative results */ |
ldap_pvt_thread_rdwr_t t_rwlock; /* Rd/wr lock for accessing queries in the template */ |
ldap_pvt_thread_rdwr_t t_rwlock; /* Rd/wr lock for accessing queries in the template */ |
} QueryTemplate; |
} QueryTemplate; |
|
|
Line 90 struct query_manager_s;
|
Line 91 struct query_manager_s;
|
/* prototypes for functions for 1) query containment |
/* prototypes for functions for 1) query containment |
* 2) query addition, 3) cache replacement |
* 2) query addition, 3) cache replacement |
*/ |
*/ |
typedef int (QCfunc)(Operation *op, struct query_manager_s*, Query*, int ); |
typedef CachedQuery * (QCfunc)(Operation *op, struct query_manager_s*, Query*, int ); |
typedef void (AddQueryfunc)(struct query_manager_s*, Query*, int, struct berval*); |
typedef void (AddQueryfunc)(struct query_manager_s*, Query*, int, struct berval*); |
typedef void (CRfunc)(struct query_manager_s*, struct berval * ); |
typedef void (CRfunc)(struct query_manager_s*, struct berval * ); |
|
|
Line 131 typedef struct cache_manager_s {
|
Line 132 typedef struct cache_manager_s {
|
void *cc_arg; |
void *cc_arg; |
|
|
ldap_pvt_thread_mutex_t cache_mutex; |
ldap_pvt_thread_mutex_t cache_mutex; |
ldap_pvt_thread_mutex_t remove_mutex; |
|
|
|
query_manager* qm; /* query cache managed by the cache manager */ |
query_manager* qm; /* query cache managed by the cache manager */ |
} cache_manager; |
} cache_manager; |
Line 263 add_query_on_top (query_manager* qm, Cac
|
Line 263 add_query_on_top (query_manager* qm, Cac
|
|
|
qc->lru_down = top; |
qc->lru_down = top; |
qc->lru_up = NULL; |
qc->lru_up = NULL; |
Debug( LDAP_DEBUG_TRACE, "Base of added query = %s\n", |
Debug( LDAP_DEBUG_CACHE, "Base of added query = %s\n", |
q->base.bv_val, 0, 0 ); |
q->base.bv_val, 0, 0 ); |
} |
} |
|
|
Line 473 final:
|
Line 473 final:
|
/* check whether query is contained in any of |
/* check whether query is contained in any of |
* the cached queries in template template_index |
* the cached queries in template template_index |
*/ |
*/ |
static int |
static CachedQuery * |
query_containment(Operation *op, query_manager *qm, |
query_containment(Operation *op, query_manager *qm, |
Query *query, |
Query *query, |
int template_index) |
int template_index) |
Line 492 query_containment(Operation *op, query_m
|
Line 492 query_containment(Operation *op, query_m
|
|
|
MatchingRule* mrule = NULL; |
MatchingRule* mrule = NULL; |
if (inputf != NULL) { |
if (inputf != NULL) { |
Debug( LDAP_DEBUG_TRACE, "Lock QC index = %d\n", |
Debug( LDAP_DEBUG_CACHE, "Lock QC index = %d\n", |
template_index, 0, 0 ); |
template_index, 0, 0 ); |
ldap_pvt_thread_rdwr_rlock(&(templa[template_index].t_rwlock)); |
ldap_pvt_thread_rdwr_rlock(&(templa[template_index].t_rwlock)); |
for(qc=templa[template_index].query; qc != NULL; qc= qc->next) { |
for(qc=templa[template_index].query; qc != NULL; qc= qc->next) { |
Line 523 query_containment(Operation *op, query_m
|
Line 523 query_containment(Operation *op, query_m
|
&(fs->f_ava->aa_value), &text); |
&(fs->f_ava->aa_value), &text); |
if (rc != LDAP_SUCCESS) { |
if (rc != LDAP_SUCCESS) { |
ldap_pvt_thread_rdwr_runlock(&(templa[template_index].t_rwlock)); |
ldap_pvt_thread_rdwr_runlock(&(templa[template_index].t_rwlock)); |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_CACHE, |
"Unlock: Exiting QC index=%d\n", |
"Unlock: Exiting QC index=%d\n", |
template_index, 0, 0 ); |
template_index, 0, 0 ); |
return 0; |
return NULL; |
} |
} |
} |
} |
switch (fs->f_choice) { |
switch (fs->f_choice) { |
Line 590 query_containment(Operation *op, query_m
|
Line 590 query_containment(Operation *op, query_m
|
add_query_on_top(qm, qc); |
add_query_on_top(qm, qc); |
} |
} |
ldap_pvt_thread_mutex_unlock(&qm->lru_mutex); |
ldap_pvt_thread_mutex_unlock(&qm->lru_mutex); |
return 1; |
return qc; |
} |
} |
} |
} |
} |
} |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_CACHE, |
"Not answerable: Unlock QC index=%d\n", |
"Not answerable: Unlock QC index=%d\n", |
template_index, 0, 0 ); |
template_index, 0, 0 ); |
ldap_pvt_thread_rdwr_runlock(&(templa[template_index].t_rwlock)); |
ldap_pvt_thread_rdwr_runlock(&(templa[template_index].t_rwlock)); |
} |
} |
return 0; |
return NULL; |
} |
} |
|
|
static void |
static void |
Line 627 static void add_query(
|
Line 627 static void add_query(
|
QueryTemplate* templ = (qm->templates)+template_index; |
QueryTemplate* templ = (qm->templates)+template_index; |
Query* new_query; |
Query* new_query; |
new_cached_query->template_id = template_index; |
new_cached_query->template_id = template_index; |
new_cached_query->q_uuid = *uuid; |
if ( uuid ) { |
|
new_cached_query->q_uuid = *uuid; |
|
new_cached_query->expiry_time = slap_get_time() + templ->ttl; |
|
} else { |
|
BER_BVZERO( &new_cached_query->q_uuid ); |
|
new_cached_query->expiry_time = slap_get_time() + templ->negttl; |
|
} |
new_cached_query->lru_up = NULL; |
new_cached_query->lru_up = NULL; |
new_cached_query->lru_down = NULL; |
new_cached_query->lru_down = NULL; |
new_cached_query->expiry_time = slap_get_time() + templ->ttl; |
Debug( LDAP_DEBUG_CACHE, "Added query expires at %ld\n", |
Debug( LDAP_DEBUG_TRACE, "Added query expires at %ld\n", |
|
(long) new_cached_query->expiry_time, 0, 0 ); |
(long) new_cached_query->expiry_time, 0, 0 ); |
new_query = (Query*)new_cached_query; |
new_query = (Query*)new_cached_query; |
|
|
Line 641 static void add_query(
|
Line 646 static void add_query(
|
new_query->attrs = query->attrs; |
new_query->attrs = query->attrs; |
|
|
/* Adding a query */ |
/* Adding a query */ |
Debug( LDAP_DEBUG_TRACE, "Lock AQ index = %d\n", |
Debug( LDAP_DEBUG_CACHE, "Lock AQ index = %d\n", |
template_index, 0, 0 ); |
template_index, 0, 0 ); |
ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock); |
ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock); |
if (templ->query == NULL) |
if (templ->query == NULL) |
Line 652 static void add_query(
|
Line 657 static void add_query(
|
new_cached_query->prev = NULL; |
new_cached_query->prev = NULL; |
templ->query = new_cached_query; |
templ->query = new_cached_query; |
templ->no_of_queries++; |
templ->no_of_queries++; |
Debug( LDAP_DEBUG_TRACE, "TEMPLATE %d QUERIES++ %d\n", |
Debug( LDAP_DEBUG_CACHE, "TEMPLATE %d QUERIES++ %d\n", |
template_index, templ->no_of_queries, 0 ); |
template_index, templ->no_of_queries, 0 ); |
|
|
Debug( LDAP_DEBUG_TRACE, "Unlock AQ index = %d \n", |
Debug( LDAP_DEBUG_CACHE, "Unlock AQ index = %d \n", |
template_index, 0, 0 ); |
template_index, 0, 0 ); |
ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock); |
ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock); |
|
|
Line 697 static void cache_replacement(query_mana
|
Line 702 static void cache_replacement(query_mana
|
result->bv_len = 0; |
result->bv_len = 0; |
|
|
if (!bottom) { |
if (!bottom) { |
Debug ( LDAP_DEBUG_TRACE, |
Debug ( LDAP_DEBUG_CACHE, |
"Cache replacement invoked without " |
"Cache replacement invoked without " |
"any query in LRU list\n", 0, 0, 0 ); |
"any query in LRU list\n", 0, 0, 0 ); |
ldap_pvt_thread_mutex_unlock(&qm->lru_mutex); |
ldap_pvt_thread_mutex_unlock(&qm->lru_mutex); |
Line 711 static void cache_replacement(query_mana
|
Line 716 static void cache_replacement(query_mana
|
*result = bottom->q_uuid; |
*result = bottom->q_uuid; |
bottom->q_uuid.bv_val = NULL; |
bottom->q_uuid.bv_val = NULL; |
|
|
Debug( LDAP_DEBUG_TRACE, "Lock CR index = %d\n", temp_id, 0, 0 ); |
Debug( LDAP_DEBUG_CACHE, "Lock CR index = %d\n", temp_id, 0, 0 ); |
ldap_pvt_thread_rdwr_wlock(&(qm->templates[temp_id].t_rwlock)); |
ldap_pvt_thread_rdwr_wlock(&(qm->templates[temp_id].t_rwlock)); |
remove_from_template(bottom, (qm->templates+temp_id)); |
remove_from_template(bottom, (qm->templates+temp_id)); |
Debug( LDAP_DEBUG_TRACE, "TEMPLATE %d QUERIES-- %d\n", |
Debug( LDAP_DEBUG_CACHE, "TEMPLATE %d QUERIES-- %d\n", |
temp_id, qm->templates[temp_id].no_of_queries, 0 ); |
temp_id, qm->templates[temp_id].no_of_queries, 0 ); |
Debug( LDAP_DEBUG_TRACE, "Unlock CR index = %d\n", temp_id, 0, 0 ); |
Debug( LDAP_DEBUG_CACHE, "Unlock CR index = %d\n", temp_id, 0, 0 ); |
ldap_pvt_thread_rdwr_wunlock(&(qm->templates[temp_id].t_rwlock)); |
ldap_pvt_thread_rdwr_wunlock(&(qm->templates[temp_id].t_rwlock)); |
free_query(bottom); |
free_query(bottom); |
} |
} |
Line 809 remove_query_data (
|
Line 814 remove_query_data (
|
op->o_req_ndn = qi->xdn; |
op->o_req_ndn = qi->xdn; |
|
|
if ( qi->del) { |
if ( qi->del) { |
Debug( LDAP_DEBUG_TRACE, "DELETING ENTRY TEMPLATE=%s\n", |
Debug( LDAP_DEBUG_CACHE, "DELETING ENTRY TEMPLATE=%s\n", |
query_uuid->bv_val, 0, 0 ); |
query_uuid->bv_val, 0, 0 ); |
|
|
op->o_tag = LDAP_REQ_DELETE; |
op->o_tag = LDAP_REQ_DELETE; |
Line 831 remove_query_data (
|
Line 836 remove_query_data (
|
mod.sml_values = vals; |
mod.sml_values = vals; |
mod.sml_nvalues = NULL; |
mod.sml_nvalues = NULL; |
mod.sml_next = NULL; |
mod.sml_next = NULL; |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_CACHE, |
"REMOVING TEMP ATTR : TEMPLATE=%s\n", |
"REMOVING TEMP ATTR : TEMPLATE=%s\n", |
query_uuid->bv_val, 0, 0 ); |
query_uuid->bv_val, 0, 0 ); |
|
|
Line 973 cache_entries(
|
Line 978 cache_entries(
|
op_tmp.o_dn = cm->db.be_rootdn; |
op_tmp.o_dn = cm->db.be_rootdn; |
op_tmp.o_ndn = cm->db.be_rootndn; |
op_tmp.o_ndn = cm->db.be_rootndn; |
|
|
Debug( LDAP_DEBUG_TRACE, "UUID for query being added = %s\n", |
Debug( LDAP_DEBUG_CACHE, "UUID for query being added = %s\n", |
uuidbuf, 0, 0 ); |
uuidbuf, 0, 0 ); |
|
|
for ( e=si->head; e; e=si->head ) { |
for ( e=si->head; e; e=si->head ) { |
si->head = e->e_private; |
si->head = e->e_private; |
e->e_private = NULL; |
e->e_private = NULL; |
Debug( LDAP_DEBUG_NONE, "LOCKING REMOVE MUTEX\n", 0, 0, 0 ); |
|
ldap_pvt_thread_mutex_lock(&cm->remove_mutex); |
|
Debug( LDAP_DEBUG_NONE, "LOCKED REMOVE MUTEX\n", 0, 0, 0); |
|
while ( cm->cur_entries > (cm->max_entries) ) { |
while ( cm->cur_entries > (cm->max_entries) ) { |
qm->crfunc(qm, &crp_uuid); |
qm->crfunc(qm, &crp_uuid); |
if (crp_uuid.bv_val) { |
if (crp_uuid.bv_val) { |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_CACHE, |
"Removing query UUID %s\n", |
"Removing query UUID %s\n", |
crp_uuid.bv_val, 0, 0 ); |
crp_uuid.bv_val, 0, 0 ); |
return_val = remove_query_data(&op_tmp, rs, &crp_uuid); |
return_val = remove_query_data(&op_tmp, rs, &crp_uuid); |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_CACHE, |
"QUERY REMOVED, SIZE=%d\n", |
"QUERY REMOVED, SIZE=%d\n", |
return_val, 0, 0); |
return_val, 0, 0); |
ldap_pvt_thread_mutex_lock( |
ldap_pvt_thread_mutex_lock( |
&cm->cache_mutex ); |
&cm->cache_mutex ); |
cm->cur_entries -= return_val; |
cm->cur_entries -= return_val; |
cm->num_cached_queries--; |
cm->num_cached_queries--; |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_CACHE, |
"STORED QUERIES = %lu\n", |
"STORED QUERIES = %lu\n", |
cm->num_cached_queries, 0, 0 ); |
cm->num_cached_queries, 0, 0 ); |
ldap_pvt_thread_mutex_unlock( |
ldap_pvt_thread_mutex_unlock( |
&cm->cache_mutex ); |
&cm->cache_mutex ); |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_CACHE, |
"QUERY REMOVED, CACHE =" |
"QUERY REMOVED, CACHE =" |
"%d entries\n", |
"%d entries\n", |
cm->cur_entries, 0, 0 ); |
cm->cur_entries, 0, 0 ); |
Line 1009 cache_entries(
|
Line 1011 cache_entries(
|
} |
} |
|
|
return_val = merge_entry(&op_tmp, e, query_uuid); |
return_val = merge_entry(&op_tmp, e, query_uuid); |
ldap_pvt_thread_mutex_unlock(&cm->remove_mutex); |
|
ldap_pvt_thread_mutex_lock(&cm->cache_mutex); |
ldap_pvt_thread_mutex_lock(&cm->cache_mutex); |
cm->cur_entries += return_val; |
cm->cur_entries += return_val; |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_CACHE, |
"ENTRY ADDED/MERGED, CACHED ENTRIES=%d\n", |
"ENTRY ADDED/MERGED, CACHED ENTRIES=%d\n", |
cm->cur_entries, 0, 0 ); |
cm->cur_entries, 0, 0 ); |
return_val = 0; |
return_val = 0; |
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); |
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); |
} |
} |
ldap_pvt_thread_mutex_lock(&cm->cache_mutex); |
|
cm->num_cached_queries++; |
|
Debug( LDAP_DEBUG_TRACE, "STORED QUERIES = %lu\n", |
|
cm->num_cached_queries, 0, 0 ); |
|
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); |
|
|
|
return return_val; |
return return_val; |
} |
} |
Line 1038 pcache_response(
|
Line 1034 pcache_response(
|
query_manager* qm = cm->qm; |
query_manager* qm = cm->qm; |
struct berval uuid; |
struct berval uuid; |
|
|
|
if ( si->query.save_attrs != NULL ) { |
|
rs->sr_attrs = si->query.save_attrs; |
|
op->ors_attrs = si->query.save_attrs; |
|
si->query.save_attrs = NULL; |
|
} |
|
|
if ( rs->sr_type == REP_SEARCH ) { |
if ( rs->sr_type == REP_SEARCH ) { |
Entry *e; |
Entry *e; |
/* If we haven't exceeded the limit for this query, |
/* If we haven't exceeded the limit for this query, |
Line 1062 pcache_response(
|
Line 1064 pcache_response(
|
si->tail = NULL; |
si->tail = NULL; |
} |
} |
} |
} |
if ( si->query.save_attrs != NULL ) { |
|
rs->sr_attrs = si->query.save_attrs; |
|
op->ors_attrs = si->query.save_attrs; |
|
si->query.save_attrs = NULL; |
|
} |
|
|
|
} else if ( rs->sr_type == REP_RESULT ) { |
} else if ( rs->sr_type == REP_RESULT ) { |
if ( si->count && cache_entries( op, rs, &uuid ) == 0 ) { |
QueryTemplate* templ = (qm->templates)+si->template_id; |
qm->addfunc(qm, &si->query, si->template_id, &uuid); |
if (( si->count && cache_entries( op, rs, &uuid ) == 0 ) || |
|
( templ->negttl && !si->count && !si->over && |
|
rs->sr_err == LDAP_SUCCESS )) { |
|
qm->addfunc(qm, &si->query, si->template_id, |
|
si->count ? &uuid : NULL); |
|
|
|
ldap_pvt_thread_mutex_lock(&cm->cache_mutex); |
|
cm->num_cached_queries++; |
|
Debug( LDAP_DEBUG_CACHE, "STORED QUERIES = %lu\n", |
|
cm->num_cached_queries, 0, 0 ); |
|
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); |
|
|
/* If the consistency checker suspended itself, |
/* If the consistency checker suspended itself, |
* wake it back up |
* wake it back up |
*/ |
*/ |
Line 1170 pcache_chk_controls(
|
Line 1178 pcache_chk_controls(
|
/* fallthru */ |
/* fallthru */ |
|
|
case SLAP_CONTROL_CRITICAL: |
case SLAP_CONTROL_CRITICAL: |
Debug( LDAP_DEBUG_TRACE, "%s: " |
Debug( LDAP_DEBUG_CACHE, "%s: " |
"%scritical pagedResults control " |
"%scritical pagedResults control " |
"disabled with proxy cache%s.\n", |
"disabled with proxy cache%s.\n", |
op->o_log_prefix, non, stripped ); |
op->o_log_prefix, non, stripped ); |
Line 1205 pcache_op_search(
|
Line 1213 pcache_op_search(
|
|
|
int attr_set = -1; |
int attr_set = -1; |
int template_id = -1; |
int template_id = -1; |
int answerable = 0; |
CachedQuery *answerable = NULL; |
int cacheable = 0; |
int cacheable = 0; |
int fattr_cnt=0; |
int fattr_cnt=0; |
int fattr_got_oc = 0; |
int fattr_got_oc = 0; |
Line 1221 pcache_op_search(
|
Line 1229 pcache_op_search(
|
return SLAP_CB_CONTINUE; |
return SLAP_CB_CONTINUE; |
} |
} |
|
|
Debug( LDAP_DEBUG_TRACE, "query template of incoming query = %s\n", |
Debug( LDAP_DEBUG_CACHE, "query template of incoming query = %s\n", |
tempstr.bv_val, 0, 0 ); |
tempstr.bv_val, 0, 0 ); |
|
|
/* FIXME: cannot cache/answer requests with pagedResults control */ |
/* FIXME: cannot cache/answer requests with pagedResults control */ |
Line 1266 pcache_op_search(
|
Line 1274 pcache_op_search(
|
BackendDB *save_bd = op->o_bd; |
BackendDB *save_bd = op->o_bd; |
slap_callback *save_cb = op->o_callback; |
slap_callback *save_cb = op->o_callback; |
|
|
Debug( LDAP_DEBUG_TRACE, "QUERY ANSWERABLE\n", 0, 0, 0 ); |
Debug( LDAP_DEBUG_CACHE, "QUERY ANSWERABLE\n", 0, 0, 0 ); |
op->o_tmpfree( filter_attrs, op->o_tmpmemctx ); |
op->o_tmpfree( filter_attrs, op->o_tmpmemctx ); |
ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock); |
ldap_pvt_thread_rdwr_runlock(&qm->templates[i].t_rwlock); |
op->o_bd = &cm->db; |
if ( BER_BVISNULL( &answerable->q_uuid )) { |
op->o_callback = NULL; |
/* No entries cached, just an empty result set */ |
i = cm->db.bd_info->bi_op_search( op, rs ); |
i = rs->sr_err = 0; |
|
send_ldap_result( op, rs ); |
|
} else { |
|
op->o_bd = &cm->db; |
|
op->o_callback = NULL; |
|
i = cm->db.bd_info->bi_op_search( op, rs ); |
|
} |
op->o_bd = save_bd; |
op->o_bd = save_bd; |
op->o_callback = save_cb; |
op->o_callback = save_cb; |
return i; |
return i; |
} |
} |
|
|
Debug( LDAP_DEBUG_TRACE, "QUERY NOT ANSWERABLE\n", 0, 0, 0 ); |
Debug( LDAP_DEBUG_CACHE, "QUERY NOT ANSWERABLE\n", 0, 0, 0 ); |
|
|
ldap_pvt_thread_mutex_lock(&cm->cache_mutex); |
ldap_pvt_thread_mutex_lock(&cm->cache_mutex); |
if (cm->num_cached_queries >= cm->max_queries) { |
if (cm->num_cached_queries >= cm->max_queries) { |
Line 1285 pcache_op_search(
|
Line 1299 pcache_op_search(
|
} |
} |
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); |
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); |
|
|
|
if (op->ors_attrsonly) |
|
cacheable = 0; |
|
|
if (cacheable) { |
if (cacheable) { |
slap_callback *cb; |
slap_callback *cb; |
struct search_info *si; |
struct search_info *si; |
|
|
Debug( LDAP_DEBUG_TRACE, "QUERY CACHEABLE\n", 0, 0, 0 ); |
Debug( LDAP_DEBUG_CACHE, "QUERY CACHEABLE\n", 0, 0, 0 ); |
query.filter = filter_dup(op->ors_filter, NULL); |
query.filter = filter_dup(op->ors_filter, NULL); |
add_filter_attrs(op, &query.attrs, &qm->attr_sets[attr_set], |
add_filter_attrs(op, &query.attrs, &qm->attr_sets[attr_set], |
filter_attrs, fattr_cnt, fattr_got_oc); |
filter_attrs, fattr_cnt, fattr_got_oc); |
Line 1326 pcache_op_search(
|
Line 1343 pcache_op_search(
|
} |
} |
|
|
} else { |
} else { |
Debug( LDAP_DEBUG_TRACE, "QUERY NOT CACHEABLE\n", |
Debug( LDAP_DEBUG_CACHE, "QUERY NOT CACHEABLE\n", |
0, 0, 0); |
0, 0, 0); |
} |
} |
|
|
Line 1405 consistency_check(
|
Line 1422 consistency_check(
|
query = templ->query_last; |
query = templ->query_last; |
if ( query ) pause = 0; |
if ( query ) pause = 0; |
op->o_time = slap_get_time(); |
op->o_time = slap_get_time(); |
ldap_pvt_thread_mutex_lock(&cm->remove_mutex); |
|
while (query && (query->expiry_time < op->o_time)) { |
while (query && (query->expiry_time < op->o_time)) { |
ldap_pvt_thread_mutex_lock(&qm->lru_mutex); |
Debug( LDAP_DEBUG_CACHE, "Lock CR index = %d\n", |
remove_query(qm, query); |
|
ldap_pvt_thread_mutex_unlock(&qm->lru_mutex); |
|
Debug( LDAP_DEBUG_TRACE, "Lock CR index = %d\n", |
|
i, 0, 0 ); |
i, 0, 0 ); |
ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock); |
ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock); |
remove_from_template(query, templ); |
remove_from_template(query, templ); |
Debug( LDAP_DEBUG_TRACE, "TEMPLATE %d QUERIES-- %d\n", |
Debug( LDAP_DEBUG_CACHE, "TEMPLATE %d QUERIES-- %d\n", |
i, templ->no_of_queries, 0 ); |
i, templ->no_of_queries, 0 ); |
Debug( LDAP_DEBUG_TRACE, "Unlock CR index = %d\n", |
Debug( LDAP_DEBUG_CACHE, "Unlock CR index = %d\n", |
i, 0, 0 ); |
i, 0, 0 ); |
ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock); |
ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock); |
return_val = remove_query_data(op, &rs, &query->q_uuid); |
ldap_pvt_thread_mutex_lock(&qm->lru_mutex); |
Debug( LDAP_DEBUG_TRACE, "STALE QUERY REMOVED, SIZE=%d\n", |
remove_query(qm, query); |
|
ldap_pvt_thread_mutex_unlock(&qm->lru_mutex); |
|
if ( BER_BVISNULL( &query->q_uuid )) |
|
return_val = 0; |
|
else |
|
return_val = remove_query_data(op, &rs, &query->q_uuid); |
|
Debug( LDAP_DEBUG_CACHE, "STALE QUERY REMOVED, SIZE=%d\n", |
return_val, 0, 0 ); |
return_val, 0, 0 ); |
ldap_pvt_thread_mutex_lock(&cm->cache_mutex); |
ldap_pvt_thread_mutex_lock(&cm->cache_mutex); |
cm->cur_entries -= return_val; |
cm->cur_entries -= return_val; |
cm->num_cached_queries--; |
cm->num_cached_queries--; |
Debug( LDAP_DEBUG_TRACE, "STORED QUERIES = %lu\n", |
Debug( LDAP_DEBUG_CACHE, "STORED QUERIES = %lu\n", |
cm->num_cached_queries, 0, 0 ); |
cm->num_cached_queries, 0, 0 ); |
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); |
ldap_pvt_thread_mutex_unlock(&cm->cache_mutex); |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_CACHE, |
"STALE QUERY REMOVED, CACHE =" |
"STALE QUERY REMOVED, CACHE =" |
"%d entries\n", |
"%d entries\n", |
cm->cur_entries, 0, 0 ); |
cm->cur_entries, 0, 0 ); |
Line 1436 consistency_check(
|
Line 1455 consistency_check(
|
query = query->prev; |
query = query->prev; |
free_query(query_prev); |
free_query(query_prev); |
} |
} |
ldap_pvt_thread_mutex_unlock(&cm->remove_mutex); |
|
} |
} |
ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); |
ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); |
if ( ldap_pvt_runqueue_isrunning( &slapd_rq, rtask )) { |
if ( ldap_pvt_runqueue_isrunning( &slapd_rq, rtask )) { |
Line 1457 enum {
|
Line 1475 enum {
|
PC_MAIN = 1, |
PC_MAIN = 1, |
PC_ATTR, |
PC_ATTR, |
PC_TEMP, |
PC_TEMP, |
PC_RESP |
PC_RESP, |
|
PC_QUERIES |
}; |
}; |
|
|
static ConfigDriver pc_cf_gen; |
static ConfigDriver pc_cf_gen; |
Line 1476 static ConfigTable pccfg[] = {
|
Line 1495 static ConfigTable pccfg[] = {
|
"( OLcfgOvAt:2.2 NAME 'olcProxyAttrset' " |
"( OLcfgOvAt:2.2 NAME 'olcProxyAttrset' " |
"DESC 'A set of attributes to cache' " |
"DESC 'A set of attributes to cache' " |
"SYNTAX OMsDirectoryString )", NULL, NULL }, |
"SYNTAX OMsDirectoryString )", NULL, NULL }, |
{ "proxytemplate", "filter> <attrset-index> <TTL", |
{ "proxytemplate", "filter> <attrset-index> <TTL> <negTTL", |
4, 4, 0, ARG_MAGIC|PC_TEMP, pc_cf_gen, |
4, 5, 0, ARG_MAGIC|PC_TEMP, pc_cf_gen, |
"( OLcfgOvAt:2.3 NAME 'olcProxyTemplate' " |
"( OLcfgOvAt:2.3 NAME 'olcProxyTemplate' " |
"DESC 'Filter template, attrset, and cache TTL' " |
"DESC 'Filter template, attrset, cache TTL, optional negative TTL' " |
"SYNTAX OMsDirectoryString )", NULL, NULL }, |
"SYNTAX OMsDirectoryString )", NULL, NULL }, |
{ "response-callback", "head|tail(default)", |
{ "response-callback", "head|tail(default)", |
2, 2, 0, ARG_MAGIC|PC_RESP, pc_cf_gen, |
2, 2, 0, ARG_MAGIC|PC_RESP, pc_cf_gen, |
"( OLcfgOvAt:2.4 NAME 'olcProxyResponseCB' " |
"( OLcfgOvAt:2.4 NAME 'olcProxyResponseCB' " |
"DESC 'Response callback position in overlay stack' " |
"DESC 'Response callback position in overlay stack' " |
"SYNTAX OMsDirectoryString )", NULL, NULL }, |
"SYNTAX OMsDirectoryString )", NULL, NULL }, |
|
{ "proxyCacheQueries", "queries", |
|
2, 2, 0, ARG_INT|ARG_MAGIC|PC_QUERIES, pc_cf_gen, |
|
"( OLcfgOvAt:2.5 NAME 'olcProxyCacheQueries' " |
|
"DESC 'Maximum number of queries to cache' " |
|
"SYNTAX OMsInteger )", NULL, NULL }, |
|
|
{ NULL, NULL, 0, 0, 0, ARG_IGNORED } |
{ NULL, NULL, 0, 0, 0, ARG_IGNORED } |
}; |
}; |
|
|
Line 1495 static ConfigOCs pcocs[] = {
|
Line 1520 static ConfigOCs pcocs[] = {
|
"DESC 'ProxyCache configuration' " |
"DESC 'ProxyCache configuration' " |
"SUP olcOverlayConfig " |
"SUP olcOverlayConfig " |
"MUST ( olcProxyCache $ olcProxyAttrset $ olcProxyTemplate ) " |
"MUST ( olcProxyCache $ olcProxyAttrset $ olcProxyTemplate ) " |
"MAY olcProxyResponseCB )", Cft_Overlay, pccfg, NULL, pc_cfadd }, |
"MAY ( olcProxyResponseCB $ olcProxyCacheQueries ) )", Cft_Overlay, pccfg, NULL, pc_cfadd }, |
{ "( OLcfgOvOc:2.2 " |
{ "( OLcfgOvOc:2.2 " |
"NAME 'olcPcacheDatabase' " |
"NAME 'olcPcacheDatabase' " |
"DESC 'Cache database configuration' " |
"DESC 'Cache database configuration' " |
Line 1590 pc_cf_gen( ConfigArgs *c )
|
Line 1615 pc_cf_gen( ConfigArgs *c )
|
break; |
break; |
case PC_TEMP: |
case PC_TEMP: |
for (i=0; i<cm->numtemplates; i++) { |
for (i=0; i<cm->numtemplates; i++) { |
bv.bv_len = snprintf( c->msg, sizeof( c->msg ), " %d %ld", |
if ( qm->templates[i].negttl ) { |
qm->templates[i].attr_set_index, |
bv.bv_len = snprintf( c->msg, sizeof( c->msg ), |
qm->templates[i].ttl ); |
" %d %ld %ld", |
|
qm->templates[i].attr_set_index, |
|
qm->templates[i].ttl, |
|
qm->templates[i].negttl ); |
|
} else { |
|
bv.bv_len = snprintf( c->msg, sizeof( c->msg ), " %d %ld", |
|
qm->templates[i].attr_set_index, |
|
qm->templates[i].ttl ); |
|
} |
bv.bv_len += qm->templates[i].querystr.bv_len + 2; |
bv.bv_len += qm->templates[i].querystr.bv_len + 2; |
bv.bv_val = ch_malloc( bv.bv_len+1 ); |
bv.bv_val = ch_malloc( bv.bv_len+1 ); |
ptr = bv.bv_val; |
ptr = bv.bv_val; |
Line 1613 pc_cf_gen( ConfigArgs *c )
|
Line 1646 pc_cf_gen( ConfigArgs *c )
|
} |
} |
value_add_one( &c->rvalue_vals, &bv ); |
value_add_one( &c->rvalue_vals, &bv ); |
break; |
break; |
|
case PC_QUERIES: |
|
c->value_int = cm->max_queries; |
|
break; |
} |
} |
return rc; |
return rc; |
} else if ( c->op == LDAP_MOD_DELETE ) { |
} else if ( c->op == LDAP_MOD_DELETE ) { |
Line 1693 pc_cf_gen( ConfigArgs *c )
|
Line 1729 pc_cf_gen( ConfigArgs *c )
|
return( 1 ); |
return( 1 ); |
} |
} |
cm->cc_period = (time_t)t; |
cm->cc_period = (time_t)t; |
Debug( LDAP_DEBUG_TRACE, |
Debug( LDAP_DEBUG_CACHE, |
"Total # of attribute sets to be cached = %d.\n", |
"Total # of attribute sets to be cached = %d.\n", |
cm->numattrsets, 0, 0 ); |
cm->numattrsets, 0, 0 ); |
qm->attr_sets = ( struct attr_set * )ch_calloc( cm->numattrsets, |
qm->attr_sets = ( struct attr_set * )ch_calloc( cm->numattrsets, |
Line 1778 pc_cf_gen( ConfigArgs *c )
|
Line 1814 pc_cf_gen( ConfigArgs *c )
|
return( 1 ); |
return( 1 ); |
} |
} |
temp->ttl = (time_t)t; |
temp->ttl = (time_t)t; |
|
if ( c->argc == 5 ) { |
|
if ( lutil_parse_time( c->argv[4], &t ) != 0 ) { |
|
snprintf( c->msg, sizeof( c->msg ), |
|
"unable to parse template negttl=\"%s\"", |
|
c->argv[4] ); |
|
Debug( LDAP_DEBUG_CONFIG, "%s: %s.\n", c->log, c->msg, 0 ); |
|
return( 1 ); |
|
} |
|
temp->negttl = (time_t)t; |
|
} else { |
|
temp->negttl = 0; |
|
} |
|
|
temp->no_of_queries = 0; |
temp->no_of_queries = 0; |
|
|
ber_str2bv( c->argv[1], 0, 1, &temp->querystr ); |
ber_str2bv( c->argv[1], 0, 1, &temp->querystr ); |
Debug( LDAP_DEBUG_TRACE, "Template:\n", 0, 0, 0 ); |
Debug( LDAP_DEBUG_CACHE, "Template:\n", 0, 0, 0 ); |
Debug( LDAP_DEBUG_TRACE, " query template: %s\n", |
Debug( LDAP_DEBUG_CACHE, " query template: %s\n", |
temp->querystr.bv_val, 0, 0 ); |
temp->querystr.bv_val, 0, 0 ); |
temp->attr_set_index = i; |
temp->attr_set_index = i; |
qm->attr_sets[i].flags |= PC_REFERENCED; |
qm->attr_sets[i].flags |= PC_REFERENCED; |
Debug( LDAP_DEBUG_TRACE, " attributes: \n", 0, 0, 0 ); |
Debug( LDAP_DEBUG_CACHE, " attributes: \n", 0, 0, 0 ); |
if ( ( attrarray = qm->attr_sets[i].attrs ) != NULL ) { |
if ( ( attrarray = qm->attr_sets[i].attrs ) != NULL ) { |
for ( i=0; attrarray[i].an_name.bv_val; i++ ) |
for ( i=0; attrarray[i].an_name.bv_val; i++ ) |
Debug( LDAP_DEBUG_TRACE, "\t%s\n", |
Debug( LDAP_DEBUG_CACHE, "\t%s\n", |
attrarray[i].an_name.bv_val, 0, 0 ); |
attrarray[i].an_name.bv_val, 0, 0 ); |
} |
} |
temp++; |
temp++; |
Line 1810 pc_cf_gen( ConfigArgs *c )
|
Line 1858 pc_cf_gen( ConfigArgs *c )
|
return 1; |
return 1; |
} |
} |
break; |
break; |
|
case PC_QUERIES: |
|
if ( c->value_int <= 0 ) { |
|
snprintf( c->msg, sizeof( c->msg ), "max queries must be positive" ); |
|
Debug( LDAP_DEBUG_CONFIG, "%s: %s.\n", c->log, c->msg, 0 ); |
|
return( 1 ); |
|
} |
|
cm->max_queries = c->value_int; |
|
break; |
} |
} |
return rc; |
return rc; |
} |
} |
Line 1874 pcache_db_init(
|
Line 1930 pcache_db_init(
|
ldap_pvt_thread_mutex_init(&qm->lru_mutex); |
ldap_pvt_thread_mutex_init(&qm->lru_mutex); |
|
|
ldap_pvt_thread_mutex_init(&cm->cache_mutex); |
ldap_pvt_thread_mutex_init(&cm->cache_mutex); |
ldap_pvt_thread_mutex_init(&cm->remove_mutex); |
|
return 0; |
return 0; |
} |
} |
|
|
Line 2010 pcache_db_destroy(
|
Line 2065 pcache_db_destroy(
|
|
|
ldap_pvt_thread_mutex_destroy( &qm->lru_mutex ); |
ldap_pvt_thread_mutex_destroy( &qm->lru_mutex ); |
ldap_pvt_thread_mutex_destroy( &cm->cache_mutex ); |
ldap_pvt_thread_mutex_destroy( &cm->cache_mutex ); |
ldap_pvt_thread_mutex_destroy( &cm->remove_mutex ); |
|
free( qm ); |
free( qm ); |
free( cm ); |
free( cm ); |
|
|