orlp / slotmap

Slotmap data structure for Rust
zlib License
1.12k stars 70 forks source link

Additional functionality, like extend, append, and PartialEq #38

Closed CGMossa closed 4 years ago

CGMossa commented 4 years ago

Hey! This crate is great. I've just noticed that this crate is missing some nice API-stuff that Vec and HashMap has, such as Extend and .append, where you can feed it an iterator, and then that being inserted into the DenseMap.

I'd love to contribute that, but am I missing something? Maybe we can make a list or something here.

orlp commented 4 years ago

It's intentional that you can't feed it an iterator of values which then get inserted. In such a scenario you would not know which keys the values are stored under, so it would most likely confuse the user. A slotmap is not an ordered data structure, so 'append' doesn't make sense either.

PartialEq is defined for secondary maps because they have a clear meaning there. But I'm not sure how you'd define equality on a primary slot map in an efficient and clear way.

CGMossa commented 4 years ago

Thanks. This is very useful to know. Can I ask what about a shrink function? I want to have a the deleted keys be "flushed" so that my SecondayMap no longer contain deleted agents. But this only happens when the storage has been recycled.

CGMossa commented 4 years ago

Is it not possible to return an iterator containing keys for the newly inserted/"extended" elements?

orlp commented 4 years ago

Can I ask what about a shrink function? I want to have a the deleted keys be "flushed" so that my SecondayMap no longer contain deleted agents. But this only happens when the storage has been recycled.

Can you be more specific?

If you want your secondary map to not lazily delete elements you should delete it yourself from the secondary map right when you delete it from the primary one. An operation you're describing can be very costly to implement, if I understand you correctly.

Is it not possible to return an iterator containing keys for the newly inserted/"extended" elements?

In theory, but then it would not be the Extend trait anymore and something custom. I don't think this operation is common enough to warrant an API for it. You can already do this yourself, suppose you have a vector of objects objs you can write

let keys_iter = objs.into_iter().map(|obj| sm.insert(obj));

to insert them into the slot map get an iterator over the keys.

CGMossa commented 4 years ago

Okay, I ended up doing that, and it is actually better that this is done on my end. Thanks! I'll close this issue.

emilk commented 1 year ago

PartialEq is defined for secondary maps because they have a clear meaning there. But I'm not sure how you'd define equality on a primary slot map in an efficient and clear way.

I think this makes sense for most people:

a.len() == b.len() && a.iter().all(|(key, value)| b.get(key) == Some(value))

This will handle cases like cloning a SlotMap, maybe mutating it, then comparing it with the original to see if they are still equal. It will also correctly handle the case where you construct two slotmaps in the same way