/* $Id$ */ /* 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;