diff --git a/src/lib_stdlib/ring.ml b/src/lib_stdlib/ring.ml index 5072f06eb..f57d98f33 100644 --- a/src/lib_stdlib/ring.ml +++ b/src/lib_stdlib/ring.ml @@ -30,6 +30,16 @@ let add r v = s.pos + 1 ; s.data.(s.pos mod Array.length s.data) <- v +let add_and_return_erased r v = + let replaced = match !r with + | Empty _ -> None + | Inited s -> + if s.pos >= Array.length s.data - 1 then + Some (s.data.(s.pos mod Array.length s.data)) + else + None in + add r v ; replaced + let add_list r l = List.iter (add r) l let last r = diff --git a/src/lib_stdlib/ring.mli b/src/lib_stdlib/ring.mli index 42f1e4fef..e67670f19 100644 --- a/src/lib_stdlib/ring.mli +++ b/src/lib_stdlib/ring.mli @@ -9,12 +9,34 @@ (** Imperative Ring Buffer *) +(** An imperative ring buffer: a mutable structure that holds at most + a fixed number of values of a same type. Values are never removed, + once the limit is reached, adding a value replaces the oldest one + in the ring buffer. *) type 'a t + +(** Allocates a ring buffer for a given number of values. *) val create : int -> 'a t + +(** Adds a value, dropping the oldest present one if full. *) val add : 'a t -> 'a -> unit + +(** Same as {!add}, but returns the dropped value if any. *) +val add_and_return_erased : 'a t -> 'a -> 'a option + +(** Adds the values of a list, in order. *) val add_list : 'a t -> 'a list -> unit + +(** Retrieves the most recent value, or [None] when empty. *) val last : 'a t -> 'a option + exception Empty + +(** Same as {!last}, but raises {!Empty} when empty. *) val last_exn : 'a t -> 'a + +(** Iterates over the elements, oldest to newest. *) val fold : 'a t -> init:'b -> f:('b -> 'a -> 'b) -> 'b + +(** Retrieves the elements as a list, oldest first.. *) val elements : 'a t -> 'a list