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.tval 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.tval 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.tval 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.tval 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.tval 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.tunordered_fold i ~init ~add ~removeconstructs a more incremental version of:let%map m = i in Map.fold m ~init ~f:addassuming that
removeis the inverse ofadd, and that the operations for different keys can be performed in any order. Note thatdata_equaldefaults tophys_equal, but a more precise equality can be provided instead.When the data for a key updates, by default
removeis called on the old data and thenaddis called on the new data.updateprovides 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
addis called on all the elements in the map. As this can be inefficient,specialized_initialcan 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.tLike
mergeinBase.Map.merge. Note thatfis 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.tThis 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.tThe 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.tval keys : (('k, 'v, 'c) Core_kernel.Map.t, 'w) Incremental.t -> (('k, 'c) Core_kernel.Set.t, 'w) Incremental.tval 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.tsubrange map (min, max)constructs an incremental submap that includes all of the keys and data frommapbetweenminandmax, and none of the keys outside the range.subrange map Noneis the empty map.rangebeingNonemeans 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.tsubrange_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.tindex_by map ~comparator ~indexconstructs an incremental map-of-maps where each key-data pair of the input map is present in one (or none) of the inner maps.indexspecifies 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_bywould 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.tval 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.tprovides a way to lookup keys in a map which uses symmetric diffs to trigger updates of the lookups.
module For_testing : sig ... endmodule type S_gen = Incr_map__.Incr_map_intf.S_genmodule type S = sig ... endmodule Make : functor (Incr : Incremental.S) -> S with type state_witness := Incr.state_witness and module Incr := Incr