Diff for /servers/slapd/overlays/pcache.c between versions 1.41.2.14 and 1.41.2.15

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 );
   

Removed from v.1.41.2.14  
changed lines
  Added in v.1.41.2.15


______________
© Copyright 1998-2020, OpenLDAP Foundation, info@OpenLDAP.org