Skip to content

Commit

Permalink
[RangeSet] Add containsRange and union
Browse files Browse the repository at this point in the history
  • Loading branch information
hyazinthh committed Feb 27, 2024
1 parent b929e1e commit 89e5d12
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 20 deletions.
132 changes: 116 additions & 16 deletions src/Aardvark.Base.FSharp/Datastructures/Immutable/RangeSet_auto.fs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ type RangeSet1i internal (store : MapExt<int32, HalfRangeKind>) =
assert (newStore.Count % 2 = 0 || MapExt.maxValue newStore = HalfRangeKind.Left)
RangeSet1i(newStore)

/// Returns the union of the set with the given set.
member inline x.Union(other : RangeSet1i) =
let mutable res = x
for r in other do
res <- res.Add r
res

/// Returns the intersection of the set with the given range.
member x.Intersect(r : Range1i) =
if r.Max < r.Min then
Expand All @@ -223,14 +230,26 @@ type RangeSet1i internal (store : MapExt<int32, HalfRangeKind>) =
assert (newStore.Count % 2 = 0 || MapExt.maxValue newStore = HalfRangeKind.Left)
RangeSet1i(newStore)

/// Returns whether the given value is contained in the range set.
member x.Contains(v : int32) =
member private x.TryFindLeftBoundary(v : int32) =
let struct (l, s, _) = MapExt.neighboursV v store
match s with
| ValueSome (_, k) -> k = HalfRangeKind.Left
| ValueSome (i, k) -> if k = HalfRangeKind.Left then ValueSome i else ValueNone
| _ ->
match l with
| ValueSome (_, HalfRangeKind.Left) -> true
| ValueSome (i, HalfRangeKind.Left) -> ValueSome i
| _ -> ValueNone

/// Returns whether the given value is contained in the range set.
member x.Contains(v : int32) =
x.TryFindLeftBoundary v |> ValueOption.isSome

/// Returns whether the given range is contained in the set.
member x.Contains(r : Range1i) =
if r.Max < r.Min then false
elif r.Min = r.Max then x.Contains r.Min
else
match x.TryFindLeftBoundary r.Min, x.TryFindLeftBoundary r.Max with
| ValueSome l, ValueSome r -> l = r
| _ -> false

/// Returns the number of disjoint ranges in the set.
Expand Down Expand Up @@ -435,6 +454,9 @@ module RangeSet1i =
/// Removes the given range from the set.
let inline remove (range : Range1i) (set : RangeSet1i) = set.Remove range

/// Returns the union of two sets.
let inline union (l : RangeSet1i) (r : RangeSet1i) = l.Union r

/// Returns the intersection of the set with the given range.
let inline intersect (range : Range1i) (set : RangeSet1i) = set.Intersect range

Expand All @@ -444,6 +466,9 @@ module RangeSet1i =
/// Returns whether the given value is contained in the range set.
let inline contains (value : int32) (set : RangeSet1i) = set.Contains value

/// Returns whether the given range is contained in the set.
let inline containsRange (range : Range1i) (set : RangeSet1i) = set.Contains range

/// Returns the number of disjoint ranges in the set.
let inline count (set : RangeSet1i) = set.Count

Expand Down Expand Up @@ -630,6 +655,13 @@ type RangeSet1ui internal (store : MapExt<uint32, HalfRangeKind>) =
assert (newStore.Count % 2 = 0 || MapExt.maxValue newStore = HalfRangeKind.Left)
RangeSet1ui(newStore)

/// Returns the union of the set with the given set.
member inline x.Union(other : RangeSet1ui) =
let mutable res = x
for r in other do
res <- res.Add r
res

/// Returns the intersection of the set with the given range.
member x.Intersect(r : Range1ui) =
if r.Max < r.Min then
Expand All @@ -651,14 +683,26 @@ type RangeSet1ui internal (store : MapExt<uint32, HalfRangeKind>) =
assert (newStore.Count % 2 = 0 || MapExt.maxValue newStore = HalfRangeKind.Left)
RangeSet1ui(newStore)

/// Returns whether the given value is contained in the range set.
member x.Contains(v : uint32) =
member private x.TryFindLeftBoundary(v : uint32) =
let struct (l, s, _) = MapExt.neighboursV v store
match s with
| ValueSome (_, k) -> k = HalfRangeKind.Left
| ValueSome (i, k) -> if k = HalfRangeKind.Left then ValueSome i else ValueNone
| _ ->
match l with
| ValueSome (_, HalfRangeKind.Left) -> true
| ValueSome (i, HalfRangeKind.Left) -> ValueSome i
| _ -> ValueNone

/// Returns whether the given value is contained in the range set.
member x.Contains(v : uint32) =
x.TryFindLeftBoundary v |> ValueOption.isSome

/// Returns whether the given range is contained in the set.
member x.Contains(r : Range1ui) =
if r.Max < r.Min then false
elif r.Min = r.Max then x.Contains r.Min
else
match x.TryFindLeftBoundary r.Min, x.TryFindLeftBoundary r.Max with
| ValueSome l, ValueSome r -> l = r
| _ -> false

/// Returns the number of disjoint ranges in the set.
Expand Down Expand Up @@ -863,6 +907,9 @@ module RangeSet1ui =
/// Removes the given range from the set.
let inline remove (range : Range1ui) (set : RangeSet1ui) = set.Remove range

/// Returns the union of two sets.
let inline union (l : RangeSet1ui) (r : RangeSet1ui) = l.Union r

/// Returns the intersection of the set with the given range.
let inline intersect (range : Range1ui) (set : RangeSet1ui) = set.Intersect range

Expand All @@ -872,6 +919,9 @@ module RangeSet1ui =
/// Returns whether the given value is contained in the range set.
let inline contains (value : uint32) (set : RangeSet1ui) = set.Contains value

/// Returns whether the given range is contained in the set.
let inline containsRange (range : Range1ui) (set : RangeSet1ui) = set.Contains range

/// Returns the number of disjoint ranges in the set.
let inline count (set : RangeSet1ui) = set.Count

Expand Down Expand Up @@ -1058,6 +1108,13 @@ type RangeSet1l internal (store : MapExt<int64, HalfRangeKind>) =
assert (newStore.Count % 2 = 0 || MapExt.maxValue newStore = HalfRangeKind.Left)
RangeSet1l(newStore)

/// Returns the union of the set with the given set.
member inline x.Union(other : RangeSet1l) =
let mutable res = x
for r in other do
res <- res.Add r
res

/// Returns the intersection of the set with the given range.
member x.Intersect(r : Range1l) =
if r.Max < r.Min then
Expand All @@ -1079,14 +1136,26 @@ type RangeSet1l internal (store : MapExt<int64, HalfRangeKind>) =
assert (newStore.Count % 2 = 0 || MapExt.maxValue newStore = HalfRangeKind.Left)
RangeSet1l(newStore)

/// Returns whether the given value is contained in the range set.
member x.Contains(v : int64) =
member private x.TryFindLeftBoundary(v : int64) =
let struct (l, s, _) = MapExt.neighboursV v store
match s with
| ValueSome (_, k) -> k = HalfRangeKind.Left
| ValueSome (i, k) -> if k = HalfRangeKind.Left then ValueSome i else ValueNone
| _ ->
match l with
| ValueSome (_, HalfRangeKind.Left) -> true
| ValueSome (i, HalfRangeKind.Left) -> ValueSome i
| _ -> ValueNone

/// Returns whether the given value is contained in the range set.
member x.Contains(v : int64) =
x.TryFindLeftBoundary v |> ValueOption.isSome

/// Returns whether the given range is contained in the set.
member x.Contains(r : Range1l) =
if r.Max < r.Min then false
elif r.Min = r.Max then x.Contains r.Min
else
match x.TryFindLeftBoundary r.Min, x.TryFindLeftBoundary r.Max with
| ValueSome l, ValueSome r -> l = r
| _ -> false

/// Returns the number of disjoint ranges in the set.
Expand Down Expand Up @@ -1291,6 +1360,9 @@ module RangeSet1l =
/// Removes the given range from the set.
let inline remove (range : Range1l) (set : RangeSet1l) = set.Remove range

/// Returns the union of two sets.
let inline union (l : RangeSet1l) (r : RangeSet1l) = l.Union r

/// Returns the intersection of the set with the given range.
let inline intersect (range : Range1l) (set : RangeSet1l) = set.Intersect range

Expand All @@ -1300,6 +1372,9 @@ module RangeSet1l =
/// Returns whether the given value is contained in the range set.
let inline contains (value : int64) (set : RangeSet1l) = set.Contains value

/// Returns whether the given range is contained in the set.
let inline containsRange (range : Range1l) (set : RangeSet1l) = set.Contains range

/// Returns the number of disjoint ranges in the set.
let inline count (set : RangeSet1l) = set.Count

Expand Down Expand Up @@ -1486,6 +1561,13 @@ type RangeSet1ul internal (store : MapExt<uint64, HalfRangeKind>) =
assert (newStore.Count % 2 = 0 || MapExt.maxValue newStore = HalfRangeKind.Left)
RangeSet1ul(newStore)

/// Returns the union of the set with the given set.
member inline x.Union(other : RangeSet1ul) =
let mutable res = x
for r in other do
res <- res.Add r
res

/// Returns the intersection of the set with the given range.
member x.Intersect(r : Range1ul) =
if r.Max < r.Min then
Expand All @@ -1507,14 +1589,26 @@ type RangeSet1ul internal (store : MapExt<uint64, HalfRangeKind>) =
assert (newStore.Count % 2 = 0 || MapExt.maxValue newStore = HalfRangeKind.Left)
RangeSet1ul(newStore)

/// Returns whether the given value is contained in the range set.
member x.Contains(v : uint64) =
member private x.TryFindLeftBoundary(v : uint64) =
let struct (l, s, _) = MapExt.neighboursV v store
match s with
| ValueSome (_, k) -> k = HalfRangeKind.Left
| ValueSome (i, k) -> if k = HalfRangeKind.Left then ValueSome i else ValueNone
| _ ->
match l with
| ValueSome (_, HalfRangeKind.Left) -> true
| ValueSome (i, HalfRangeKind.Left) -> ValueSome i
| _ -> ValueNone

/// Returns whether the given value is contained in the range set.
member x.Contains(v : uint64) =
x.TryFindLeftBoundary v |> ValueOption.isSome

/// Returns whether the given range is contained in the set.
member x.Contains(r : Range1ul) =
if r.Max < r.Min then false
elif r.Min = r.Max then x.Contains r.Min
else
match x.TryFindLeftBoundary r.Min, x.TryFindLeftBoundary r.Max with
| ValueSome l, ValueSome r -> l = r
| _ -> false

/// Returns the number of disjoint ranges in the set.
Expand Down Expand Up @@ -1719,6 +1813,9 @@ module RangeSet1ul =
/// Removes the given range from the set.
let inline remove (range : Range1ul) (set : RangeSet1ul) = set.Remove range

/// Returns the union of two sets.
let inline union (l : RangeSet1ul) (r : RangeSet1ul) = l.Union r

/// Returns the intersection of the set with the given range.
let inline intersect (range : Range1ul) (set : RangeSet1ul) = set.Intersect range

Expand All @@ -1728,6 +1825,9 @@ module RangeSet1ul =
/// Returns whether the given value is contained in the range set.
let inline contains (value : uint64) (set : RangeSet1ul) = set.Contains value

/// Returns whether the given range is contained in the set.
let inline containsRange (range : Range1ul) (set : RangeSet1ul) = set.Contains range

/// Returns the number of disjoint ranges in the set.
let inline count (set : RangeSet1ul) = set.Count

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,13 @@ type __rangeset__ internal (store : MapExt<__ltype__, HalfRangeKind>) =
assert (newStore.Count % 2 = 0 || MapExt.maxValue newStore = HalfRangeKind.Left)
__rangeset__(newStore)

/// Returns the union of the set with the given set.
member inline x.Union(other : __rangeset__) =
let mutable res = x
for r in other do
res <- res.Add r
res

/// Returns the intersection of the set with the given range.
member x.Intersect(r : __range__) =
if r.Max < r.Min then
Expand All @@ -237,14 +244,26 @@ type __rangeset__ internal (store : MapExt<__ltype__, HalfRangeKind>) =
assert (newStore.Count % 2 = 0 || MapExt.maxValue newStore = HalfRangeKind.Left)
__rangeset__(newStore)

/// Returns whether the given value is contained in the range set.
member x.Contains(v : __ltype__) =
member private x.TryFindLeftBoundary(v : __ltype__) =
let struct (l, s, _) = MapExt.neighboursV v store
match s with
| ValueSome (_, k) -> k = HalfRangeKind.Left
| ValueSome (i, k) -> if k = HalfRangeKind.Left then ValueSome i else ValueNone
| _ ->
match l with
| ValueSome (_, HalfRangeKind.Left) -> true
| ValueSome (i, HalfRangeKind.Left) -> ValueSome i
| _ -> ValueNone

/// Returns whether the given value is contained in the range set.
member x.Contains(v : __ltype__) =
x.TryFindLeftBoundary v |> ValueOption.isSome

/// Returns whether the given range is contained in the set.
member x.Contains(r : __range__) =
if r.Max < r.Min then false
elif r.Min = r.Max then x.Contains r.Min
else
match x.TryFindLeftBoundary r.Min, x.TryFindLeftBoundary r.Max with
| ValueSome l, ValueSome r -> l = r
| _ -> false

/// Returns the number of disjoint ranges in the set.
Expand Down Expand Up @@ -449,6 +468,9 @@ module __rangeset__ =
/// Removes the given range from the set.
let inline remove (range : __range__) (set : __rangeset__) = set.Remove range

/// Returns the union of two sets.
let inline union (l : __rangeset__) (r : __rangeset__) = l.Union r

/// Returns the intersection of the set with the given range.
let inline intersect (range : __range__) (set : __rangeset__) = set.Intersect range

Expand All @@ -458,6 +480,9 @@ module __rangeset__ =
/// Returns whether the given value is contained in the range set.
let inline contains (value : __ltype__) (set : __rangeset__) = set.Contains value

/// Returns whether the given range is contained in the set.
let inline containsRange (range : __range__) (set : __rangeset__) = set.Contains range

/// Returns the number of disjoint ranges in the set.
let inline count (set : __rangeset__) = set.Count

Expand Down
15 changes: 15 additions & 0 deletions src/Tests/Aardvark.Base.FSharp.Benchmarks/RangeSet.fs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,21 @@ module RangeSetTests =
let actual = RangeSet1l.ofList ranges
actual |> should equal expected

[<Theory>]
let ``[RangeSet] Contains Range`` (maxValue : bool) =
let set = RangeSet1l.ofList [ Range1l(-3L, -2L); Range1l(1L, 4L); Range1l(6L, 8L); Range1l(10L, if maxValue then Int64.MaxValue else 30L)]

set |> RangeSet1l.containsRange (Range1l(-3L, -2L)) |> should be True
set |> RangeSet1l.containsRange (Range1l(-3L, -3L)) |> should be True
set |> RangeSet1l.containsRange (Range1l(-3L, -2L)) |> should be True
set |> RangeSet1l.containsRange (Range1l(-2L, -2L)) |> should be True

set |> RangeSet1l.containsRange (Range1l(2L, 3L)) |> should be True
set |> RangeSet1l.containsRange (Range1l(3L, 3L)) |> should be True

set |> RangeSet1l.containsRange (Range1l(-2L, 3L)) |> should be False

set |> RangeSet1l.containsRange (Range1l(20L, Int64.MaxValue)) |> should equal maxValue

module RangeSetBenchmarks =
open BenchmarkDotNet.Attributes;
Expand Down

0 comments on commit 89e5d12

Please sign in to comment.