slotmap icon indicating copy to clipboard operation
slotmap copied to clipboard

Allow converting values, preserving keys

Open NickNick opened this issue 3 years ago • 4 comments

I have a slotmap like <FooID, FooV1> and now I'd like to make <FooID, FooV2>, without changing the keys. Is there some way I can do this? I couldn't figure it out. Thanks.

NickNick avatar Nov 17 '21 20:11 NickNick

Right now there isn't a direct way to do this on a slotmap. You could have the keys allocated by one slotmap and then store the values in a SecondaryMap. You can have multiple SecondaryMaps with the same key, so creating a v2 shouldn't be an issue.

orlp avatar Nov 17 '21 22:11 orlp

Same requirement here. Though it took a lot of debugging to even notice the source of my problem...

I layout a graph. The layout happens in sequential process steps. In each step I need some shared and some different data. When I convert the nodes they get new keys. But the edges and other data structure still refer to the old indices. And since the keys are of the same type, this went unnoticed for a while and was really hard to debug, when I eventually noticed it.

Update the references to nodes (the keys) would take a lot of computing time. There usually are much more references to nodes than there are nodes.

I havn't looked into using a SecondaryMap yet. What is the impact of using SecondaryMap on cache locality?

NeverGivinUp avatar Feb 11 '22 13:02 NeverGivinUp

@orlp Using SecondaryMap works well, generally. And the conversion quite easy, too. I have some duplicate data now, but that isn't so bad, and could be remedied, if it proved problematic.

One problem I noted is that when iterating over the secondary map after removing an element from the primary, but not from the secondary, the removed element still is iterated.

NeverGivinUp avatar Feb 28 '22 07:02 NeverGivinUp

@NeverGivinUp

One problem I noted is that when iterating over the secondary map after removing an element from the primary, but not from the secondary, the removed element still is iterated.

Yes, a SecondaryMap is completely independent from its primary map. It can re-use slots so old things get deleted automatically eventually if their space is needed, but nothing is guaranteed. If you want them to stay synced you have to perform a delete on a primary map and all secondary maps.

Note that I do think I will implement the following function in slotmap 2.0, when I have the time and energy to make it:

pub fn map<U, F>(self, f: F) -> SlotMap<K, U>
where F: FnMut((K, V) -> U)

orlp avatar Feb 28 '22 11:02 orlp