From 4924bc5bdc89ac4d186f80572f78caef937651ec Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 10 Jul 2024 15:21:36 +0200 Subject: [PATCH] [Tests] Remove output spam from unit tests --- .../Aardvark.Base.FSharp.Tests/CachesTest.fs | 349 +++++++------- .../Datastructures/MapExt.fs | 81 ++-- .../Datastructures/OrderMaintenanceTrie.fs | 426 +++++++++--------- .../Datastructures/SortedSetExt.fs | 1 - .../RangesBoxes/BoxTests.cs | 2 - 5 files changed, 415 insertions(+), 444 deletions(-) diff --git a/src/Tests/Aardvark.Base.FSharp.Tests/CachesTest.fs b/src/Tests/Aardvark.Base.FSharp.Tests/CachesTest.fs index 8582d8950..2a5820106 100644 --- a/src/Tests/Aardvark.Base.FSharp.Tests/CachesTest.fs +++ b/src/Tests/Aardvark.Base.FSharp.Tests/CachesTest.fs @@ -1,4 +1,4 @@ -module Caches +namespace Aardvark.Base.FSharp.Tests open System open NUnit.Framework @@ -10,283 +10,266 @@ open System.Threading open System.Reflection open System.Collections -type RuntimeObject(name : string) = +module Caches = + type RuntimeObject(name : string) = - static let mutable objCount = 0 + static let mutable objCount = 0 - let data = Array.zeroCreate 100000 + let data = Array.zeroCreate 100000 - let number = Interlocked.Increment &objCount + let number = Interlocked.Increment &objCount - do - Log.line "Create %s %d" name number + static member ObjCount = objCount - static member ObjCount = objCount + member x.Name + with get() = name - member x.Name - with get() = name + override x.Finalize() = + Interlocked.Decrement &objCount |> ignore - override x.Finalize() = - Interlocked.Decrement &objCount |> ignore - Log.line "Collect %s %d" name number + override x.ToString() = name - override x.ToString() = name + type ResultObject<'a, 'b>(a : 'a, b : 'b) = - type ResultObject<'a, 'b>(a : 'a, b : 'b) = + static let mutable resCount = 0 - static let mutable resCount = 0 + do Interlocked.Increment &resCount |> ignore - do - let resCnt = Interlocked.Increment &resCount - Log.line "Create Result %d" resCnt + static member ResCount = resCount - static member ResCount = resCount + member x.A + with get() = a + member x.B + with get() = b - member x.A - with get() = a - member x.B - with get() = b + override x.ToString() = + a.ToString() + b.ToString() - override x.ToString() = - a.ToString() + b.ToString() + [] + let ``[Caches] BinaryCache forward``() = -[] -let ``[Caches] BinaryCache forward``() = + let a = "hugo" - let a = "hugo" + let mutable compCount = 0 + let cache = BinaryCache<_, _, _>((fun a b -> + let res = a.ToString() + b.ToString() + compCount <- compCount + 1 + res)) - let mutable compCount = 0 - let cache = BinaryCache<_, _, _>((fun a b -> - let res = a.ToString() + b.ToString() - compCount <- compCount + 1 - Log.line "result created" - res)) + let sw = Stopwatch.StartNew() + let mutable i = 0 + let random = Random(123) + let mutable temp = RuntimeObject(sprintf "run-%i" i) - let sw = Stopwatch.StartNew() - let mutable i = 0 - let random = Random(123) - let mutable temp = RuntimeObject(sprintf "run-%i" i) + while sw.Elapsed.TotalSeconds < 10.0 do - while sw.Elapsed.TotalSeconds < 10.0 do + let resCount = + if random.NextDouble() < 0.1 || i = 0 then + temp <- RuntimeObject(sprintf "run-%i" i) + compCount + 1 + else + compCount - let resCount = - if random.NextDouble() < 0.1 || i = 0 then - temp <- RuntimeObject(sprintf "run-%i" i) - compCount + 1 - else - compCount + let result = cache.Invoke(a, temp) - let result = cache.Invoke(a, temp) + if resCount <> compCount then + failwith "caching failed" - if resCount <> compCount then - failwith "caching failed" + i <- i + 1 - Log.line "created: %A" result - - i <- i + 1 + System.GC.Collect(3) + System.GC.WaitForFullGCComplete() |> ignore System.GC.Collect(3) System.GC.WaitForFullGCComplete() |> ignore - System.GC.Collect(3) - System.GC.WaitForFullGCComplete() |> ignore - - Log.line "RuntimeObject Count=%d" RuntimeObject.ObjCount + Log.line "RuntimeObject Count=%d" RuntimeObject.ObjCount - if RuntimeObject.ObjCount > 100 then - failwith "leak" + if RuntimeObject.ObjCount > 100 then + failwith "leak" -[] -let ``[Caches] BinaryCache backward``() = + [] + let ``[Caches] BinaryCache backward``() = - let a = "hugo" + let a = "hugo" - let mutable compCount = 0 - let cache = BinaryCache<_, _, _>((fun a b -> - let res = a.ToString() + b.ToString() - compCount <- compCount + 1 - Log.line "result created: %s" res - res)) + let mutable compCount = 0 + let cache = BinaryCache<_, _, _>((fun a b -> + let res = a.ToString() + b.ToString() + compCount <- compCount + 1 + res)) - let sw = Stopwatch.StartNew() - let mutable i = 0 - let random = Random(123) - let mutable temp = RuntimeObject(sprintf "run-%i" i) + let sw = Stopwatch.StartNew() + let mutable i = 0 + let random = Random(123) + let mutable temp = RuntimeObject(sprintf "run-%i" i) - while sw.Elapsed.TotalSeconds < 10.0 do + while sw.Elapsed.TotalSeconds < 10.0 do - let resCount = - if random.NextDouble() < 0.1 || i = 0 then - temp <- RuntimeObject(sprintf "run-%i" i) - compCount + 1 - else - compCount + let resCount = + if random.NextDouble() < 0.1 || i = 0 then + temp <- RuntimeObject(sprintf "run-%i" i) + compCount + 1 + else + compCount - let result = cache.Invoke(temp, a) + let result = cache.Invoke(temp, a) - if resCount <> compCount then - failwith "caching failed" + if resCount <> compCount then + failwith "caching failed" - Log.line "created: %A" result + i <- i + 1 - i <- i + 1 + System.GC.Collect(3) + System.GC.WaitForFullGCComplete() |> ignore System.GC.Collect(3) System.GC.WaitForFullGCComplete() |> ignore - System.GC.Collect(3) - System.GC.WaitForFullGCComplete() |> ignore - - Log.line "RuntimeObject Count=%d" RuntimeObject.ObjCount + Log.line "RuntimeObject Count=%d" RuntimeObject.ObjCount - if RuntimeObject.ObjCount > 100 then - failwith "leak" + if RuntimeObject.ObjCount > 100 then + failwith "leak" -[] -let ``[Caches] BinaryCache forward with ResultObject``() = + [] + let ``[Caches] BinaryCache forward with ResultObject``() = - let a = "hugo" + let a = "hugo" - let cache = BinaryCache<_, _, _>((fun a b -> ResultObject(a, b))) + let cache = BinaryCache<_, _, _>((fun a b -> ResultObject(a, b))) - let sw = Stopwatch.StartNew() - let mutable i = 0 + let sw = Stopwatch.StartNew() + let mutable i = 0 - let rnd = Random(123) - let mutable temp = Unchecked.defaultof<_> + let rnd = Random(123) + let mutable temp = Unchecked.defaultof<_> - while sw.Elapsed.TotalSeconds < 10.0 do + while sw.Elapsed.TotalSeconds < 10.0 do - let resCount = - if rnd.NextDouble() < 0.1 || i = 0 then - temp <- RuntimeObject(sprintf "run-%i" i) - ResultObject.ResCount + 1 - else - ResultObject.ResCount + let resCount = + if rnd.NextDouble() < 0.1 || i = 0 then + temp <- RuntimeObject(sprintf "run-%i" i) + ResultObject.ResCount + 1 + else + ResultObject.ResCount - let result = cache.Invoke(a, temp) + let result = cache.Invoke(a, temp) - if resCount <> ResultObject.ResCount then - failwith "cache not working" + if resCount <> ResultObject.ResCount then + failwith "cache not working" - Log.line "created: %A" result + i <- i + 1 - i <- i + 1 + System.GC.Collect(3) + System.GC.WaitForFullGCComplete() |> ignore System.GC.Collect(3) System.GC.WaitForFullGCComplete() |> ignore - System.GC.Collect(3) - System.GC.WaitForFullGCComplete() |> ignore + Log.line "RuntimeObject Count=%d" RuntimeObject.ObjCount - Log.line "RuntimeObject Count=%d" RuntimeObject.ObjCount + if RuntimeObject.ObjCount > 100 then + failwith "leak" - if RuntimeObject.ObjCount > 100 then - failwith "leak" + [] + let ``[Caches] BinaryCache backward with ResultObject``() = -[] -let ``[Caches] BinaryCache backward with ResultObject``() = + let a = "hugo" + let cache = BinaryCache<_, _, _>((fun a b -> ResultObject(a, b))) - let a = "hugo" - let cache = BinaryCache<_, _, _>((fun a b -> ResultObject(a, b))) + let sw = Stopwatch.StartNew() + let mutable i = 0 - let sw = Stopwatch.StartNew() - let mutable i = 0 + let rnd = Random(123) + let mutable temp = Unchecked.defaultof<_> - let rnd = Random(123) - let mutable temp = Unchecked.defaultof<_> + while sw.Elapsed.TotalSeconds < 10.0 do - while sw.Elapsed.TotalSeconds < 10.0 do + let resCount = + if rnd.NextDouble() < 0.1 || i = 0 then + temp <- RuntimeObject(sprintf "run-%i" i) + ResultObject.ResCount + 1 + else + ResultObject.ResCount - let resCount = - if rnd.NextDouble() < 0.1 || i = 0 then - temp <- RuntimeObject(sprintf "run-%i" i) - ResultObject.ResCount + 1 - else - ResultObject.ResCount + let result = cache.Invoke(temp, a) - let result = cache.Invoke(temp, a) + if resCount <> ResultObject.ResCount then + failwith "cache not working" - if resCount <> ResultObject.ResCount then - failwith "cache not working" + i <- i + 1 - Log.line "created: %A" result - - i <- i + 1 + System.GC.Collect(3) + System.GC.WaitForFullGCComplete() |> ignore System.GC.Collect(3) System.GC.WaitForFullGCComplete() |> ignore - System.GC.Collect(3) - System.GC.WaitForFullGCComplete() |> ignore - - Log.line "RuntimeObject Count=%d" RuntimeObject.ObjCount + Log.line "RuntimeObject Count=%d" RuntimeObject.ObjCount - if RuntimeObject.ObjCount > 100 then - failwith "leak" + if RuntimeObject.ObjCount > 100 then + failwith "leak" - let x = cache.Invoke(temp, a) - let y = cache.Invoke(temp, a) - if not (System.Object.ReferenceEquals(x,y)) then failwith "not caching" + let x = cache.Invoke(temp, a) + let y = cache.Invoke(temp, a) + if not (System.Object.ReferenceEquals(x,y)) then failwith "not caching" -[] -let ``[Caches] ConditionalWeakTable: input holding output``() = + [] + let ``[Caches] ConditionalWeakTable: input holding output``() = - let sw = Stopwatch.StartNew() - let mutable i = 0 - while sw.Elapsed.TotalSeconds < 10.0 do + let sw = Stopwatch.StartNew() + let mutable i = 0 + while sw.Elapsed.TotalSeconds < 10.0 do - let temp = RuntimeObject(sprintf "run-%i" i) + let temp = RuntimeObject(sprintf "run-%i" i) - let result = UnaryCache<_, _>(fun a -> a).Invoke temp + let result = UnaryCache<_, _>(fun a -> a).Invoke temp - Log.line "created: %A" result + i <- i + 1 - i <- i + 1 + System.GC.Collect(3) + System.GC.WaitForFullGCComplete() |> ignore System.GC.Collect(3) System.GC.WaitForFullGCComplete() |> ignore - System.GC.Collect(3) - System.GC.WaitForFullGCComplete() |> ignore - - Log.line "RuntimeObject Count=%d" RuntimeObject.ObjCount + Log.line "RuntimeObject Count=%d" RuntimeObject.ObjCount - if RuntimeObject.ObjCount > 100 then - failwith "leak" + if RuntimeObject.ObjCount > 100 then + failwith "leak" -[] -let ``[Caches] Introspection plugin cache``() = + [] + let ``[Caches] Introspection plugin cache``() = - // Don't want to make this type public just for a unit test, so we just use reflection? - let cacheType = typeof.GetNestedType("PluginCache", BindingFlags.Public ||| BindingFlags.NonPublic) + // Don't want to make this type public just for a unit test, so we just use reflection? + let cacheType = typeof.GetNestedType("PluginCache", BindingFlags.Public ||| BindingFlags.NonPublic) - let dataType = cacheType.GetNestedType("Data"); - let dataCtor = dataType.GetConstructor([| typeof; typeof |]) + let dataType = cacheType.GetNestedType("Data"); + let dataCtor = dataType.GetConstructor([| typeof; typeof |]) - let cacheCtor = cacheType.GetConstructor([||]) - let serialize = cacheType.GetMethod("Serialize", [| typeof |]) - let deserialize = cacheType.GetMethod("Deserialize", [| typeof |]) - let add = cacheType.GetMethod("Add", [| typeof; dataType |]) + let cacheCtor = cacheType.GetConstructor([||]) + let serialize = cacheType.GetMethod("Serialize", [| typeof |]) + let deserialize = cacheType.GetMethod("Deserialize", [| typeof |]) + let add = cacheType.GetMethod("Add", [| typeof; dataType |]) - let addEntry (path : string) (lastModified : DateTime) (isPlugin : bool) (cache : IDictionary) = - let data = dataCtor.Invoke([| lastModified; isPlugin |]) - add.Invoke(cache, [| path; data |]) |> ignore + let addEntry (path : string) (lastModified : DateTime) (isPlugin : bool) (cache : IDictionary) = + let data = dataCtor.Invoke([| lastModified; isPlugin |]) + add.Invoke(cache, [| path; data |]) |> ignore - let cache = unbox <| cacheCtor.Invoke([||]) - cache |> addEntry "foo.dll" DateTime.Now true - cache |> addEntry "bar.dll" DateTime.Now false + let cache = unbox <| cacheCtor.Invoke([||]) + cache |> addEntry "foo.dll" DateTime.Now true + cache |> addEntry "bar.dll" DateTime.Now false - use stream = new MemoryStream() - serialize.Invoke(cache, [| stream |]) |> ignore + use stream = new MemoryStream() + serialize.Invoke(cache, [| stream |]) |> ignore - stream.Seek(0L, SeekOrigin.Begin) |> ignore - let result = unbox <| deserialize.Invoke(null, [| stream |]) + stream.Seek(0L, SeekOrigin.Begin) |> ignore + let result = unbox <| deserialize.Invoke(null, [| stream |]) - Expect.equal result.Count cache.Count "Unexpected entry count" + Expect.equal result.Count cache.Count "Unexpected entry count" - for path in cache.Keys do - Expect.isTrue (result.Contains path) "Result did not contain path" - Expect.equal result.[path] cache.[path] "Cache entry mismatch" \ No newline at end of file + for path in cache.Keys do + Expect.isTrue (result.Contains path) "Result did not contain path" + Expect.equal result.[path] cache.[path] "Cache entry mismatch" \ No newline at end of file diff --git a/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/MapExt.fs b/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/MapExt.fs index 0ff7e4730..29fd9d82c 100644 --- a/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/MapExt.fs +++ b/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/MapExt.fs @@ -1,56 +1,53 @@ -module MapExt +namespace Aardvark.Base.FSharp.Tests -open System -open NUnit -open NUnit.Framework open FsCheck open FsCheck.NUnit open Aardvark.Base +module MapExt = + module List = + let all (l : list) = + l |> List.fold (&&) true -module List = - let all (l : list) = - l |> List.fold (&&) true + [] + let ``[MapExt] alter`` (m : Map) (v : int) (f : Option -> Option) = + not (Map.containsKey v m) ==> lazy ( + let me = MapExt.ofSeq (Map.toSeq m) -[] -let ``[MapExt] alter`` (m : Map) (v : int) (f : Option -> Option) = - not (Map.containsKey v m) ==> lazy ( - let me = MapExt.ofSeq (Map.toSeq m) - - let alter (key : int) (f : Option -> Option) (m : Map) = - match f (Map.tryFind key m) with - | Some v -> Map.add key v m - | None -> Map.remove key m + let alter (key : int) (f : Option -> Option) (m : Map) = + match f (Map.tryFind key m) with + | Some v -> Map.add key v m + | None -> Map.remove key m - List.all [ - MapExt.toList (MapExt.alter v f me) = Map.toList (alter v f m) - MapExt.toList (MapExt.alter v f (MapExt.add v v me)) = Map.toList (alter v f (Map.add v v m)) - ] - ) + List.all [ + MapExt.toList (MapExt.alter v f me) = Map.toList (alter v f m) + MapExt.toList (MapExt.alter v f (MapExt.add v v me)) = Map.toList (alter v f (Map.add v v m)) + ] + ) -[] -let ``[MapExt] choose`` (m : Map) (f : int -> int -> Option) = - let me = MapExt.ofSeq (Map.toSeq m) + [] + let ``[MapExt] choose`` (m : Map) (f : int -> int -> Option) = + let me = MapExt.ofSeq (Map.toSeq m) - let choose (f : int -> int -> Option) (m : Map) = - let mutable res = Map.empty - for (k,v) in Map.toSeq m do - match f k v with - | Some v -> res <- Map.add k v res - | _ -> () + let choose (f : int -> int -> Option) (m : Map) = + let mutable res = Map.empty + for (k,v) in Map.toSeq m do + match f k v with + | Some v -> res <- Map.add k v res + | _ -> () - res + res - List.all [ - MapExt.toList (MapExt.choose f me) = Map.toList (choose f m) - ] + List.all [ + MapExt.toList (MapExt.choose f me) = Map.toList (choose f m) + ] -[] -let ``[MapExt] range`` (m : Map) (min : int) (max : int) = - (min <= max) ==> lazy ( - let me = MapExt.ofSeq (Map.toSeq m) - let expected = me |> MapExt.filter (fun k _ -> k >= min && k <= max) - let actual = me |> MapExt.range min max - expected = actual - ) \ No newline at end of file + [] + let ``[MapExt] range`` (m : Map) (min : int) (max : int) = + (min <= max) ==> lazy ( + let me = MapExt.ofSeq (Map.toSeq m) + let expected = me |> MapExt.filter (fun k _ -> k >= min && k <= max) + let actual = me |> MapExt.range min max + expected = actual + ) \ No newline at end of file diff --git a/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/OrderMaintenanceTrie.fs b/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/OrderMaintenanceTrie.fs index 614ab7782..9c084aa36 100644 --- a/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/OrderMaintenanceTrie.fs +++ b/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/OrderMaintenanceTrie.fs @@ -1,245 +1,239 @@ -module OrderMaintenanceTrieTest +namespace Aardvark.Base.FSharp.Tests #nowarn "1336" open Aardvark.Base.OrderMaintenanceTrieImplementation -open System open System.Collections.Generic -open NUnit open NUnit.Framework -open FsCheck -open FsCheck.NUnit open Aardvark.Base open FSharp.Data.Adaptive - -let rec validateTree (x : OrderMaintenanceTrieNode<_,_>) = - if x.IsEmpty && not (List.isEmpty x.Path) then failwithf "empty node with key: %A" (List.rev x.Path) +module OrderMaintenanceTrieTest = + let rec validateTree (x : OrderMaintenanceTrieNode<_,_>) = + if x.IsEmpty && not (List.isEmpty x.Path) then failwithf "empty node with key: %A" (List.rev x.Path) - if not (isNull x.ChildrenDict) then - let mutable reached = HashSet.empty - let mutable missing = HashSet.ofSeq x.ChildrenDict.Keys - let mutable f = x.ChildrenDict.First - let mutable lastKey = ValueNone - - let cmp = x.GetComparer(x.Level + 1) - - while not (isNull f) do - let k = List.head f.Path - - match lastKey with - | ValueSome last -> - match cmp with - | Some cmp -> - if cmp.Compare(last, k) > 0 then failwithf "inconsistent order on level %d (%A > %A)" x.Level last k - | None -> + if not (isNull x.ChildrenDict) then + let mutable reached = HashSet.empty + let mutable missing = HashSet.ofSeq x.ChildrenDict.Keys + let mutable f = x.ChildrenDict.First + let mutable lastKey = ValueNone + + let cmp = x.GetComparer(x.Level + 1) + + while not (isNull f) do + let k = List.head f.Path + + match lastKey with + | ValueSome last -> + match cmp with + | Some cmp -> + if cmp.Compare(last, k) > 0 then failwithf "inconsistent order on level %d (%A > %A)" x.Level last k + | None -> + () + | ValueNone -> () - | ValueNone -> - () - missing <- HashSet.remove k missing + missing <- HashSet.remove k missing - if HashSet.contains k reached then - failwithf "duplicate key: %A" k - reached <- HashSet.add k reached + if HashSet.contains k reached then + failwithf "duplicate key: %A" k + reached <- HashSet.add k reached - if f.Parent <> x then - failwithf "bad parent for %A: %A" (List.rev f.Path) (List.rev f.Parent.Path) + if f.Parent <> x then + failwithf "bad parent for %A: %A" (List.rev f.Path) (List.rev f.Parent.Path) - validateTree f + validateTree f - f <- f.Next - lastKey <- ValueSome k + f <- f.Next + lastKey <- ValueSome k - if missing.Count > 0 then - failwithf "not all keys reached: %A" missing - -let validateInternal (getComparer : int -> option>) (t : OrderMaintenanceTrie<'k, 'v>) = - validateTree t.Root - - let forward = - let res = System.Collections.Generic.List * 'v>() - let mutable c = t.First - while (ValueOption.isSome c) do - res.Add(c.Value.Key, c.Value.Value) - c <- c.Value.Next - res - - let backward = - let res = System.Collections.Generic.List * 'v>() - let mutable c = t.Last - while (ValueOption.isSome c) do - res.Add(c.Value.Key, c.Value.Value) - c <- c.Value.Prev - res - - let all = - let res = System.Collections.Generic.List * 'v>() - t.Iter(fun k v -> res.Add(k,v)) - res - - - if forward.Count <> all.Count then - failwithf "inconsistent forward count: %A vs %A" forward.Count all.Count - - if backward.Count <> all.Count then - failwithf "inconsistent backward counts: %A vs %A" backward.Count all.Count - - let mutable j = backward.Count - 1 - for i in 0 .. forward.Count - 1 do - if forward.[i] <> backward.[j] then - failwithf "error at position %d: %A vs %A" i forward.[i] backward.[j] - if forward.[i] <> all.[i] then - failwithf "error at position %d: %A vs %A" i forward.[i] all.[j] - j <- j - 1 - -let validateAgainst (t : OrderMaintenanceTrie<'k, 'v>) (m : HashMap, 'v>) = - let mutable missing = m - t.Iter (fun k v -> - match HashMap.tryRemove k missing with - | Some (hv, r) -> - if v <> hv then failwithf "inconsistent value %A vs %A" v hv - missing <- r - | None -> - failwithf "superflous value for %A: %A" k v - ) - - if missing.Count > 0 then - failwithf "missing values: %A" missing - -type ValidationTrie<'k, 'v when 'k : equality and 'v : equality>(getComparer : int -> option>) = - - let trie = OrderMaintenanceTrie<'k, 'v>(getComparer) - let mutable store = HashMap.empty - - let check() = - validateInternal getComparer trie - validateAgainst trie store - - member x.Forward = - let rec s (r : voption>) = - match r with - | ValueSome r -> - Seq.append - (Seq.singleton (r.Key, r.Value)) - (Seq.delay (fun () -> s r.Next)) - | ValueNone -> - Seq.empty - s trie.First + if missing.Count > 0 then + failwithf "not all keys reached: %A" missing + + let validateInternal (getComparer : int -> option>) (t : OrderMaintenanceTrie<'k, 'v>) = + validateTree t.Root + + let forward = + let res = System.Collections.Generic.List * 'v>() + let mutable c = t.First + while (ValueOption.isSome c) do + res.Add(c.Value.Key, c.Value.Value) + c <- c.Value.Next + res + + let backward = + let res = System.Collections.Generic.List * 'v>() + let mutable c = t.Last + while (ValueOption.isSome c) do + res.Add(c.Value.Key, c.Value.Value) + c <- c.Value.Prev + res + + let all = + let res = System.Collections.Generic.List * 'v>() + t.Iter(fun k v -> res.Add(k,v)) + res + + + if forward.Count <> all.Count then + failwithf "inconsistent forward count: %A vs %A" forward.Count all.Count + + if backward.Count <> all.Count then + failwithf "inconsistent backward counts: %A vs %A" backward.Count all.Count - member x.Count = store.Count - member x.Content = store - member x.Trie = trie - - member x.Set(key : list<'k>, value : 'v) = - trie.Set(key, value) |> ignore - store <- HashMap.add key value store - check() - - member x.Remove(key : list<'k>) = - trie.TryRemove(key) |> ignore - store <- HashMap.remove key store - check() - - member x.AddOrUpdate(key : list<'k>, create : voption<'v> -> 'v) = - - let mutable other = None - let realCreate (o : voption<'v>) = - match other with - | Some (oo, on) -> - if oo <> o then failwithf "bad old value: %A vs %A" oo o - on + let mutable j = backward.Count - 1 + for i in 0 .. forward.Count - 1 do + if forward.[i] <> backward.[j] then + failwithf "error at position %d: %A vs %A" i forward.[i] backward.[j] + if forward.[i] <> all.[i] then + failwithf "error at position %d: %A vs %A" i forward.[i] all.[j] + j <- j - 1 + + let validateAgainst (t : OrderMaintenanceTrie<'k, 'v>) (m : HashMap, 'v>) = + let mutable missing = m + t.Iter (fun k v -> + match HashMap.tryRemove k missing with + | Some (hv, r) -> + if v <> hv then failwithf "inconsistent value %A vs %A" v hv + missing <- r | None -> - let r = create o - other <- Some (o, r) - r + failwithf "superflous value for %A: %A" k v + ) + + if missing.Count > 0 then + failwithf "missing values: %A" missing + + type ValidationTrie<'k, 'v when 'k : equality and 'v : equality>(getComparer : int -> option>) = + + let trie = OrderMaintenanceTrie<'k, 'v>(getComparer) + let mutable store = HashMap.empty + + let check() = + validateInternal getComparer trie + validateAgainst trie store + + member x.Forward = + let rec s (r : voption>) = + match r with + | ValueSome r -> + Seq.append + (Seq.singleton (r.Key, r.Value)) + (Seq.delay (fun () -> s r.Next)) + | ValueNone -> + Seq.empty + s trie.First + + member x.Count = store.Count + member x.Content = store + member x.Trie = trie + + member x.Set(key : list<'k>, value : 'v) = + trie.Set(key, value) |> ignore + store <- HashMap.add key value store + check() + + member x.Remove(key : list<'k>) = + trie.TryRemove(key) |> ignore + store <- HashMap.remove key store + check() + + member x.AddOrUpdate(key : list<'k>, create : voption<'v> -> 'v) = + + let mutable other = None + let realCreate (o : voption<'v>) = + match other with + | Some (oo, on) -> + if oo <> o then failwithf "bad old value: %A vs %A" oo o + on + | None -> + let r = create o + other <- Some (o, r) + r - trie.AddOrUpdate(key, realCreate) |> ignore - store <- store.AlterV(key, realCreate >> ValueSome) - check() + trie.AddOrUpdate(key, realCreate) |> ignore + store <- store.AlterV(key, realCreate >> ValueSome) + check() -[] -let ``[OrderMaintenanceTrie] validation``() = - let rand = RandomSystem() + [] + let ``[OrderMaintenanceTrie] validation``() = + let rand = RandomSystem() - let comparers = - Seq.initInfinite (fun i -> - if i % 2 = 0 then Comparer.Default :> IComparer<_> |> Some - else None - ) |> Seq.cache + let comparers = + Seq.initInfinite (fun i -> + if i % 2 = 0 then Comparer.Default :> IComparer<_> |> Some + else None + ) |> Seq.cache - let t = - ValidationTrie (fun l -> - Seq.item l comparers - ) - - let mutable updates = 0 - let mutable adds = 0 - let mutable removes = 0 - let mutable dummyRemoves = 0 - let mutable maxCount = 0 - - let add() = - if rand.UniformDouble() > 0.2 || t.Count = 0 then - // new key - let k = - let len = rand.UniformInt(5) + 1 - List.init len (fun _ -> rand.UniformInt(20)) - - adds <- adds + 1 - let v = List.sum k - t.Set(k, v) - else - // existing key - let k = t.Content |> Seq.item (rand.UniformInt t.Count) |> fst - updates <- updates + 1 - if rand.UniformDouble() > 0.5 then - t.Set(k, rand.UniformInt()) + let t = + ValidationTrie (fun l -> + Seq.item l comparers + ) + + let mutable updates = 0 + let mutable adds = 0 + let mutable removes = 0 + let mutable dummyRemoves = 0 + let mutable maxCount = 0 + + let add() = + if rand.UniformDouble() > 0.2 || t.Count = 0 then + // new key + let k = + let len = rand.UniformInt(5) + 1 + List.init len (fun _ -> rand.UniformInt(20)) + + adds <- adds + 1 + let v = List.sum k + t.Set(k, v) else - t.AddOrUpdate(k, function ValueSome o -> 2*o | _ -> failwith "should exist") - maxCount <- max maxCount t.Count - - let rem() = - if rand.UniformDouble() > 0.05 && t.Count > 0 then - // existing key - removes <- removes + 1 - let k = t.Content |> Seq.item (rand.UniformInt t.Count) |> fst - t.Remove(k) - else - dummyRemoves <- dummyRemoves + 1 - // non existing key - let k = - let len = rand.UniformInt(5) + 1 - List.init len (fun _ -> rand.UniformInt(100)) - t.Remove k - maxCount <- max maxCount t.Count - - let randomOp () = - if t.Count > 1 then - if rand.UniformDouble() > 0.55 then - rem() + // existing key + let k = t.Content |> Seq.item (rand.UniformInt t.Count) |> fst + updates <- updates + 1 + if rand.UniformDouble() > 0.5 then + t.Set(k, rand.UniformInt()) + else + t.AddOrUpdate(k, function ValueSome o -> 2*o | _ -> failwith "should exist") + maxCount <- max maxCount t.Count + + let rem() = + if rand.UniformDouble() > 0.05 && t.Count > 0 then + // existing key + removes <- removes + 1 + let k = t.Content |> Seq.item (rand.UniformInt t.Count) |> fst + t.Remove(k) + else + dummyRemoves <- dummyRemoves + 1 + // non existing key + let k = + let len = rand.UniformInt(5) + 1 + List.init len (fun _ -> rand.UniformInt(100)) + t.Remove k + maxCount <- max maxCount t.Count + + let randomOp () = + if t.Count > 1 then + if rand.UniformDouble() > 0.55 then + rem() + else + add() else add() - else - add() - let iter = 50000 - Log.startTimed "random ops" - for i in 1 .. iter do - randomOp() - Report.Progress(float i / float iter) - - Log.line "%d adds" adds - Log.line "%d updates" updates - Log.line "%d removes" removes - Log.line "%d removes of non existing" dummyRemoves - Log.line "%d maximal entries" maxCount - Log.stop() - - Log.start "content" - for (k, v) in t.Trie do - Log.line "%A: %A" k v - Log.stop() - + let iter = 50000 + Log.startTimed "random ops" + for i in 1 .. iter do + randomOp() + + Log.line "%d adds" adds + Log.line "%d updates" updates + Log.line "%d removes" removes + Log.line "%d removes of non existing" dummyRemoves + Log.line "%d maximal entries" maxCount + Log.stop() + + Log.start "content" + for (k, v) in t.Trie do + Log.line "%A: %A" k v + Log.stop() \ No newline at end of file diff --git a/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/SortedSetExt.fs b/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/SortedSetExt.fs index ed1f84a70..1f9779eea 100644 --- a/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/SortedSetExt.fs +++ b/src/Tests/Aardvark.Base.FSharp.Tests/Datastructures/SortedSetExt.fs @@ -44,7 +44,6 @@ module SortedSetNeighbours = for i in 0..10000 do let remove = r.NextDouble() > 0.5 && d.Count > 0 - Console.WriteLine("iteration {0}: {1}", i, d.Count) if remove && i > 200 then let kvp = d |> Seq.item (r.Next(d.Count)) diff --git a/src/Tests/Aardvark.Base.Tests/RangesBoxes/BoxTests.cs b/src/Tests/Aardvark.Base.Tests/RangesBoxes/BoxTests.cs index fbfb1b90d..6aa17fe64 100644 --- a/src/Tests/Aardvark.Base.Tests/RangesBoxes/BoxTests.cs +++ b/src/Tests/Aardvark.Base.Tests/RangesBoxes/BoxTests.cs @@ -395,7 +395,6 @@ public void TransformedEmpty() var test = Box3d.Invalid.Transformed(mat); Assert.True(test.IsEmpty); Assert.False(test.Max.AnyNaN || test.Min.AnyNaN || test.IsNonEmpty); - if (test.Min.AnyInfinity || test.Max.AnyInfinity) Report.Line("Max -> Infinite"); } } @@ -407,7 +406,6 @@ public void TransformedInfinite() { var mat = new M44d(rnd.CreateUniformDoubleArray(16)); var test = Box3d.Infinite.Transformed(mat); - if (test.Min.AnyInfinity || test.Max.AnyInfinity) Report.Line("Max -> Infinite"); // NOTE: some max values will be infinite Assert.False(test.Max.AnyNaN || test.Min.AnyNaN || test.IsEmpty); } }