Stateful.PoolA pool of previously generated values. Not thread-safe.
Rules can add to it and draw from it, so a rule can use values that another rule produced rather than a new drawn value.
Create one with create and populate it with add. To draw from the pool, use the following generators:
values_reusable: drawing from it returns a value in the pool without removing it.values_consumed: drawing from it removes a value from the pool and returns it.Example: a resource allocator. The alloc rule creates a new handle and deposits it in the pool. The free rule draws one of those handles back out and releases it. Without a pool, free would have no way to name a handle that a previous alloc actually created. It could only draw an arbitrary integer, most of which name no live resource.
type state =
{ mutable live : int list
; handles : int Stateful.Pool.t
}
let alloc =
Stateful.Rule.create
~name:"alloc"
~step:(fun tc state ->
let h = fresh_handle () in
Stateful.Pool.add state.handles tc h;
state.live <- h :: state.live)
()
;;
let free =
Stateful.Rule.create
~name:"free"
~step:(fun tc state ->
(* draws a handle a prior [alloc] put in the pool *)
let h = draw_silent tc (Stateful.Pool.values_consumed state.handles) in
release h;
state.live <- List.filter (fun x -> x <> h) state.live)
()
;;Creates an empty pool. Pools are tied to a test case. Do not reuse one across test cases. Drawn mutable values are shared by default. Pass a copying function for independent mutable values. Consumed draws return the stored value directly. clone must not call back into the same pool.
add pool tc value records value in pool.
let n = draw tc (integers ~min_value:0 ~max_value:100 ()) in
Stateful.Pool.add pool tc nval size : _ t -> intReturns the number of values in the pool.
assume tc (Stateful.Pool.size pool > 0)val values_reusable : 'a t -> ('a, Generators.unprintable) Generators.generatorDraws a value without removing it. A draw from an empty pool rejects the current rule.
let existing = draw_silent tc (Stateful.Pool.values_reusable pool)val values_consumed : 'a t -> ('a, Generators.unprintable) Generators.generatorDraws and removes a value. A draw from an empty pool rejects the current rule.
let taken = draw_silent tc (Stateful.Pool.values_consumed pool)