Closed martinus closed 1 year ago
To further dismiss the std::deque option: the performance is very dependent on the stl implementation (and probably the underlying chunk size). I found that with MSVC, the performance is surprisingly bad.
More thoughts:
Yes, I made a similar container, precisely because std::deque was found to be slow. My primary interest was to prevent reallocation, in the context of acquiring random batches of data in real-time.
This is not too clear from your doc, but with segmented_map, we get stable buckets; that is, once inserted in the map, a key/value pair will never be moved, whatever mutation happens to the map (right?). In which case do we not have iterator stability, given this fact?
With segmented_map you'll get stable iterators & references on insert, but not on erase.
Thank you for your answer; it would be worth clarifying this in your documentation about segment_map.
Closing the issue as I won't have time to work on this
robin_hood map has an option for stable iterators, that's currently not possible with unordered_dense.
One way to implement this might be be to be able to replace the underlying container with some kind of slotmap.
Slot map design
a member for
size
one
index
array (same capacity as data array)one
data
array with stable references on insert (e.g. std::deque)index
is split into two parts: first part untilsize()
, contains indices into the data with actual content. second part aftersize
contains unused indicesdata
is not densely stored, there are empty unconstructed cells in it.Insert: O(1) amortized.
Take the index after
size
, construct element in that location indata
. Increase size by 1. When capacity is reached we know data is completely full. push back a new index withsize
and construct there.Erase at location
x
: O(1)index[x]
and destroy that element.std::swap(index[x], index.back())
Iterate
Needs a custom iterator that goes over the index and dereferences from there.
Open questions
std::vector
?std::optional<Data>
but that is huge unnecessary overhead.