/* $Id: cache.x 7783 2006-11-20 21:49:46Z gerd $ */
/* a caching service (probably memory-based) */
/* the up to 255-byte key, typically produced by computing an md5 hash */
typedef string key<255>;
typedef string longstring<>;
typedef hyper timestamp; /* unix timestamp -- seconds since 1.1.1970 */
typedef int bucket;
typedef string md5<16>;
struct entry {
key e_key;
timestamp e_creation; /* When this entry was added */
timestamp e_modification; /* Last modification of e_value */
timestamp e_expiration; /* When the entry will expire; 0 = never */
bool e_delete_flag; /* Whether this entry is scheduled for deletion */
longstring e_value;
md5 e_value_hash; /* Hash value of [e_value] */
int e_value_length; /* Length of [e_value] */
int e_counter; /* Number of [get] accesses */
bucket e_bucket;
};
struct set_options {
bool opt_overwrite;
bool opt_add;
bool opt_undelete;
bool opt_setifchanged;
};
enum set_enum {
NOT_STORED = 0,
STORED = 1
};
union set_result switch (set_enum d) {
case STORED:
void;
case NOT_STORED:
void;
};
struct get_options {
bool opt_novalue;
timestamp *opt_getifmodifiedsince;
md5 *opt_getifnotmd5;
};
enum get_enum {
NOT_FOUND = 0,
FOUND = 1
};
union get_result switch (get_enum d) {
case FOUND:
entry e;
case NOT_FOUND:
void;
};
struct delete_options {
bool opt_strictlock;
timestamp *opt_delifolderthan;
md5 *opt_delifmd5;
md5 *opt_delifnotmd5;
};
struct config {
hyper max_size; /* Max size of cache in bytes */
int save_cache_period; /* Save the cache to disk every this number of seconds */
int save_cache_speed; /* Speed in bytes/sec */
};
struct stats {
/* the number of entries in the cache */
int num_entries;
/* the total number of stored bytes (excluding overhead for indexes, etc) */
hyper num_bytes;
/* the number of get() calls */
int num_calls_get;
/* the number of set() calls */
int num_calls_set;
/* the number of delete() calls */
int num_calls_delete;
/* number of get() calls returning FOUND */
int num_hits;
/* when the request and hit counters were last set to zero */
timestamp counters_reset_on;
};
program Cache {
version V1 {
void ping(void) = 0;
set_result set( key,
bucket,
longstring, /* value */
timestamp, /* expiration */
set_options
) = 1;
/* Store a (key,value) pair in the cache. The [key] identifies the entry.
* The [bucket] determines into which file the entry is saved if
* persistency is enabled. The [longstring] is the value to store.
* The [timestamp] specifies when the entry expires. A value of 0 means
* it will never expire.
*
* The [set_options]:
* - [opt_overwrite]: If true, an existing entry for [key] is overwritten.
* If false, existing entries are not modified.
* - [opt_add]: If true, it is possible to add new keys. If false, this
* is not allowed.
* - [opt_undelete]: If true, it is possible to add/overwrite entries that
* are already scheduled for deletion. These entries are removed from
* the delete queue and are no longer scheduled for deletion. If false,
* such entries cannot be modified.
* - [opt_setifchanged]: If true and also [opt_overwrite] is in effect,
* entries are only overwritten if the new value is distinct from the
* already stored value. This also means that the new expiration time
* is only accepted if the new value is distinct.
*
* The procedure returns STORED or NOT_STORED.
*/
get_result get( key,
get_options
) = 2;
/* Look up the [key] in the cache, and return either FOUND or NOT_FOUND.
*
* The [get_options] modify the lookup:
* - [opt_novalue]: If true, the value of the entry is not returned, but
* replaced with the empty string. Thus only the meta data of the entry
* are returned.
* - [opt_getifmodifiedsince]: If non-NULL, the existing entry is only returned
* as FOUND if its value has been modified since the passed timestamp.
* Otherwise, NOT_FOUND is passed back for the existing entry.
* - [opt_getifnotmd5]: If non-NULL, the existing entry is only returned as
* FOUND if the MD5 hash of its value is different than the passed
* MD5 hash.
*/
void delete( key,
timestamp,
delete_options
) = 3;
/* Schedules the entry identified by [key] for deletion at the passed
* [timestamp]. If the timestamp is in the past, the deletion is executed
* immediately.
*
* If the deletion will happen in the future, the [key] is added to the
* deletion queue, and locked against any modification until the
* deletion actually happens (except that [opt_undelete] may override
* this lock). Actually, the expiration date of the entry is set to
* [timestamp], and [e_delete_flag] is set to true.
*
* The [delete_options] modify the deletion procedure:
* - [opt_strictlock]: If true, the [key] is even added to the deletion
* queue if the entry does not exist. This means that an entry for [key]
* cannot be added until [timestamp].
* - [opt_delifolderthan]: If non-NULL the entry is only deleted if the last
* modification of its value happened before the timestamp passed
* as argument of [opt_ifolderthan].
* - [opt_delifmd5]: If non-NULL the entry is only deleted if the
* MD5 hash of its value is equal to the passed MD5 hash.
* - [opt_delifnotmd5]: If non-NULL the entry is only deleted if the
* MD5 hash of its value is not equal to the passed MD5 hash.
*/
void clear(void) = 4;
/* delete all the entries */
config get_config( void ) = 5;
void set_config ( config ) = 6;
/* get/set the dynamically modifiable part of the configuration */
stats get_stats( void ) = 7;
/* get cache statistics */
void clear_counters( void ) = 8;
/* clear all the hit counters */
} = 1;
} = 600;