diff --git a/src/FSharp.Data.Adaptive/AdaptifyHelpers.fs b/src/FSharp.Data.Adaptive/AdaptifyHelpers.fs index 47dc99f..b1244f8 100644 --- a/src/FSharp.Data.Adaptive/AdaptifyHelpers.fs +++ b/src/FSharp.Data.Adaptive/AdaptifyHelpers.fs @@ -38,7 +38,7 @@ type ChangeableModelMap<'K, 'V, 'C, 'A>(map : HashMap<'K, 'V>, init : 'V -> 'C, | Remove -> struct (ValueNone, ValueNone) - let s, ops = HashMap.ApplyDelta(history.State, HashMapDelta.toHashMap ops, apply) + let struct(s, ops) = HashMap.ApplyDeltaV(history.State, HashMapDelta.toHashMap ops, apply) history.PerformUnsafe(s, HashMapDelta.ofHashMap ops) |> ignore member x.GetReader() = diff --git a/src/FSharp.Data.Adaptive/AdaptiveHashSet/AdaptiveHashSet.fs b/src/FSharp.Data.Adaptive/AdaptiveHashSet/AdaptiveHashSet.fs index 1a9e65b..463a40c 100644 --- a/src/FSharp.Data.Adaptive/AdaptiveHashSet/AdaptiveHashSet.fs +++ b/src/FSharp.Data.Adaptive/AdaptiveHashSet/AdaptiveHashSet.fs @@ -652,7 +652,7 @@ module AdaptiveHashSetImplementation = struct (outRef, outDelta) - let newState, delta = HashMap.ApplyDelta(state, changes, apply) + let struct(newState, delta) = HashMap.ApplyDeltaV(state, changes, apply) state <- newState HashSetDelta.ofHashMap delta @@ -700,7 +700,7 @@ module AdaptiveHashSetImplementation = struct (outRef, outDelta) - let newState, delta = HashMap.ApplyDelta(state, changes, apply) + let struct(newState, delta) = HashMap.ApplyDeltaV(state, changes, apply) state <- newState HashSetDelta.ofHashMap delta @@ -748,7 +748,7 @@ module AdaptiveHashSetImplementation = struct (outRef, outDelta) - let newState, delta = HashMap.ApplyDelta(state, changes, apply) + let struct(newState, delta) = HashMap.ApplyDeltaV(state, changes, apply) state <- newState HashSetDelta.ofHashMap delta diff --git a/src/FSharp.Data.Adaptive/Datastructures/HashCollections.fs b/src/FSharp.Data.Adaptive/Datastructures/HashCollections.fs index acb6123..ebded78 100644 --- a/src/FSharp.Data.Adaptive/Datastructures/HashCollections.fs +++ b/src/FSharp.Data.Adaptive/Datastructures/HashCollections.fs @@ -3846,6 +3846,14 @@ and [(a.Comparer, state) let delta = HashMap<'K, 'U>(a.Comparer, delta) state, delta + + [] + static member ApplyDeltaV(a : HashMap<'K, 'V>, b : HashMap<'K, 'T>, apply : 'K -> voption<'V> -> 'T -> struct(voption<'V> * voption<'U>)) = + let state = a.Root + let struct(delta, state) = MapNode.applyDelta a.Comparer (OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt apply) state b.Root + let state = HashMap<'K, 'V>(a.Comparer, state) + let delta = HashMap<'K, 'U>(a.Comparer, delta) + struct(state, delta) [] member x.Choose2V(other : HashMap<'K, 'T>, mapping : 'K -> voption<'V> -> voption<'T> -> voption<'U>) = diff --git a/src/FSharp.Data.Adaptive/Traceable/CountingHashSet.fs b/src/FSharp.Data.Adaptive/Traceable/CountingHashSet.fs index a9777b5..071e528 100644 --- a/src/FSharp.Data.Adaptive/Traceable/CountingHashSet.fs +++ b/src/FSharp.Data.Adaptive/Traceable/CountingHashSet.fs @@ -45,7 +45,7 @@ type CountingHashSet<'T>(store : HashMap<'T, int>) = { tmonoid = HashSetDelta.monoid tempty = CountingHashSet<'T>(HashMap.empty) - tapplyDelta = fun s d -> s.ApplyDeltaNoRefCount d + tapplyDelta = fun s d -> s.ApplyDeltaNoRefCountV d tcomputeDelta = fun l r -> l.ComputeDelta r tprune = None tsize = fun s -> s.Count @@ -213,8 +213,8 @@ type CountingHashSet<'T>(store : HashMap<'T, int>) = let mutable res = HashMap<'B, int>.Empty for (k,ro) in store do let r = mapping k - let rr, _ = - HashMap<'B, int>.ApplyDelta(res, r.Store, fun _ oldRef delta -> + let struct(rr, _) = + HashMap<'B, int>.ApplyDeltaV(res, r.Store, fun _ oldRef delta -> let oldRef = match oldRef with | ValueSome o -> o | ValueNone -> 0 struct (ValueSome (oldRef + ro * delta), ValueNone) ) @@ -309,7 +309,7 @@ type CountingHashSet<'T>(store : HashMap<'T, int>) = struct(value, delta) - let s, d = HashMap.ApplyDelta(store, deltas.Store, apply) + let struct(s, d) = HashMap.ApplyDeltaV(store, deltas.Store, apply) CountingHashSet s, HashSetDelta d @@ -333,9 +333,32 @@ type CountingHashSet<'T>(store : HashMap<'T, int>) = struct(value, delta) - let s, d = HashMap.ApplyDelta(store, deltas.Store, apply) + let struct(s, d) = HashMap.ApplyDeltaV(store, deltas.Store, apply) CountingHashSet s, HashSetDelta d + /// Integrates the given delta into the set, returns a new set and the effective deltas. + member x.ApplyDeltaNoRefCountV (deltas : HashSetDelta<'T>) = + let apply (_k : 'T) (o : voption) (d : int) = + let o = match o with | ValueSome _ -> 1 | ValueNone -> 0 + let n = + if d > 0 then 1 + elif d < 0 then 0 + else o + + let delta = + if o = 0 && n > 0 then ValueSome 1 + elif o > 0 && n = 0 then ValueSome -1 + else ValueNone + + let value = + if n <= 0 then ValueNone + else ValueSome n + + struct(value, delta) + + let struct(s, d) = HashMap.ApplyDeltaV(store, deltas.Store, apply) + struct(CountingHashSet s, HashSetDelta d) + /// Compares two sets. static member internal Compare(l : CountingHashSet<'T>, r : CountingHashSet<'T>) = let i = l.Intersect r @@ -511,6 +534,10 @@ module CountingHashSet = /// Integrates the given delta into the set without ref-counting, returns a new set and the effective deltas. let inline applyDeltaNoRefCount (set : CountingHashSet<'T>) (delta : HashSetDelta<'T>) = set.ApplyDeltaNoRefCount delta + + /// Integrates the given delta into the set without ref-counting, returns a new set and the effective deltas. + let inline applyDeltaNoRefCountV (set : CountingHashSet<'T>) (delta : HashSetDelta<'T>) = + set.ApplyDeltaNoRefCountV delta /// Compares two sets. let internal compare (l : CountingHashSet<'T>) (r : CountingHashSet<'T>) =