Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request: get_or_insert method #169

Closed
laralove143 opened this issue Dec 19, 2021 · 6 comments
Closed

feature request: get_or_insert method #169

laralove143 opened this issue Dec 19, 2021 · 6 comments

Comments

@laralove143
Copy link

a utility method to do this, possibly more optimized, would be nice since i think it's used very often

let key = key();
let value = match dashmap.get(key) {
    Some(value) => value,
    None => {
        let default = default();
        dashmap.insert(key, default);
        default
    }
}

this way we could just do let value = dashmap.get_or_insert(key(), default());

@wangnengjie
Copy link

If dashmap.get returns None, then there is no lock guard for target shard and dashmap.insert may replace some value.
The dashmap.entry api can do this by

let dashmap = DashMap::<String, i32>::new();
dashmap.insert("a".to_string(), 1);
{
    let entry = dashmap.entry("a".to_string());
    match entry {
        Entry::Occupied(ref o) => println!("{}", o.get()),
        Entry::Vacant(_) => panic!("should not go here"),
    }
}
{
    let entry = dashmap.entry("b".to_string());
    match entry {
        Entry::Occupied(_) => panic!("should not go here"),
        Entry::Vacant(vacant) => {
            vacant.insert(2);
        }
    }
}
println!("{}", dashmap.get("b").unwrap().value());

Both OccupiedEntry and VacantEntry has a write guard to target shard so it's safe. (I don't know whether this api is stable?)
Problem is that OccupiedEntry will keep a write guard and for get_or_insert situation maybe you need a read guard? It seems that parking_lot provide some method to upgrade or downgrade the guard but I'm not so familiar with them.
I'm new to rust language. Please tell me if I have something wrong in the example code.

@laralove143
Copy link
Author

do you mean this is how it could be implemented? i don’t know how dashmap’s private code works but one of the contributors could probably come up with the best solution using methods that aren’t exposed publicly

@wangnengjie
Copy link

wangnengjie commented Jan 11, 2022

not exactly. I just show that your example code is not concurrent safe and if you had used it in your project to temporarily fill the lack of get_or_insert, you may need to have a look on your code. Just a kindly reminder...
my example is only a compromise for the lack of api at this moment. It's sure that contributors can implemented it in a nice and effective way.

@xacrimon
Copy link
Owner

xacrimon commented Feb 6, 2022

The entry API is stable and this is one of it's intended use cases. If this doesn't work for you and you have a proposition for a better API, please reopen. Closing as I don't want two API's that does the same thing. This is still a fairly niche use case which is why it's under the entry API.

@AshleySchaeffer
Copy link

For those stumbling across this in future. See a possible solution here:

#292 (comment)

@geekbeast
Copy link

So I took a crack at implementing this here (#293) for reason mentioned in #78 #292. The work around in #292 works great, but ends up computing the usize hash and shard twice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants