Module Tjr_lru_cache.Mt_intf

Main mt (multithreaded lru) types; don't open outside this lib

module Mt_callback_ops : sig ... end

The LRU operations, expressed using callbacks. This is somehow more primitive than the monadic map interface. This interface is converted into the typical monadic "syncable map" interface using events.

type ('k, 'v, 't) mt_callback_ops = ('k'v't) Mt_callback_ops.mt_callback_ops
module Mt_ops : sig ... end

The main LRU operations, with a non-callback interface.

include Mt_ops
type ('k, 'v, 't) mt_ops = {
mt_find : 'k -> ('v option't) Tjr_monad.m;
mt_insert : 'k -> 'v -> (unit, 't) Tjr_monad.m;
mt_delete : 'k -> (unit, 't) Tjr_monad.m;
mt_sync_key : 'k -> (unit, 't) Tjr_monad.m;
mt_sync_all_keys : unit -> (unit, 't) Tjr_monad.m;
}

The interface provided by the multithreaded LRU; provides blocking/non-blocking operations, and persist now/persist later flags.

These are the operations supported by the LRU.

NOTE this interface doesn't allow "transaction" operations (multiple ops, which commit atomically). This is sufficient for ImpFS - the kv store is pointwise syncable not transactional. However, since the lower level does support transactional operations, it seems strange to limit the functionality here.

NOTE all calls are blocking; for non-blocking calls, launch an async light-weight thread.

type ('v, 't) blocked_thread = 'v option -> (unit, 't) Tjr_monad.m

We want to store "blocked threads" in a map, indexed by key; we use a polymap; the threads are of type 'v -> ('a,'t) m; the 'a return type can just be unit, since a thread can launch some other thread to eventually return 'a

module Mt_state : sig ... end
include Mt_state
type ('k, 'v, 'lru, 't_map, 't) mt_state = {
lru_state_im : 'lru Im_intf.lru_state_im;
blocked_threads : 't_map;
blocked_threads_ops : ('k('v't) blocked_thread list't_map) Tjr_lib.Tjr_map.map_ops;
}

The state consists of:

  • the cache state
  • a map from k to a wait list (of threads that are waiting for a find operation to complete at the disk layer)

NOTE t_map is "thread map"

val mt_initial_state : lru_state_im:'lru Im_intf.lru_state_im -> k_cmp:('k -> 'k -> int) -> ('k'v'lru('k('v't) blocked_thread list, unit) Tjr_lib.Tjr_map.map't) mt_state
module Lru_msg : sig ... end
include Lru_msg
type ('k, 'v, 't) lru_msg =
| Insert of 'k * 'v * unit -> (unit, 't) Tjr_monad.m
| Delete of 'k * unit -> (unit, 't) Tjr_monad.m
| Find of 'k * 'v option -> (unit, 't) Tjr_monad.m
| Evictees of ('k'v) Tjr_fs_shared.kvop list
| Sync of unit -> (unit, 't) Tjr_monad.m

The type of messages that we send to the lower level. NOTE that the callbacks are needed to implement the "persist now" mode, i.e., to inform the caller when the operation has committed to disk.

type lru_params = Im_intf.lru_params_im
module Lru_factory : sig ... end
include Lru_factory
type ('k, 'v, 'lru, 't) lru_factory = < empty : lru_params -> 'lru; make_ops : with_state:('lru't) Tjr_monad.with_state -> to_lower:(('k'v't) lru_msg -> (unit, 't) Tjr_monad.m) -> ('k'v't) mt_ops; >

This is the eventual interface provided by Make. NOTE this type is unreadable in odoc