Module Incr_map
include Incr_map__.Incr_map_intf.Incr_map
val of_set : (('k, 'cmp) Core_kernel.Set.t, 'w) Incremental.t -> (('k, unit, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
val filter_mapi : ?data_equal:('v1 -> 'v1 -> bool) -> (('k, 'v1, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> f:(key:'k -> data:'v1 -> 'v2 option) -> (('k, 'v2, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
val mapi : ?data_equal:('v1 -> 'v1 -> bool) -> (('k, 'v1, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> f:(key:'k -> data:'v1 -> 'v2) -> (('k, 'v2, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
val filter_mapi' : ?cutoff:'v1 Incremental.Cutoff.t -> ?data_equal:('v1 -> 'v1 -> bool) -> (('k, 'v1, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> f:(key:'k -> data:('v1, 'w) Incremental.t -> ('v2 option, 'w) Incremental.t) -> (('k, 'v2, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
val mapi' : ?cutoff:'v1 Incremental.Cutoff.t -> ?data_equal:('v1 -> 'v1 -> bool) -> (('k, 'v1, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> f:(key:'k -> data:('v1, 'w) Incremental.t -> ('v2, 'w) Incremental.t) -> (('k, 'v2, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
val unordered_fold : ?data_equal:('v -> 'v -> bool) -> ?update:(key:'k -> old_data:'v -> new_data:'v -> 'acc -> 'acc) -> ?specialized_initial:(init:'acc -> ('k, 'v, 'cmp) Core_kernel.Map.t -> 'acc) -> (('k, 'v, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> init:'acc -> add:(key:'k -> data:'v -> 'acc -> 'acc) -> remove:(key:'k -> data:'v -> 'acc -> 'acc) -> ('acc, 'w) Incremental.t
unordered_fold i ~init ~add ~remove
constructs a more incremental version of:let%map m = i in Map.fold m ~init ~f:add
assuming that
remove
is the inverse ofadd
, and that the operations for different keys can be performed in any order. Note thatdata_equal
defaults tophys_equal
, but a more precise equality can be provided instead.When the data for a key updates, by default
remove
is called on the old data and thenadd
is called on the new data.update
provides an alternative single function to call each time a key's data updates, and can be used to improve efficiency.For the initial computation, by default
add
is called on all the elements in the map. As this can be inefficient,specialized_initial
can be provided to perform the computation in a more effective way.
val merge : ?data_equal_left:('v1 -> 'v1 -> bool) -> ?data_equal_right:('v2 -> 'v2 -> bool) -> (('k, 'v1, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> (('k, 'v2, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> f:(key:'k -> [ `Left of 'v1 | `Right of 'v2 | `Both of 'v1 * 'v2 ] -> 'v3 option) -> (('k, 'v3, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
Like
merge
inBase.Map.merge
. Note thatf
is called at most once per key in any given stabilization.
val flatten : 'w Incremental.State.t -> ('k, ('v, 'w) Incremental.t, 'cmp) Core_kernel.Map.t -> (('k, 'v, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
This is the "easy" version of
join
val join : (('k, ('v, 'w) Incremental.t, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> (('k, 'v, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
The non-incremental semantics of this function is the identity function. Its purpose is to collapse the extra level of incrementality at the level of the data of the map.
val separate : (('k, 'v, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> data_equal:('v -> 'v -> bool) -> (('k, ('v, 'w) Incremental.t, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
val keys : (('k, 'v, 'c) Core_kernel.Map.t, 'w) Incremental.t -> (('k, 'c) Core_kernel.Set.t, 'w) Incremental.t
val subrange : ?data_equal:('v -> 'v -> bool) -> (('k, 'v, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> (('k Core_kernel.Maybe_bound.As_lower_bound.t * 'k Core_kernel.Maybe_bound.As_upper_bound.t) option, 'w) Incremental.t -> (('k, 'v, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
subrange map (min, max)
constructs an incremental submap that includes all of the keys and data frommap
betweenmin
andmax
, and none of the keys outside the range.subrange map None
is the empty map.range
beingNone
means no elements are chosen.Note that incremental changes have a runtime of O((k + m) log n) where k is the size of the changes to the underlying map and m is the size of the changes to the elements contained by the range. The complexity of the initial computation is the same as the incremental computation, with some simplification. k = 0 because we have not made any changes to the underlying map yet, and m equals the size of the range, because the initial range is empty.
val subrange_by_rank : ?data_equal:('v -> 'v -> bool) -> (('k, 'v, 'cmp) Core_kernel.Map.t, 'w) Incremental.t -> (int Core_kernel.Maybe_bound.As_lower_bound.t * int Core_kernel.Maybe_bound.As_upper_bound.t, 'w) Incremental.t -> (('k, 'v, 'cmp) Core_kernel.Map.t, 'w) Incremental.t
subrange_by_rank map (s, e)
constructs an incremental submap that includes (e-s+1) keys between s-th and e-th, inclusive.If s is greater or equal to map length, the result is empty. If e is greater or equal to map length, the result contains keys from s-th to the last one.
Raises for invalid indices - s < 0 or e < s.
Runtime of the initial computation is O(min(e, n-s) + log(n)), i.e. linear, but optimized for ranges close to beginning or end.
Runtime of the incremental computation is O(log(n) + k + (m+m') * log(n)) where:
- k is the size of the diff
- m is the total impact of map changes on the range, bounded by k (e.g. if we add 1001 keys and remove 1000 below s, then m = 1)
- m' = O( |new s - old s| + |new e - old e| ).
val index_by : (('inner_key, 'v, 'inner_cmp) Core_kernel.Map.t, 'w) Incremental.t -> comparator:('outer_key, 'outer_cmp) Core_kernel.Map.comparator -> index:('v -> 'outer_key option) -> (('outer_key, ('inner_key, 'v, 'inner_cmp) Core_kernel.Map.t, 'outer_cmp) Core_kernel.Map.t, 'w) Incremental.t
index_by map ~comparator ~index
constructs an incremental map-of-maps where each key-data pair of the input map is present in one (or none) of the inner maps.index
specifies the outer map key under which each original key-data pair is found.All of the resulting inner maps are guaranteed to be non-empty.
An all-at-once version of
index_by
would look like:let index_by map ~comparator ~index = Map.to_alist map |> List.filter_map ~f:(fun (key, data) -> match index data with | None -> None | Some index -> index, (key, data)) |> Map.of_alist_multi comparator |> Map.map ~f:(Map.of_alist_exn (Map.comparator_s map)) ;;
val unordered_fold_nested_maps : ?data_equal:('v -> 'v -> bool) -> ?update:(outer_key:'outer_key -> inner_key:'inner_key -> old_data:'v -> new_data:'v -> 'acc -> 'acc) -> (('outer_key, ('inner_key, 'v, 'inner_cmp) Core_kernel.Map.t, 'outer_cmp) Core_kernel.Map.t, 'w) Incremental.t -> init:'acc -> add:(outer_key:'outer_key -> inner_key:'inner_key -> data:'v -> 'acc -> 'acc) -> remove:(outer_key:'outer_key -> inner_key:'inner_key -> data:'v -> 'acc -> 'acc) -> ('acc, 'w) Incremental.t
val transpose : ?data_equal:('v -> 'v -> bool) -> ('k2, 'k2_cmp) Core_kernel.Map.comparator -> (('k1, ('k2, 'v, 'k2_cmp) Core_kernel.Map.t, 'k1_cmp) Core_kernel.Map.t, 'w) Incremental.t -> (('k2, ('k1, 'v, 'k1_cmp) Core_kernel.Map.t, 'k2_cmp) Core_kernel.Map.t, 'w) Incremental.t
module Lookup : sig ... end
('k, 'v) Lookup.t
provides a way to lookup keys in a map which uses symmetric diffs to trigger updates of the lookups.
module For_testing : sig ... end
module type S_gen = Incr_map__.Incr_map_intf.S_gen
module type S = sig ... end
module Make : functor (Incr : Incremental.S) -> S with type state_witness := Incr.state_witness and module Incr := Incr