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

📄 cache.c

📁 OpenLdap是LDAP的开源项目
💻 C
📖 第 1 页 / 共 2 页
字号:
/* cache.c - routines to maintain an in-core cache of entries *//* $OpenLDAP: pkg/ldap/servers/slapd/back-ldbm/cache.c,v 1.66.2.5 2007/01/02 21:44:02 kurt Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 1998-2007 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * <http://www.OpenLDAP.org/license.html>. */#include "portable.h"#include <stdio.h>#include <ac/errno.h>#include <ac/string.h>#include <ac/socket.h>#include "slap.h"#include "back-ldbm.h"/* LDBM backend specific entry info -- visible only to the cache */typedef struct ldbm_entry_info {	/*	 * These items are specific to the LDBM backend and should	 * be hidden.  Backend cache lock required to access.	 */	int		lei_state;	/* for the cache */#define	CACHE_ENTRY_UNDEFINED	0#define CACHE_ENTRY_CREATING	1#define CACHE_ENTRY_READY	2#define CACHE_ENTRY_DELETED	3#define CACHE_ENTRY_COMMITTED	4		int		lei_refcnt;	/* # threads ref'ing this entry */	Entry	*lei_lrunext;	/* for cache lru list */	Entry	*lei_lruprev;} EntryInfo;#undef LEI#define LEI(e)	((EntryInfo *) ((e)->e_private))static int	cache_delete_entry_internal(Cache *cache, Entry *e);#ifdef LDAP_DEBUG#ifdef SLAPD_UNUSEDstatic void	lru_print(Cache *cache);#endif#endifstatic intcache_entry_private_init( Entry*e ){	assert( e->e_private == NULL );	if( e->e_private != NULL ) {		/* this should never happen */		return 1;	}	e->e_private = ch_calloc(1, sizeof(struct ldbm_entry_info));	return 0;}/* * marks an entry in CREATING state as committed, so it is really returned * to the cache. Otherwise an entry in CREATING state is removed. * Makes e_private be destroyed at the following cache_return_entry_w, * but lets the entry untouched (owned by someone else) */voidcache_entry_commit( Entry *e ){	assert( e != NULL );	assert( e->e_private != NULL );	assert( LEI(e)->lei_state == CACHE_ENTRY_CREATING );	/* assert( LEI(e)->lei_refcnt == 1 ); */	LEI(e)->lei_state = CACHE_ENTRY_COMMITTED;}static intcache_entry_private_destroy( Entry*e ){	assert( e->e_private != NULL );	free( e->e_private );	e->e_private = NULL;	return 0;}voidcache_return_entry_rw( Cache *cache, Entry *e, int rw ){	ID id;	int refcnt, freeit = 1;	if ( slapMode != SLAP_SERVER_MODE ) {		return;	}	/* set cache mutex */	ldap_pvt_thread_mutex_lock( &cache->c_mutex );	assert( e->e_private != NULL );	id = e->e_id;	refcnt = --LEI(e)->lei_refcnt;	/*	 * if the entry is returned when in CREATING state, it is deleted	 * but not freed because it may belong to someone else (do_add,	 * for instance)	 */	if (  LEI(e)->lei_state == CACHE_ENTRY_CREATING ) {		cache_delete_entry_internal( cache, e );		freeit = 0;		/* now the entry is in DELETED state */	}	if ( LEI(e)->lei_state == CACHE_ENTRY_COMMITTED ) {		LEI(e)->lei_state = CACHE_ENTRY_READY;		/* free cache mutex */		ldap_pvt_thread_mutex_unlock( &cache->c_mutex );		Debug( LDAP_DEBUG_TRACE,			"====> cache_return_entry_%s( %ld ): created (%d)\n",			rw ? "w" : "r", id, refcnt );	} else if ( LEI(e)->lei_state == CACHE_ENTRY_DELETED ) {		if( refcnt > 0 ) {			/* free cache mutex */			ldap_pvt_thread_mutex_unlock( &cache->c_mutex );			Debug( LDAP_DEBUG_TRACE,				"====> cache_return_entry_%s( %ld ): delete pending (%d)\n",				rw ? "w" : "r", id, refcnt );		} else {			cache_entry_private_destroy( e );			if ( freeit ) {				entry_free( e );			}			/* free cache mutex */			ldap_pvt_thread_mutex_unlock( &cache->c_mutex );			Debug( LDAP_DEBUG_TRACE,				"====> cache_return_entry_%s( %ld ): deleted (%d)\n",				rw ? "w" : "r", id, refcnt );		}	} else {		/* free cache mutex */		ldap_pvt_thread_mutex_unlock( &cache->c_mutex );		Debug( LDAP_DEBUG_TRACE,			"====> cache_return_entry_%s( %ld ): returned (%d)\n",			rw ? "w" : "r", id, refcnt);	}}#define LRU_DELETE( cache, e ) do { \	if ( LEI(e)->lei_lruprev != NULL ) { \		LEI(LEI(e)->lei_lruprev)->lei_lrunext = LEI(e)->lei_lrunext; \	} else { \		(cache)->c_lruhead = LEI(e)->lei_lrunext; \	} \	if ( LEI(e)->lei_lrunext != NULL ) { \		LEI(LEI(e)->lei_lrunext)->lei_lruprev = LEI(e)->lei_lruprev; \	} else { \		(cache)->c_lrutail = LEI(e)->lei_lruprev; \	} \} while(0)#define LRU_ADD( cache, e ) do { \	LEI(e)->lei_lrunext = (cache)->c_lruhead; \	if ( LEI(e)->lei_lrunext != NULL ) { \		LEI(LEI(e)->lei_lrunext)->lei_lruprev = (e); \	} \	(cache)->c_lruhead = (e); \	LEI(e)->lei_lruprev = NULL; \	if ( (cache)->c_lrutail == NULL ) { \		(cache)->c_lrutail = (e); \	} \} while(0)/* * cache_add_entry_rw - create and lock an entry in the cache * returns:	0	entry has been created and locked *		1	entry already existed *		-1	something bad happened */intcache_add_entry_rw(    Cache	*cache,    Entry		*e,	int		rw){	int	i, rc;	Entry	*ee;	/* set cache mutex */	ldap_pvt_thread_mutex_lock( &cache->c_mutex );	assert( e->e_private == NULL );	if( cache_entry_private_init(e) != 0 ) {		/* free cache mutex */		ldap_pvt_thread_mutex_unlock( &cache->c_mutex );		Debug( LDAP_DEBUG_ANY,			"====> cache_add_entry( %ld ): \"%s\": private init failed!\n",		    e->e_id, e->e_dn, 0 );		return( -1 );	}	if ( avl_insert( &cache->c_dntree, (caddr_t) e,	                 entry_dn_cmp, avl_dup_error ) != 0 )	{		/* free cache mutex */		ldap_pvt_thread_mutex_unlock( &cache->c_mutex );		Debug( LDAP_DEBUG_TRACE,			"====> cache_add_entry( %ld ): \"%s\": already in dn cache\n",		    e->e_id, e->e_dn, 0 );		cache_entry_private_destroy(e);		return( 1 );	}	/* id tree */	if ( avl_insert( &cache->c_idtree, (caddr_t) e,	                 entry_id_cmp, avl_dup_error ) != 0 )	{		Debug( LDAP_DEBUG_ANY,			"====> cache_add_entry( %ld ): \"%s\": already in id cache\n",		    e->e_id, e->e_dn, 0 );		/* delete from dn tree inserted above */		if ( avl_delete( &cache->c_dntree, (caddr_t) e,		                 entry_dn_cmp ) == NULL )		{			Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n",			    0, 0, 0 );		}		cache_entry_private_destroy(e);		/* free cache mutex */		ldap_pvt_thread_mutex_unlock( &cache->c_mutex );		return( -1 );	}	/* put the entry into 'CREATING' state */	/* will be marked after when entry is returned */	LEI(e)->lei_state = CACHE_ENTRY_CREATING;	LEI(e)->lei_refcnt = 1;	/* lru */	LRU_ADD( cache, e );	if ( ++cache->c_cursize > cache->c_maxsize ) {		/*		 * find the lru entry not currently in use and delete it.		 * in case a lot of entries are in use, only look at the		 * first 10 on the tail of the list.		 */		i = 0;		while ( cache->c_lrutail != NULL &&			LEI(cache->c_lrutail)->lei_refcnt != 0 &&			i < 10 )		{			/* move this in-use entry to the front of the q */			ee = cache->c_lrutail;			LRU_DELETE( cache, ee );			LRU_ADD( cache, ee );			i++;		}		/*		 * found at least one to delete - try to get back under		 * the max cache size.		 */		while ( cache->c_lrutail != NULL &&			LEI(cache->c_lrutail)->lei_refcnt == 0 &&			cache->c_cursize > cache->c_maxsize )		{			e = cache->c_lrutail;			/* delete from cache and lru q */			/* XXX do we need rc ? */			rc = cache_delete_entry_internal( cache, e );			cache_entry_private_destroy( e );			entry_free( e );		}	}	/* free cache mutex */	ldap_pvt_thread_mutex_unlock( &cache->c_mutex );	return( 0 );}/* * cache_update_entry - update a LOCKED entry which has been deleted. * returns:	0	entry has been created and locked *		1	entry already existed *		-1	something bad happened */intcache_update_entry(    Cache	*cache,    Entry		*e){	int	i, rc;	Entry	*ee;	/* set cache mutex */	ldap_pvt_thread_mutex_lock( &cache->c_mutex );	assert( e->e_private != NULL );	if ( avl_insert( &cache->c_dntree, (caddr_t) e,	                 entry_dn_cmp, avl_dup_error ) != 0 )	{		Debug( LDAP_DEBUG_TRACE,			"====> cache_update_entry( %ld ): \"%s\": already in dn cache\n",		    e->e_id, e->e_dn, 0 );

⌨️ 快捷键说明

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