-
Notifications
You must be signed in to change notification settings - Fork 6
Description
It would make sense for the primitives library to offer some sort of SparseSet
implementation that works, at minimum, with Point
, in some capacity.
Consider the use case of storing a subset of Point
objects which reside on a grid view (a fairly common when dealing with grid and/or grid algorithms).
There are two options, currently, that don't involve creating custom data structures. The first, is to use an IGridView<bool>
(probably BitArrayView
, in most cases). This is quite memory efficient (around 1 bit per location on a grid), and provides very quick Contains
operations. What it does not provide, is O(n)
iteration over elements in the set; you instead have to iterate over all elements in the grid view; an operation proportional to the size of the grid, rather than the number of elements in the set.
In the case where you need iteration, you can instead use a HashSet<Point>
. This provides O(1) contains, and O(n) iteration; but is not particularly CPU cache efficient, and involves allocating during Add and Remove operations; therefore this does not fit all use cases either.
In cases like this, where a grid size is known, and doing allocation up front is preferable to allocation during Add/Remove operations, a sparse set structure (good example here) can be useful. It provides O(1) contains, O(1) add and remove, and O(n) iteration with good cache locality, in exchange for a fixed max size (not a problem for grid views) and performing allocation up front (a trade-off that grid views make anyway).
Another option is something like BitArrayView
paired with List<int>
. This would provide some memory reduction over the set above, and still provide O(1)
contains, O(1)
add, and O(n) iteration, in exchange for
O(n)` remove. This in particular may fit use cases that clear the set entirely, rather than removing items.