From a6cb156e683327372fe2843a82d1cc8cc1464cca Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 19 Aug 2024 17:05:23 +0200 Subject: [PATCH] [FSharp] Rework LookupTable utilities --- .../Utilities/Interop/FSLibExtensions.fs | 54 +++++++++++++------ .../PixImage/ImageTrafo.fs | 4 +- .../PixImage/PixImageErrorMetric.fs | 2 +- .../Tensors/PixTests.fs | 2 +- 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/Aardvark.Base.FSharp/Utilities/Interop/FSLibExtensions.fs b/src/Aardvark.Base.FSharp/Utilities/Interop/FSLibExtensions.fs index 1d484020..b63e5c13 100644 --- a/src/Aardvark.Base.FSharp/Utilities/Interop/FSLibExtensions.fs +++ b/src/Aardvark.Base.FSharp/Utilities/Interop/FSLibExtensions.fs @@ -367,35 +367,55 @@ module NiceUtilities = module LookupTable = open System.Collections.Generic - let lookupTable (l : list<'a * 'b>) = + let private build (entries: #seq<'Key * 'Value>) = let d = Dictionary() - for (k,v) in l do + for k, v in entries do match d.TryGetValue k with - | (true, vo) -> failwithf "duplicated lookup-entry: %A (%A vs %A)" k vo v - | _ -> () + | (true, vo) -> raise <| ArgumentException($"Duplicate lookup table entry {k}: {v} and {vo}.") + | _ -> () d.[k] <- v - fun (key : 'a) -> + d + + /// Builds a lookup table from the given entries and returns a function that retrieves the value associated with a key. + /// Fails if a key occurs more than once in the input collection. + let lookup (entries: #seq<'Key * 'Value>) = + let d = build entries + + fun (key : 'Key) -> match d.TryGetValue key with - | (true, v) -> v - | _ -> failwithf "unsupported %A: %A" typeof<'a> key + | (true, v) -> v + | _ -> raise <| KeyNotFoundException($"Key {key} of type {typeof<'Key>} not found in lookup table.") + /// Builds a lookup table from the given entries and returns a function that retrieves the value associated with a key if it exists. + /// Fails if a key occurs more than once in the input collection. + let tryLookup (entries: #seq<'Key * 'Value>) = + let d = build entries - let lookupTable' (l : list<'a * 'b>) = - let d = Dictionary() - for (k,v) in l do - match d.TryGetValue k with - | (true, vo) -> failwithf "duplicated lookup-entry: %A (%A vs %A)" k vo v - | _ -> () + fun (key : 'Key) -> + match d.TryGetValue key with + | (true, v) -> Some v + | _ -> None - d.[k] <- v + /// Builds a lookup table from the given entries and returns a function that retrieves the value associated with a key if it exists. + /// Fails if a key occurs more than once in the input collection. + let tryLookupV (entries: #seq<'Key * 'Value>) = + let d = build entries - fun (key : 'a) -> + fun (key : 'Key) -> match d.TryGetValue key with - | (true, v) -> Some v - | _ -> None + | (true, v) -> ValueSome v + | _ -> ValueNone + + [] + let lookupTable (l : list<'a * 'b>) = + lookup l + + [] + let lookupTable' (l : list<'a * 'b>) = + tryLookup l [] module EnumExtensions = diff --git a/src/Aardvark.Base.Tensors/PixImage/ImageTrafo.fs b/src/Aardvark.Base.Tensors/PixImage/ImageTrafo.fs index 71a210d0..0b55b103 100644 --- a/src/Aardvark.Base.Tensors/PixImage/ImageTrafo.fs +++ b/src/Aardvark.Base.Tensors/PixImage/ImageTrafo.fs @@ -3,7 +3,7 @@ [] module ImageTrafo = let private composeTable = - LookupTable.lookupTable [ + LookupTable.lookup [ struct (ImageTrafo.Identity, ImageTrafo.Identity), ImageTrafo.Identity struct (ImageTrafo.Identity, ImageTrafo.Rot90), ImageTrafo.Rot90 struct (ImageTrafo.Identity, ImageTrafo.Rot180), ImageTrafo.Rot180 @@ -74,7 +74,7 @@ module ImageTrafo = composeTable (struct (l, r)) let inverse = - LookupTable.lookupTable [ + LookupTable.lookup [ ImageTrafo.MirrorX, ImageTrafo.MirrorX ImageTrafo.MirrorY, ImageTrafo.MirrorY ImageTrafo.Identity, ImageTrafo.Identity diff --git a/src/Aardvark.Base.Tensors/PixImage/PixImageErrorMetric.fs b/src/Aardvark.Base.Tensors/PixImage/PixImageErrorMetric.fs index 99e7ba6d..a113eae1 100644 --- a/src/Aardvark.Base.Tensors/PixImage/PixImageErrorMetric.fs +++ b/src/Aardvark.Base.Tensors/PixImage/PixImageErrorMetric.fs @@ -13,7 +13,7 @@ module FSharpPixImageErrorMetricExtensions = module ErrorMetricHelpers = let maxValues = - LookupTable.lookupTable [ + LookupTable.lookup [ typeof, 255.0 typeof, 255.0 typeof, 65535.0 diff --git a/src/Tests/Aardvark.Base.FSharp.Tests/Tensors/PixTests.fs b/src/Tests/Aardvark.Base.FSharp.Tests/Tensors/PixTests.fs index 6efc38b6..52c357a1 100644 --- a/src/Tests/Aardvark.Base.FSharp.Tests/Tensors/PixTests.fs +++ b/src/Tests/Aardvark.Base.FSharp.Tests/Tensors/PixTests.fs @@ -258,7 +258,7 @@ module PixTests = let computePSNR = let table : Type -> (PixImage -> PixImage -> float) = - LookupTable.lookupTable [ + LookupTable.lookup [ typeof, fun src dst -> PixImage.peakSignalToNoiseRatio (src.AsPixImage()) (dst.AsPixImage()) typeof, fun src dst -> PixImage.peakSignalToNoiseRatio (src.AsPixImage()) (dst.AsPixImage()) typeof, fun src dst -> PixImage.peakSignalToNoiseRatio (src.AsPixImage()) (dst.AsPixImage())