/*++ /* NAME /* dict_cache 3 /* SUMMARY /* External cache manager /* SYNOPSIS /* #include <dict_cache.h> /* /* DICT_CACHE *dict_cache_open(dbname, open_flags, dict_flags) /* const char *dbname; /* int open_flags; /* int dict_flags; /* /* void dict_cache_close(cache) /* DICT_CACHE *cache; /* /* const char *dict_cache_lookup(cache, cache_key) /* DICT_CACHE *cache; /* const char *cache_key; /* /* int dict_cache_update(cache, cache_key, cache_val) /* DICT_CACHE *cache; /* const char *cache_key; /* const char *cache_val; /* /* int dict_cache_delete(cache, cache_key) /* DICT_CACHE *cache; /* const char *cache_key; /* /* int dict_cache_sequence(cache, first_next, cache_key, cache_val) /* DICT_CACHE *cache; /* int first_next; /* const char **cache_key; /* const char **cache_val; /* /* int dict_cache_error(cache) /* DICT_CACHE *cache; /* AUXILIARY FUNCTIONS /* void dict_cache_control(cache, name, value, ...) /* DICT_CACHE *cache; /* int name; /* /* typedef int (*DICT_CACHE_VALIDATOR_FN) (const char *cache_key, /* const char *cache_val, void *context); /* /* const char *dict_cache_name(cache) /* DICT_CACHE *cache; /* DESCRIPTION /* This module maintains external cache files with support /* for expiration. The underlying table must implement the /* "lookup", "update", "delete" and "sequence" operations. /* /* Although this API is similar to the one documented in /* dict_open(3), there are subtle differences in the interaction /* between the iterators that access all cache elements, and /* other operations that access individual cache elements. /* /* In particular, when a "sequence" or "cleanup" operation is /* in progress the cache intercepts requests to delete the /* "current" entry, as this would cause some databases to /* mis-behave. Instead, the cache implements a "delete behind" /* strategy, and deletes such an entry after the "sequence" /* or "cleanup" operation moves on to the next cache element. /* The "delete behind" strategy also affects the cache lookup /* and update operations as detailed below. /* /* dict_cache_open() is a wrapper around the dict_open() /* function. It opens the specified cache and returns a handle /* that must be used for subsequent access. This function does /* not return in case of error. /* /* dict_cache_close() closes the specified cache and releases /* memory that was allocated by dict_cache_open(), and terminates /* any thread that was started with dict_cache_control(). /* /* dict_cache_lookup() looks up the specified cache entry. /* The result value is a null pointer when the cache entry was /* not found, or when the entry is scheduled for "delete /* behind". /* /* dict_cache_update() updates the specified cache entry. If /* the entry is scheduled for "delete behind", the delete /* operation is canceled (because of this, the cache must be /* opened with DICT_FLAG_DUP_REPLACE). This function does not /* return in case of error. /* /* dict_cache_delete() removes the specified cache entry. If /* this is the "current" entry of a "sequence" operation, the /* entry is scheduled for "delete behind". The result value /* is zero when the entry was found. /* /* dict_cache_sequence() iterates over the specified cache and /* returns each entry in an implementation-defined order. The /* result value is zero when a cache entry was found. /* /* Important: programs must not use both dict_cache_sequence() /* and the built-in cache cleanup feature. /* /* dict_cache_control() provides control over the built-in /* cache cleanup feature and logging. The arguments are a list /* of macros with zero or more arguments, terminated with /* CA_DICT_CACHE_CTL_END which has none. The following lists /* the macros and corresponding argument types. /* .IP "CA_DICT_CACHE_CTL_FLAGS(int flags)" /* The arguments to this command are the bit-wise OR of zero /* or more of the following: /* .RS /* .IP CA_DICT_CACHE_CTL_FLAG_VERBOSE /* Enable verbose logging of cache activity. /* .IP CA_DICT_CACHE_CTL_FLAG_EXP_SUMMARY /* Log cache statistics after each cache cleanup run. /* .RE /* .IP "CA_DICT_CACHE_CTL_INTERVAL(int interval)" /* The interval between cache cleanup runs. Specify a null /* validator or interval to stop cache cleanup and log cache /* statistics if a cleanup run was in progress. /* .IP "CA_DICT_CACHE_CTL_VALIDATOR(DICT_CACHE_VALIDATOR_FN validator)" /* An application call-back routine that returns non-zero when /* a cache entry should be kept. The call-back function should /* not make changes to the cache. Specify a null validator or /* interval to stop cache cleanup. /* .IP "CA_DICT_CACHE_CTL_CONTEXT(void *context)" /* Application context that is passed to the validator function. /* .RE /* .PP /* dict_cache_name() returns the name of the specified cache. /* /* dict_cache_error() returns the error status for the underlying /* dictionary. /* /* Arguments: /* .IP "dbname, open_flags, dict_flags" /* These are passed unchanged to dict_open(). The cache must /* be opened with DICT_FLAG_DUP_REPLACE. /* .IP cache /* Cache handle created with dict_cache_open(). /* .IP cache_key /* Cache lookup key. /* .IP cache_val /* Information that is stored under a cache lookup key. /* .IP first_next /* One of DICT_SEQ_FUN_FIRST (first cache element) or /* DICT_SEQ_FUN_NEXT (next cache element). /* .sp /* Note: there is no "stop" request. To ensure that the "delete /* behind" strategy does not interfere with database access, /* allow dict_cache_sequence() to run to completion. /* .IP table /* A bare dictionary handle. /* DIAGNOSTICS /* When a request is satisfied, the lookup routine returns /* non-null, and the update, delete and sequence routines /* return zero. The cache->error value is zero when a request /* could not be satisfied because an item did not exist (delete, /* sequence) or if it could not be updated. The cache->error /* value is non-zero only when a request could not be satisfied, /* and the cause was a database error. /* /* Cache access errors are logged with a warning message. To /* avoid spamming the log, each type of operation logs no more /* than one cache access error per second, per cache. Specify /* the DICT_CACHE_FLAG_VERBOSE flag (see above) to log all /* warnings. /* BUGS /* There should be a way to suspend automatic program suicide /* until a cache cleanup run is completed. Some entries may /* never be removed when the process max_idle time is less /* than the time needed to make a full pass over the cache. /* /* The delete-behind strategy assumes that all updates are /* made by a single process. Otherwise, delete-behind may /* remove an entry that was updated after it was scheduled for /* deletion. /* LICENSE /* .ad /* .fi /* The Secure Mailer license must be distributed with this software. /* HISTORY /* .ad /* .fi /* A predecessor of this code was written first for the Postfix /* tlsmgr(8) daemon. /* AUTHOR(S) /* Wietse Venema /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA
/*--*/
/* *Opaquedatastructure.Usedict_cache_name()toaccessthenameofthe *underlyingdatabase.
*/ struct DICT_CACHE { char *name; /* full name including proxy: */ int cache_flags; /* see below */ int user_flags; /* logging */
DICT *db; /* database handle */ int error; /* last operation only */
/* Cleanup support. */ int exp_interval; /* time between cleanup runs */
DICT_CACHE_VALIDATOR_FN exp_validator; /* expiration call-back */ void *exp_context; /* call-back context */ int retained; /* entries retained in cleanup run */ int dropped; /* entries removed in cleanup run */
/* Rate-limited logging support. */ int log_delay;
time_t upd_log_stamp; /* last update warning */
time_t get_log_stamp; /* last lookup warning */
time_t del_log_stamp; /* last delete warning */
time_t seq_log_stamp; /* last sequence warning */
};
#define DC_FLAG_DEL_SAVED_CURRENT_KEY (1<<0) /* delete-behind is scheduled */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.