Plasma GitLab Archive
Projects Blog Knowledge

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

    

This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml