Module type Sigs.CACHE_MAP
type 'a t
The type of Lwt-friendly caches holding bindings from
key
to'a
.Instead of adding values directly to this cache, you can add promises (using
replace
) or, more interestingly, atomically (a) querying for an already bound promises or (b) generating a new one if needed. This helps avoid race conditions.A promise is removed from the cache if:
- The cache overflows (in which case, the removal of the promise depends on the policies of the cache, see
Ringo.CACHE_MAP
for details). - The promise is still held by the cache when
- the cache is
clear
ed (in which case the promise is canceled). - it is
replace
d by another one (in which case it is canceled). - it is explicitly
remove
d (in which case it is canceled). - it is rejected.
If a promise is not held by the cache, then it cannot be removed from the cache and it will not be canceled by the cache.
- The cache overflows (in which case, the removal of the promise depends on the policies of the cache, see
val create : int -> 'a t
create n
creates a cache with a size-bound ofn
. Remember that the size-bound is not upheld strictly by all caches.
val replace : 'a t -> key -> 'a Lwt.t -> unit
replace c k p
binds the keyk
top
in the cachec
.Note that when a promise is rejected, it is automatically removed from the cache.
Note that, for the purpose of determining if an inserted binding is supernumerary, and thus if it pushes another binding out of the cache, an unresolved binding counts fully.
val fold : (key -> 'a -> 'b -> 'b Lwt.t) -> 'a t -> 'b -> 'b Lwt.t
fold f c init
folds the functionf
and valueinit
over the bindings ofc
. More specifically, it takes the bindings that are inc
at the moment of the call (inserting a binding whilst thefold
promise is pending has no effect on thefold
promise) and traverses them sequentially: it waits for one step of the folding to resolve before starting the next one. Promises that are rejected are not visible by thisfold
operation: they are simply ignored.E.g., you can run
fold (fun _ _ () -> Lwt.return_unit) ()
to wait for all currently-held bindings to resolve.Note that for some caches, this function may fold over a subset of the bindings of
c
. Specifically, on caches with aWeak
overflow policy, only the strongly-held elements are folded over.
val fold_promises : (key -> 'a Lwt.t -> 'b -> 'b) -> 'a t -> 'b -> 'b
fold_promises f c init
folds the functionf
and valueinit
over the promises of bindings ofc
. More specifically, it takes the bindings that are inc
at the moment of the call (inserting a binding whilst thefold
promise is pending has no effect on thefold
promise) and traverses them all immediately. The function that folds over the bindings is given the promises (rather than the values these promises resolve to).E.g., You can count the number of resolved/pending like so:
fold_promises (fun _ p (sleeping, not_sleeping) -> match Lwt.state p with | Sleep -> (sleeping + 1, not_sleeping) | Return _ -> (sleeping, not_sleeping + 1) | Fail _ -> assert false (* these are removed from the cache *) ) c (0, 0)
Note that for some caches, this function may fold over a subset of the bindings of
c
. Specifically, on caches with aWeak
overflow policy, only the strongly-held elements are folded over.
val find_opt : 'a t -> key -> 'a Lwt.t option
find_opt c k
isNone
ifk
is not bound inc
. Otherwise it isSome p
wherep
is bound tok
inc
.Note that the in some caches, this may have a side effect on the
k
-to-v
binding. Specifically, in some caches, it might make it less likely to be removed when supernumerary bindings are inserted.
val find_or_replace : 'a t -> key -> (key -> 'a Lwt.t) -> 'a Lwt.t
find_or_replace c k f
behaves likesfind_opt c k
ifk
is bound inc
, and it behaves likereplace c k f
otherwise. Either way, it returns the promise that resolves to the value associated tok
whichever behaviorfind_or_replace
resembled.
val remove : 'a t -> key -> unit
remove c k
removes the binding fromk
inc
. Ifk
is not bound inc
, it does nothing. If the binding is not resolved yet, it also cancels the promise.Note that in some caches, removed bindings can still count towards the size bound for some time.
val length : 'a t -> int
length c
is the number of bindings held byc
.
val capacity : 'a t -> int
capacity c
is the number of bindingsc
can hold:capacity (create n) = n
val clear : 'a t -> unit
clear c
removes all bindings fromc
. It also cancels unresolved bindings.