-
Notifications
You must be signed in to change notification settings - Fork 223
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
Mappable RwLock guards #83
Comments
If you look at the docs, However it is not implemented for |
Looking at your example, you might want to defer calling |
@Amanieu indeed the non-upgradable ones have |
I'm not exactly sure what you are using this for, but generally speaking in most cases you will be returning an existing entry rather than inserting a new one. You could try explicitly optimizing for this case by first attempting to just read from the map with a normal read lock. If that fails then you can release the read lock and grab a write lock, with which you attempt a lookup again and only insert if that lookup fails as well. This is slightly less efficient in the case where an insertion is needed, but if that is relatively rare then the overall performance should improve. |
@Amanieu I think you understand my use case. Getting a read lock followed by a possible write lock has the following downsides for me:
fn get_or_create_with<F: FnOnce() -> V>(lock: RwLock<Self>, key: Key, create_fn: F) -> &V {...} In other words, I'd like this function to borrow the lock immutably and return something that can be de-referenced into the value. If this function tries to mess with locking internally in any way, there is no ability to return such a value wrapper any more. |
@kvark Here's a quick sketch of how this would look like: fn get_or_create_with<F: FnOnce() -> V>(lock: &RwLock<Self>, key: Key, create_fn: F) -> MappedRwLockReadGuard<V> {
{
let guard = RwLockReadGuard::map(lock.read(), |map| map.get(key));
if guard.is_some() {
return RwLockReadGuard::map(guard, |opt| opt.unwrap());
}
}
RwLockWriteGuard::map(lock.write(), |map| map.entry(key).or_insert_with(create_fn)).downgrade()
} |
@Amanieu |
Also cc-ing @gankro on the last comment here ^ |
@kvark Oh, good point, I missed that. It seems that there is no way to avoid a double lookup with the current API then: let guard = lock.read();
if guard.contains_key(key) {
return RwLockReadGuard::map(guard, |map| map.get(key).unwrap());
} I think we could add a |
Try_map would be great to have indeed.
… On Jul 17, 2018, at 18:19, Amanieu ***@***.***> wrote:
@kvark Oh, good point, I missed that. It seems that there is no way to avoid a double lookup with the current API then:
let guard = lock.read();
if guard.contains_key(key) {
return RwLockReadGuard::map(guard, |map| map.get(key).unwrap());
}
I think we could add a try_map API for this use case, if there is sufficient motivation.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@Amanieu heads up, we happen to need |
It it now available in |
This is a logical continuation of #10. It looks like the
MappableMutexGuard
is implemented, but nothing is done forRwLock
. We have a strong case for it: a map with data that needs to be either read or created and then read. Ideally, it would have the following implementation (roughly):The text was updated successfully, but these errors were encountered: