[xsync.MapOf] Atomically delete a value based on value's state?
alberto-miranda opened this issue Β· comments
Hi! We are using xsync.MapOf
for a couple of projects (great package btw π ) and we recently have a new use case where we would need to delete a value atomically if and only if such value meets certain conditions. Basically something like this:
func main() {
ms := xsync.NewMapOf[int, []string]()
id := 42
// Delete the value atomically if and only if someCondition and someOtherCondition are true
v, deleted := ms.DeleteIf(id, func(value []string) bool {
if someCondition(value) && someOtherCondition(value) {
return true
}
return false
})
// If the value was deleted, we can use it safely since it's not in the map anymore
if deleted {
fmt.Printf("v: %v\n", v)
}
}
Is there a way to do this with MapOf
? If there isn't and the implementation is not very complex, would you accept a contribution for this?
Hello,
You can use Compute
for this purpose: if it's delete
return value is true, the key will be deleted. See the Delete an existing value
part of the doc example.
Thanks for the prompt response. Is a strict ordering guaranteed between competing calls to Compute()
and Load()
in different goroutines? We wrote a small test to validate our implementation, where a goroutine tries to Load()
a key concurrently with a deletion, and it looks like Load()
is able to find the value while the valueFn
passed to Compute
is being executed. We assumed that once valueFn
started its execution, other goroutines would be blocked until it completed, but maybe we were wrong about this?
Writes, e.g. Compute
or Store
or Delete
, never block reads, e.g. Load
or Range
. That's the reason why MapOf
reads scale in terms of core/goroutine count. In your case, you could try using Compute
for both reads and writes - readers may simply read the key and do something about it while writers will be deleting it based on a condition. Just make sure to do this in the function provided to the Compute
call - otherwise, as soon as your code leaves the function, a concurrent reader/writer may do something with the key.
Great, thanks, we will attempt what you propose. It will not be as performant as it could, but it will be consistent which is what we need right now.