I'm looking to implement a multi-map that maintains insertion order of the entries, and allows in-place insertion/replacement without affecting the order. Guava's LinkedListMultimap
is almost perfect, but doesn't allow the type of replacement I'm looking for. LinkedListMultimap
is implemented as a hash map and multiple linked lists; it looks like this:
________________
/ \
(A,1) -> (B,2) -> (A,3) -> (C,4) -> (B,5) -> (C,6) -> (A,7)
\________\_______/\________________/_________________/
\_______________________/
Internally, every node has a pointer to the next node in the sequence, as well as the next node with the same key, and a hash table maintains a mapping from keys to the first node with that key.
Unfortunately, this doesn't allow for efficient in-place insertions or replacements. For example, to replace (C,4)
with (B,8)
, I'd have to walk backwards an arbitrarily long way to find (B,2)
in order to update its "next of same key" pointer.
The best idea I have to far is to associate each element with a sequence number, and keep a sorted set for each key. But to insert in the middle of the sequence, I would need infinitely divisible sequence numbers.
(By the way, I'm implementing this in C++, but I'm just looking for a description of a data structure that would work. If there's a pre-existing library that would work that would be great, but even boost::multi_index_container
doesn't seem up to the task.)