module Cache_client:sig..end
e_bucket component
of the entries. Functions for doing this can be found in
Cache_util:
let e_key = Cache_util.hash_of_key k in
let e_bucket = Cache_util.bucket_of_hash n e_key
The number n is the number of buckets.
Expiration. Entries can have a timestamp that says when the entries
are removed from the cache. It is ensured that the get operation never
returns an expired entry when both client and server have the same clock.
Independent of expiration by time, the cache may also expire entries
because the cache becomes too large. The cache implements a LRU semantics:
The least recently used entries are removed first. As "use" any get
or set operation qualifies.
Deletion. There is a third mechanism for removing
entries: One can also actively delete entries. The delete operation
takes a delete timestamp as argument. If this timestamp is in the past
(e.g. 0), the deletion is performed immediately. Otherwise the entry
is scheduled for deletion at the given time. The e_delete_flag says
whether such a deletion will happen.
In order to coordinate parallel accesses to the cache, all entries
that are scheduled for deletion are locked for overwriting. Any
set operation is refused by default. You can break this lock by
setting the opt_undelete option. In this case, set not only overwrites
but also cancels the scheduled deletion.
The delete operation has effectively a higher precedence than the
set operation unless you specify opt_undelete. This makes delete
different from setting a new expiration timestamp in the entry by
calling set. The higher precedence is useful if you have new knowledge
about the validity period of entries, and you want to prevent that
restricting the validity period interfers with the regular use of set.
Note that a scheduled deletion does not prevent the entry from expiring
because of the expiration timestamp or because of exceeding the maximum
size of the cache.
Atomicity. The operations set and delete are either fully
conducted, or not conducted at all. For example, if you call set
with opt_setifchanged, there are only two outcomes:
set operation is done: The value is overwritten, the
new modification timestamp is set, the expiration timestamp is
set to the passed value, and any delete flag is removed.set operation is not done: The entry is not modified at all.opt_setifchanged causes that set is only performed for
value changes, you get implicitly the effect of only setting
the modification and expiration timestamps when the value is
distinct from the previous one.typekey =[ `Hash of Digest.t | `String of string ]
`Hash dg: As digest of a string`String s: As string (to be digested)typetimestamp =int64
typeentry =Cache_aux.entry= {
|
mutable e_key : |
(* | The key in hashed form | *) |
|
mutable e_creation : |
(* | Time of first addition to the cache | *) |
|
mutable e_modification : |
(* | Time of last modification in the cache | *) |
|
mutable e_expiration : |
(* | Time when the entry will expire; 0 = never | *) |
|
mutable e_delete_flag : |
(* | Whether this entry is scheduled for deletion | *) |
|
mutable e_value : |
(* | The value of the entry, an arbitrary string | *) |
|
mutable e_value_hash : |
(* | The MD5 sum of the value | *) |
|
mutable e_value_length : |
(* | The length of the value | *) |
|
mutable e_counter : |
(* | The number of get accesses to this entry | *) |
|
mutable e_bucket : |
(* | The bucket number of this entry | *) |
typeset_options =Cache_aux.set_options= {
|
mutable opt_overwrite : |
(* | Allow overwriting existing entries | *) |
|
mutable opt_add : |
(* | Allow adding new entries | *) |
|
mutable opt_undelete : |
(* | Allow the modification of entries that are scheduled for deletion. Such entries are revived, and count no longer as deleted | *) |
|
mutable opt_setifchanged : |
(* | Modifies opt_overwrite:
Overwriting is only permitted if the new value is distinct from
the old one | *) |
set operationtypeget_options =Cache_aux.get_options= {
|
mutable opt_novalue : |
(* | Do not return the e_value
component of entries, but an empty string as replacement (for
getting meta data only) | *) |
|
mutable opt_getifmodifiedsince : |
(* | When Some t: Only return
entries that have e_modification >= t. When None: No
restriction. | *) |
|
mutable opt_getifnotmd5 : |
(* | When Some dg: Only return
entries when e_value_hash <> dg. When None: No restriction. | *) |
get operationtypedelete_options =Cache_aux.delete_options= {
|
mutable opt_strictlock : |
(* | Forces that the entry is even
scheduled for deletion if it does not exist. Unless
opt_undelete is given, a set operation cannot be successful
for the key while the entry is in the delete queue, i.e. the
key is locked until the deletion is really conducted. | *) |
|
mutable opt_delifolderthan : |
(* | When Some t: It is required
that e_modification < t in order to schedule an entry for
deletion. When None: no such requirement. | *) |
|
mutable opt_delifmd5 : |
(* | When Some dg: It is required
that e_value_hash = dg in order to schedule an entry for
deletion. When None: no such requirement. | *) |
|
mutable opt_delifnotmd5 : |
(* | When Some dg: It is required
that e_value_hash <> dg in order to schedule an entry for
deletion. When None: no such requirement. | *) |
delete operationtypeconfig =Cache_aux.config= {
|
mutable max_size : |
(* | The maximum size in bytes | *) |
|
mutable save_cache_period : |
(* | Save the cache to disk every this number of seconds. 0 or negative number disables saving to disk entirely | *) |
|
mutable save_cache_speed : |
(* | How fast to save to disk in bytes per second. Setting this to a reasonable value increases the responsiveness of the cache server while a save operation is in progress. Setting to 0 means as fast as possible. | *) |
typestats =Cache_aux.stats= {
|
mutable num_entries : |
(* | The number of entries in the cache, including entries scheduled for deletion. | *) |
|
mutable num_bytes : |
(* | The size of the cache in bytes, excluding overhead space | *) |
|
mutable num_calls_get : |
(* | The number of get calls | *) |
|
mutable num_calls_set : |
(* | The number of set calls | *) |
|
mutable num_calls_delete : |
(* | The number of delete calls | *) |
|
mutable num_hits : |
(* | The number of get calls
returning `Found. | *) |
|
mutable counters_reset_on : |
(* | When the counters were last reset | *) |
type'aasync_reply =(unit -> 'a) -> unit
let process_result get_result =
try
let result = get_result() in (* May raise exception *)
...
with error -> ...
exception Server_not_alive
false for the
is_alive test.class type client_config =object..end
class type async_client =object..end
class type sync_client =object..end
val create_async_client : client_config ->
Unixqueue.event_system -> async_clientUnixqueue.run the event system in
order to conduct the requested operations.val create_sync_client : client_config -> sync_client