Skip to content

Commit eae4a56

Browse files
committed
refining batch operation
1 parent 1124556 commit eae4a56

2 files changed

Lines changed: 56 additions & 29 deletions

File tree

src/FSharp.Data.Adaptive/AdaptiveHashMap/AdaptiveHashMap.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ module AdaptiveHashMapImplementation =
821821
let mutable changes = HashMap.empty
822822
let setOps =
823823
(setOps, dirty)
824-
||> HashMap.fold(fun s k v ->
824+
||> HashMap.fold(fun s k _ ->
825825
match HashMap.tryFind k old with
826826
| Some v ->
827827
HashMap.add k v s
@@ -1416,7 +1416,7 @@ module AMap =
14161416
create (fun () -> MapAReader(map, mapping))
14171417

14181418
/// Adaptively applies the given mapping to all changes and reapplies mapping on dirty outputs
1419-
let batchRecalcDirty (mapping: HashMap<'K,'T1> -> HashMap<'K,aval<'T2>>) (map: amap<'K, 'T1>) =
1419+
let batchRecalcDirty (mapping: HashMap<'K, 'T1> -> HashMap<'K, aval<'T2>>) (map: amap<'K, 'T1>) =
14201420
if map.IsConstant then
14211421
let map = force map |> mapping
14221422
if map |> HashMap.forall (fun _ v -> v.IsConstant) then

src/Test/FSharp.Data.Adaptive.Tests/AMap.fs

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -643,36 +643,47 @@ let ``[AMap] mapA``() =
643643
res |> AMap.force |> should equal (HashMap.ofList ["A", 2; "B", 4; "C", 6])
644644

645645

646+
module AVal =
646647

647-
/// <summary>
648-
/// Calls a mapping function which creates additional dependencies to be tracked.
649-
/// </summary>
650-
let mapWithAdditionalDependenies (mapping: 'a -> 'b * #seq<#IAdaptiveValue>) (value: aval<'a>) : aval<'b> =
651-
let mutable lastDeps = HashSet.empty
648+
/// <summary>
649+
/// Calls a mapping function which creates additional dependencies to be tracked.
650+
/// </summary>
651+
let mapWithAdditionalDependenies (mapping: 'a -> 'b * #seq<#IAdaptiveValue>) (value: aval<'a>) : aval<'b> =
652+
let mutable lastDeps = HashSet.empty
652653

653-
{ new AVal.AbstractVal<'b>() with
654-
member x.Compute(token: AdaptiveToken) =
655-
let input = value.GetValue token
654+
{ new AVal.AbstractVal<'b>() with
655+
member x.Compute(token: AdaptiveToken) =
656+
let input = value.GetValue token
656657

657-
// re-evaluate the mapping based on the (possibly new input)
658-
let result, deps = mapping input
658+
// re-evaluate the mapping based on the (possibly new input)
659+
let result, deps = mapping input
659660

660-
// compute the change in the additional dependencies and adjust the graph accordingly
661-
let newDeps = HashSet.ofSeq deps
661+
// compute the change in the additional dependencies and adjust the graph accordingly
662+
let newDeps = HashSet.ofSeq deps
662663

663-
for op in HashSet.computeDelta lastDeps newDeps do
664-
match op with
665-
| Add(_, d) ->
666-
// the new dependency needs to be evaluated with our token, s.t. we depend on it in the future
667-
d.GetValueUntyped token |> ignore
668-
| Rem(_, d) ->
669-
// we no longer need to depend on the old dependency so we can remove ourselves from its outputs
670-
lock d.Outputs (fun () -> d.Outputs.Remove x) |> ignore
664+
for op in HashSet.computeDelta lastDeps newDeps do
665+
match op with
666+
| Add(_, d) ->
667+
// the new dependency needs to be evaluated with our token, s.t. we depend on it in the future
668+
d.GetValueUntyped token |> ignore
669+
| Rem(_, d) ->
670+
// we no longer need to depend on the old dependency so we can remove ourselves from its outputs
671+
lock d.Outputs (fun () -> d.Outputs.Remove x) |> ignore
671672

672-
lastDeps <- newDeps
673+
lastDeps <- newDeps
674+
675+
result }
676+
:> aval<_>
677+
678+
module AMap =
679+
let mapWithAdditionalDependenies (mapping: HashMap<'K, 'T1> -> HashMap<'K, 'T2 * #seq<#IAdaptiveValue>>) (map: amap<'K, 'T1>) =
680+
let mapping =
681+
mapping
682+
>> HashMap.map(fun _ v ->
683+
AVal.constant v |> AVal.mapWithAdditionalDependenies (id)
684+
)
685+
AMap.batchRecalcDirty mapping map
673686

674-
result }
675-
:> aval<_>
676687

677688
[<Test>]
678689
let ``[AMap] batchRecalcDirty``() =
@@ -687,7 +698,7 @@ let ``[AMap] batchRecalcDirty``() =
687698
let file3Cval = cval 3
688699
let file3DepCval = cval 1
689700

690-
let m = Map [file1, file1DepCval; file2, file2DepCval; file3, file3DepCval]
701+
let dependencies = Map [file1, file1DepCval; file2, file2DepCval; file3, file3DepCval]
691702

692703
let projs =
693704
[
@@ -701,11 +712,11 @@ let ``[AMap] batchRecalcDirty``() =
701712
let mutable lastBatch = Unchecked.defaultof<_>
702713
let res =
703714
projs
704-
|> AMap.batchRecalcDirty(fun d ->
715+
|> AMap.mapWithAdditionalDependenies(fun d ->
705716
lastBatch <- d
706717
HashMap.ofList [
707718
for k,v in d do
708-
k, (AVal.constant <| Guid.NewGuid()) |> mapWithAdditionalDependenies(fun a -> a, [m.[k]])
719+
k, (Guid.NewGuid(), [dependencies.[k]])
709720
]
710721
)
711722
let firstResult = res |> AMap.force
@@ -739,14 +750,30 @@ let ``[AMap] batchRecalcDirty``() =
739750
lastBatch |> should haveCount 1
740751

741752
thirdResult.[file1] |> should not' (equal fourthResult.[file1])
753+
thirdResult.[file2] |> should equal fourthResult.[file2]
754+
thirdResult.[file3] |> should equal fourthResult.[file3]
742755

743756
transact(fun () ->
744757
file1DepCval.Value <- file1DepCval.Value + 1
745-
file1Cval.Value <- file1Cval.Value)
758+
file1Cval.Value <- file1Cval.Value + 1)
746759

747760
let fifthResult = res |> AMap.force
748761
lastBatch |> should haveCount 1
749762

750763
fourthResult.[file1] |> should not' (equal fifthResult.[file1])
764+
fourthResult.[file2] |> should equal fifthResult.[file2]
765+
fourthResult.[file3] |> should equal fifthResult.[file3]
766+
767+
768+
transact(fun () ->
769+
file2DepCval.Value <- file2DepCval.Value + 1
770+
file3Cval.Value <- file3Cval.Value + 1)
771+
772+
let sixthResult = res |> AMap.force
773+
lastBatch |> should haveCount 2
774+
775+
fifthResult.[file1] |> should equal sixthResult.[file1]
776+
fifthResult.[file2] |> should not' (equal sixthResult.[file2])
777+
fifthResult.[file3] |> should not' (equal sixthResult.[file3])
751778

752779
()

0 commit comments

Comments
 (0)