mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
Add ability to cache negative results and specify negative TTL on templates
This commit is contained in:
parent
84315e96f8
commit
4361a942ab
@ -69,6 +69,7 @@ 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;
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ 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 * );
|
||||||
|
|
||||||
@ -473,7 +474,7 @@ 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)
|
||||||
@ -526,7 +527,7 @@ query_containment(Operation *op, query_manager *qm,
|
|||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"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) {
|
||||||
@ -590,7 +591,7 @@ query_containment(Operation *op, query_manager *qm,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -599,7 +600,7 @@ query_containment(Operation *op, query_manager *qm,
|
|||||||
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
|
||||||
@ -627,10 +628,15 @@ 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_TRACE, "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;
|
||||||
@ -1018,11 +1024,6 @@ cache_entries(
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@ -1038,6 +1039,12 @@ 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,
|
||||||
@ -1062,15 +1069,20 @@ 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 ) ||
|
||||||
|
( !si->count && templ->negttl )) {
|
||||||
|
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_TRACE, "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
|
||||||
*/
|
*/
|
||||||
@ -1205,7 +1217,7 @@ 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;
|
||||||
@ -1269,9 +1281,15 @@ pcache_op_search(
|
|||||||
Debug( LDAP_DEBUG_TRACE, "QUERY ANSWERABLE\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "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;
|
||||||
@ -1419,7 +1437,10 @@ consistency_check(
|
|||||||
Debug( LDAP_DEBUG_TRACE, "Unlock CR index = %d\n",
|
Debug( LDAP_DEBUG_TRACE, "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);
|
if ( BER_BVISNULL( &query->q_uuid ))
|
||||||
|
return_val = 0;
|
||||||
|
else
|
||||||
|
return_val = remove_query_data(op, &rs, &query->q_uuid);
|
||||||
Debug( LDAP_DEBUG_TRACE, "STALE QUERY REMOVED, SIZE=%d\n",
|
Debug( LDAP_DEBUG_TRACE, "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);
|
||||||
@ -1477,10 +1498,10 @@ 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,
|
||||||
@ -1597,9 +1618,17 @@ 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;
|
||||||
@ -1788,6 +1817,18 @@ 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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user