diff --git a/src/data/CCCache.ml b/src/data/CCCache.ml index fa75ff95..3437d493 100644 --- a/src/data/CCCache.ml +++ b/src/data/CCCache.ml @@ -26,18 +26,25 @@ type ('a,'b) t = { clear : unit -> unit; } +type ('a, 'b) callback = in_cache:bool -> 'a -> 'b -> unit + let clear c = c.clear () -let with_cache c f x = +let default_callback_ ~in_cache:_ _ _ = () + +let with_cache ?(cb=default_callback_) c f x = try - c.get x + let y = c.get x in + cb ~in_cache:true x y; + y with Not_found -> let y = f x in c.set x y; + cb ~in_cache:false x y; y -let with_cache_rec c f = - let rec f' x = with_cache c (f f') x in +let with_cache_rec ?(cb=default_callback_) c f = + let rec f' x = with_cache ~cb c (f f') x in f' (*$R diff --git a/src/data/CCCache.mli b/src/data/CCCache.mli index c22e469f..a5ccc2ce 100644 --- a/src/data/CCCache.mli +++ b/src/data/CCCache.mli @@ -31,13 +31,22 @@ type ('a, 'b) t val clear : (_,_) t -> unit (** Clear the content of the cache *) -val with_cache : ('a, 'b) t -> ('a -> 'b) -> 'a -> 'b +type ('a, 'b) callback = in_cache:bool -> 'a -> 'b -> unit +(** Type of the callback that is called once a cached value is found + or not. + Should never raise. + @param in_cache is [true] if the value was in cache, [false] + if the value was just produced. + @since NEXT_RELEASE *) + +val with_cache : ?cb:('a, 'b) callback -> ('a, 'b) t -> ('a -> 'b) -> 'a -> 'b (** [with_cache c f] behaves like [f], but caches calls to [f] in the cache [c]. It always returns the same value as [f x], if [f x] returns, or raise the same exception. - However, [f] may not be called if [x] is in the cache. *) + However, [f] may not be called if [x] is in the cache. + @param cb called after the value is generated or retrieved *) -val with_cache_rec : ('a,'b) t -> (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b +val with_cache_rec : ?cb:('a, 'b) callback -> ('a,'b) t -> (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b (** [with_cache_rec c f] is a function that first, applies [f] to some [f' = fix f], such that recursive calls to [f'] are cached in [c]. It is similar to {!with_cache} but with a function that takes as @@ -52,6 +61,7 @@ val with_cache_rec : ('a,'b) t -> (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b fib 70;; ]} + @param cb called after the value is generated or retrieved *) val size : (_,_) t -> int