-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
sync: add new Map method LoadAndDelete #33762
Comments
CC @bcmills |
On a cosmetic note, I would want to name the method |
I'm curious what the concrete use-cases are. (The proposed operation seems useful in theory, but I wonder whether it actually is in practice.) Could you give some examples of existing code using |
A practical example would be using sync.Map as an in-memory cache above a remote database. Since database
|
That example seems racy, though: nothing in
Now your cache is out of sync with the underlying database: the cache contains no mapping for I suspect that you'll find this sort of insert/delete race in most concrete examples, and the fix is generally to add some other exclusion mechanism (for example, a |
By that logic, shouldn't
By the time Ultimately, I don't think there is an expectation that the In my specific use case, deletes happen substantially later than adds, so there is never |
Ping @bcmills |
Ok, I think I can see what you mean. For example, you may have a wave of In that case, I'd be ok with a new method with a signature along the lines of: func (m *Map) Remove(key interface{}) (prevValue interface{}, removed bool) |
Why call it Remove? Then we'd have Delete and Remove, with no obvious distinction between them (but a big difference). We have LoadOrStore already; why is this not LoadAndDelete? |
For me “delete” carries the connotation of destroying the thing to be deleted, especially “by blotting out, cutting out, or erasing”. The proposed function erases a key or entry from the map, but does not erase the corresponding value; in contrast, a In contrast, “remove” carries the connotation of “[changing] the location, position, station, or residence of” the thing, which is what we are doing with the proposed function: changing the location (of the reference to the value) from the map to the caller.
I would be ok with naming it |
My preference would be naming this |
@wkonkel, I don't think we need to deprecate |
@bcmills, I admire your precision with the different meanings of delete and remove but I don't think many users will see that distinction. I retitled this to be about adding Are there any objections to adding LoadAndDelete? |
Rereading the thread, based on this discussion it seems like this is a likely accept. Leaving open for a week for final comments. |
Accepted. |
Change https://golang.org/cl/205899 mentions this issue: |
Problem
It is not currently possible to determine if a value was deleted from a sync.Map. For example:
This is not atomic in that another goroutine could Delete the value between Load and Delete and
doSomething()
would be called twice.Previous issues #25396 and #23547 suggested modifying
Delete
signature which would break backwards compatibility.Solution
Create a new function:
If the key is found in the map, this function would return the deleted value and
true
. If the value is not found, this would returnnil, false
. The above code would then become:The text was updated successfully, but these errors were encountered: