⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcache.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 4 页
字号:
					case LDAP_FILTER_OR:					case LDAP_FILTER_AND:						fs = fs->f_and;						fi = fi->f_and;						res=1;						break;					case LDAP_FILTER_SUBSTRINGS:						/* check if the equality query can be						* answered with cached substring query */						if ((fi->f_choice == LDAP_FILTER_EQUALITY)							&& substr_containment_equality( op,							fs, fi))							res=1;						/* check if the substring query can be						* answered with cached substring query */						if ((fi->f_choice ==LDAP_FILTER_SUBSTRINGS							) && substr_containment_substr( op,							fs, fi))							res= 1;						fs=fs->f_next;						fi=fi->f_next;						break;					case LDAP_FILTER_PRESENT:						res=1;						fs=fs->f_next;						fi=fi->f_next;						break;					case LDAP_FILTER_EQUALITY:						if (ret == 0)							res = 1;						fs=fs->f_next;						fi=fi->f_next;						break;					case LDAP_FILTER_GE:						if (ret >= 0)							res = 1;						fs=fs->f_next;						fi=fi->f_next;						break;					case LDAP_FILTER_LE:						if (ret <= 0)							res = 1;						fs=fs->f_next;						fi=fi->f_next;						break;					case LDAP_FILTER_NOT:						res=0;						break;					default:						break;					}				} while((res) && (fi != NULL) && (fs != NULL));				if(res) {					ldap_pvt_thread_mutex_lock(&qm->lru_mutex);					if (qm->lru_top != qc) {						remove_query(qm, qc);						add_query_on_top(qm, qc);					}					ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);					return qc;				}			}		}		Debug( pcache_debug,			"Not answerable: Unlock QC index=%d\n",			template_index, 0, 0 );		ldap_pvt_thread_rdwr_runlock(&(templa[template_index].t_rwlock));	}	return NULL;}static voidfree_query (CachedQuery* qc){	Query* q = (Query*)qc;	int i;	free(qc->q_uuid.bv_val);	filter_free(q->filter);	free (q->base.bv_val);	free(q->attrs);	free(qc);}/* Add query to query cache */static void add_query(	query_manager* qm,	Query* query,	int template_index,	struct berval* uuid){	CachedQuery* new_cached_query = (CachedQuery*) ch_malloc(sizeof(CachedQuery));	QueryTemplate* templ = (qm->templates)+template_index;	Query* new_query;	new_cached_query->template_id = template_index;	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_down = NULL;	Debug( pcache_debug, "Added query expires at %ld\n",			(long) new_cached_query->expiry_time, 0, 0 );	new_query = (Query*)new_cached_query;	ber_dupbv(&new_query->base, &query->base);	new_query->scope = query->scope;	new_query->filter = query->filter;	new_query->attrs = query->attrs;	/* Adding a query    */	Debug( pcache_debug, "Lock AQ index = %d\n",			template_index, 0, 0 );	ldap_pvt_thread_rdwr_wlock(&templ->t_rwlock);	if (templ->query == NULL)		templ->query_last = new_cached_query;	else		templ->query->prev = new_cached_query;	new_cached_query->next = templ->query;	new_cached_query->prev = NULL;	templ->query = new_cached_query;	templ->no_of_queries++;	Debug( pcache_debug, "TEMPLATE %d QUERIES++ %d\n",			template_index, templ->no_of_queries, 0 );	Debug( pcache_debug, "Unlock AQ index = %d \n",			template_index, 0, 0 );	ldap_pvt_thread_rdwr_wunlock(&templ->t_rwlock);	/* Adding on top of LRU list  */	ldap_pvt_thread_mutex_lock(&qm->lru_mutex);	add_query_on_top(qm, new_cached_query);	ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);}static voidremove_from_template (CachedQuery* qc, QueryTemplate* template){	if (!qc->prev && !qc->next) {		template->query_last = template->query = NULL;	} else if (qc->prev == NULL) {		qc->next->prev = NULL;		template->query = qc->next;	} else if (qc->next == NULL) {		qc->prev->next = NULL;		template->query_last = qc->prev;	} else {		qc->next->prev = qc->prev;		qc->prev->next = qc->next;	}	template->no_of_queries--;}/* remove bottom query of LRU list from the query cache */static void cache_replacement(query_manager* qm, struct berval *result){	CachedQuery* bottom;	int temp_id;	ldap_pvt_thread_mutex_lock(&qm->lru_mutex);	bottom = qm->lru_bottom;	result->bv_val = NULL;	result->bv_len = 0;	if (!bottom) {		Debug ( pcache_debug,			"Cache replacement invoked without "			"any query in LRU list\n", 0, 0, 0 );		ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);		return;	}	temp_id = bottom->template_id;	remove_query(qm, bottom);	ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);	*result = bottom->q_uuid;	bottom->q_uuid.bv_val = NULL;	Debug( pcache_debug, "Lock CR index = %d\n", temp_id, 0, 0 );	ldap_pvt_thread_rdwr_wlock(&(qm->templates[temp_id].t_rwlock));	remove_from_template(bottom, (qm->templates+temp_id));	Debug( pcache_debug, "TEMPLATE %d QUERIES-- %d\n",		temp_id, qm->templates[temp_id].no_of_queries, 0 );	Debug( pcache_debug, "Unlock CR index = %d\n", temp_id, 0, 0 );	ldap_pvt_thread_rdwr_wunlock(&(qm->templates[temp_id].t_rwlock));	free_query(bottom);}struct query_info {	struct query_info *next;	struct berval xdn;	int del;};static intremove_func (	Operation	*op,	SlapReply	*rs){	Attribute *attr;	struct query_info *qi;	int count = 0;	if ( rs->sr_type != REP_SEARCH ) return 0;	for (attr = rs->sr_entry->e_attrs; attr!= NULL; attr = attr->a_next) {		if (attr->a_desc == ad_queryid) {			for (count=0; attr->a_vals[count].bv_val; count++)				;			break;		}	}	if ( count == 0 ) return 0;	qi = op->o_tmpalloc( sizeof( struct query_info ), op->o_tmpmemctx );	qi->next = op->o_callback->sc_private;	op->o_callback->sc_private = qi;	ber_dupbv_x( &qi->xdn, &rs->sr_entry->e_nname, op->o_tmpmemctx );	qi->del = ( count == 1 );	return 0;}static intremove_query_data (	Operation	*op,	SlapReply	*rs,	struct berval* query_uuid){	struct query_info	*qi, *qnext;	char			filter_str[64];#ifdef LDAP_COMP_MATCH	AttributeAssertion	ava = { NULL, BER_BVNULL, NULL };#else	AttributeAssertion	ava = { NULL, BER_BVNULL };#endif	Filter			filter = {LDAP_FILTER_EQUALITY};	SlapReply 		sreply = {REP_RESULT};	slap_callback cb = { NULL, remove_func, NULL, NULL };	int deleted = 0;	sreply.sr_entry = NULL;	sreply.sr_nentries = 0;	op->ors_filterstr.bv_len = snprintf(filter_str, sizeof(filter_str),		"(%s=%s)", ad_queryid->ad_cname.bv_val, query_uuid->bv_val);	filter.f_ava = &ava;	filter.f_av_desc = ad_queryid;	filter.f_av_value = *query_uuid;	op->o_tag = LDAP_REQ_SEARCH;	op->o_protocol = LDAP_VERSION3;	op->o_callback = &cb;	op->o_time = slap_get_time();	op->o_do_not_cache = 1;	op->o_req_dn = op->o_bd->be_suffix[0];	op->o_req_ndn = op->o_bd->be_nsuffix[0];	op->ors_scope = LDAP_SCOPE_SUBTREE;	op->ors_deref = LDAP_DEREF_NEVER;	op->ors_slimit = SLAP_NO_LIMIT;	op->ors_tlimit = SLAP_NO_LIMIT;	op->ors_filter = &filter;	op->ors_filterstr.bv_val = filter_str;	op->ors_filterstr.bv_len = strlen(filter_str);	op->ors_attrs = NULL;	op->ors_attrsonly = 0;	op->o_bd->be_search( op, &sreply );	for ( qi=cb.sc_private; qi; qi=qnext ) {		qnext = qi->next;		op->o_req_dn = qi->xdn;		op->o_req_ndn = qi->xdn;		if ( qi->del) {			Debug( pcache_debug, "DELETING ENTRY TEMPLATE=%s\n",				query_uuid->bv_val, 0, 0 );			op->o_tag = LDAP_REQ_DELETE;			if (op->o_bd->be_delete(op, &sreply) == LDAP_SUCCESS) {				deleted++;			}		} else {			Modifications mod;			struct berval vals[2];			vals[0] = *query_uuid;			vals[1].bv_val = NULL;			vals[1].bv_len = 0;			mod.sml_op = LDAP_MOD_DELETE;			mod.sml_flags = 0;			mod.sml_desc = ad_queryid;			mod.sml_type = ad_queryid->ad_cname;			mod.sml_values = vals;			mod.sml_nvalues = NULL;			mod.sml_next = NULL;			Debug( pcache_debug,				"REMOVING TEMP ATTR : TEMPLATE=%s\n",				query_uuid->bv_val, 0, 0 );			op->orm_modlist = &mod;			op->o_bd->be_modify( op, &sreply );		}		op->o_tmpfree( qi->xdn.bv_val, op->o_tmpmemctx );		op->o_tmpfree( qi, op->o_tmpmemctx );	}	return deleted;}static intget_attr_set(	AttributeName* attrs,	query_manager* qm,	int num);static intfilter2template(	Operation		*op,	Filter			*f,	struct			berval *fstr,	AttributeName**		filter_attrs,	int*			filter_cnt,	int*			filter_got_oc ){	AttributeDescription *ad;	switch ( f->f_choice ) {	case LDAP_FILTER_EQUALITY:		ad = f->f_av_desc;		sprintf( fstr->bv_val+fstr->bv_len, "(%s=)", ad->ad_cname.bv_val );		fstr->bv_len += ad->ad_cname.bv_len + ( sizeof("(=)") - 1 );		break;	case LDAP_FILTER_GE:		ad = f->f_av_desc;		sprintf( fstr->bv_val+fstr->bv_len, "(%s>=)", ad->ad_cname.bv_val);		fstr->bv_len += ad->ad_cname.bv_len + ( sizeof("(>=)") - 1 );		break;	case LDAP_FILTER_LE:		ad = f->f_av_desc;		sprintf( fstr->bv_val+fstr->bv_len, "(%s<=)", ad->ad_cname.bv_val);		fstr->bv_len += ad->ad_cname.bv_len + ( sizeof("(<=)") - 1 );		break;	case LDAP_FILTER_APPROX:		ad = f->f_av_desc;		sprintf( fstr->bv_val+fstr->bv_len, "(%s~=)", ad->ad_cname.bv_val);		fstr->bv_len += ad->ad_cname.bv_len + ( sizeof("(~=)") - 1 );		break;	case LDAP_FILTER_SUBSTRINGS:		ad = f->f_sub_desc;		sprintf( fstr->bv_val+fstr->bv_len, "(%s=)", ad->ad_cname.bv_val );		fstr->bv_len += ad->ad_cname.bv_len + ( sizeof("(=)") - 1 );		break;	case LDAP_FILTER_PRESENT:		ad = f->f_desc;		sprintf( fstr->bv_val+fstr->bv_len, "(%s=*)", ad->ad_cname.bv_val );		fstr->bv_len += ad->ad_cname.bv_len + ( sizeof("(=*)") - 1 );		break;	case LDAP_FILTER_AND:	case LDAP_FILTER_OR:	case LDAP_FILTER_NOT: {		int rc = 0;		sprintf( fstr->bv_val+fstr->bv_len, "(%c",			f->f_choice == LDAP_FILTER_AND ? '&' :			f->f_choice == LDAP_FILTER_OR ? '|' : '!' );		fstr->bv_len += sizeof("(%") - 1;		for ( f = f->f_list; f != NULL; f = f->f_next ) {			rc = filter2template( op, f, fstr, filter_attrs, filter_cnt,				filter_got_oc );			if ( rc ) break;		}		sprintf( fstr->bv_val+fstr->bv_len, ")" );		fstr->bv_len += sizeof(")") - 1;		return rc;		}	default:		strcpy( fstr->bv_val, "(?=?)" );		fstr->bv_len += sizeof("(?=?)")-1;		return -1;	}	*filter_attrs = (AttributeName *)op->o_tmprealloc(*filter_attrs,				(*filter_cnt + 2)*sizeof(AttributeName), op->o_tmpmemctx);	(*filter_attrs)[*filter_cnt].an_desc = ad;	(*filter_attrs)[*filter_cnt].an_name = ad->ad_cname;	(*filter_attrs)[*filter_cnt].an_oc = NULL;	(*filter_attrs)[*filter_cnt].an_oc_exclude = 0;	BER_BVZERO( &(*filter_attrs)[*filter_cnt+1].an_name );	(*filter_cnt)++;	if ( ad == slap_schema.si_ad_objectClass )		*filter_got_oc = 1;	return 0;}struct search_info {	slap_overinst *on;	Query query;	int template_id;	int max;	int over;	int count;	Entry *head, *tail;};static intcache_entries(	Operation	*op,	SlapReply	*rs,	struct berval *query_uuid){	struct search_info *si = op->o_callback->sc_private;	slap_overinst *on = si->on;	cache_manager *cm = on->on_bi.bi_private;	query_manager*		qm = cm->qm;	int		return_val = 0;	Entry		*e;	struct berval	crp_uuid;	char		uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];	Operation op_tmp = *op;	query_uuid->bv_len = lutil_uuidstr(uuidbuf, sizeof(uuidbuf));	ber_str2bv(uuidbuf, query_uuid->bv_len, 1, query_uuid);	op_tmp.o_bd = &cm->db;	op_tmp.o_dn = cm->db.be_rootdn;	op_tmp.o_ndn = cm->db.be_rootndn;	Debug( pcache_debug, "UUID for query being added = %s\n",			uuidbuf, 0, 0 );	for ( e=si->head; e; e=si->head ) {		si->head = e->e_private;		e->e_private = NULL;		while ( cm->cur_entries > (cm->max_entries) ) {				qm->crfunc(qm, &crp_uuid);				if (crp_uuid.bv_val) {					Debug( pcache_debug,						"Removing query UUID %s\n",						crp_uuid.bv_val, 0, 0 );					return_val = remove_query_data(&op_tmp, rs, &crp_uuid);					Debug( pcache_debug,						"QUERY REMOVED, SIZE=%d\n",						return_val, 0, 0);					ldap_pvt_thread_mutex_lock(							&cm->cache_mutex );					cm->cur_entries -= return_val;					cm->num_cached_queries--;					Debug( pcache_debug,						"STORED QUERIES = %lu\n",						cm->num_cached_queries, 0, 0 );					ldap_pvt_thread_mutex_unlock(							&cm->cache_mutex );					Debug( pcache_debug,						"QUERY REMOVED, CACHE ="						"%d entries\n",						cm->cur_entries, 0, 0 );				}		}		return_val = merge_entry(&op_tmp, e, query_uuid);		ldap_pvt_thread_mutex_lock(&cm->cache_mutex);		cm->cur_entries += return_val;		Debug( pcache_debug,			"ENTRY ADDED/MERGED, CACHED ENTRIES=%d\n",			cm->cur_entries, 0, 0 );		return_val = 0;		ldap_pvt_thread_mutex_unlock(&cm->cache_mutex);	}	return return_val;}static intpcache_response(	Operation	*op,	SlapReply	*rs ){	struct search_info *si = op->o_callback->sc_private;	slap_overinst *on = si->on;	cache_manager *cm = on->on_bi.bi_private;	query_manager*		qm = cm->qm;	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 ) {		Entry *e;		/* 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 ) {			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 {				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;			}		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -