orlp / slotmap

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

get_or_insert for SecondaryMap #96

Closed gzp79 closed 1 year ago

gzp79 commented 1 year ago

I have a SecondaryMap that is updated eventually: it may contain previous versions of an Id for a while and updated only on demand. I'm looking for an get_or_insert feature on the map and this is what I could put together with the current API:

pub fn foo() {

    let mut sm = SlotMap::<Id, usize>::default();
    let mut ssm = SecondaryMap::<Id, usize>::default();

    let node_id = sm.insert(2);

    {
        // let data =  ssm.get_or_insert(node_id, Default::default);
        let data = match ssm.entry(node_id) {
            Some(entry) => entry.or_insert_with(Default::default),
            None => {
                ssm.insert(node_id, Default::default());
                ssm.get_mut(node_id).unwrap()
            }
        };

        *data = 22;
    }

    println!("out: {:?}", ssm.get(node_id));
}

Is there any better, alternative option

orlp commented 1 year ago

For the moment, no, this is the best option I can think of. You can wrap it in a function to make it more convenient though.

Keep in mind that if entry returns None that then either the key was invalid or outdated compared to what's in the SecondaryMap. So ssm.entry(node_id).expect("outdated/invalid key").or_insert_with(Default::default) might also do what you want.

gzp79 commented 1 year ago

Do you mean entry returns none only if the id is older than the current version in the map and for any other version that is not older than the one stored in the secondarymap an entry is returned ? If so than thank's this is just what I needed and the issue can be closed.