puzpuzpuz / xsync

Concurrent data structures for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Store based on previous value

german94 opened this issue · comments

Hello,

First of all thanks for this package, I really like it and I'm using it in a few of my side projects.

I just wanted to ask something regarding the MapOf type. Is there a way to store for a key, based on the previous value, atomically?

For example, I'm doing this:

	var new []string
	old, ok := ms.data.Load(id)
	if ok {
		new = old
	}
	new = append(new, values...)
	ms.data.Store(id, new)

however I'd like to do it in an atomic way, everything in a function.

Thanks.

Thanks for the feedback!

As for updating a value atomically, that's simple. You just need to use Compute method:

func main() {
	ms := xsync.NewMapOf[int, []string]()

	id := 42
	values := make([]string, 3)
	// Update the value atomically.
	v, ok := ms.Compute(id, func(oldValue []string, loaded bool) (newValue []string, delete bool) {
		if loaded { // Existing key case
			// It's important to allocate a new slice each time we mutate a value.
			// That's to avoid races with concurrent readers.
			newValue = append(make([]string, 0, len(oldValue)+len(values)), oldValue...)
			newValue = append(newValue, values...)
		} else { // New key case
			newValue = values
		}
		delete = false
		return
	})
	fmt.Printf("v: %v, ok: %v\n", v, ok)
}