syncs: add iterators to Map (#13739)

Add Keys, Values, and All to iterate over
all keys, values, and entries, respectively.

Updates #11038

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
pull/13755/head
Joe Tsai 1 month ago committed by GitHub
parent 89ee6bbdae
commit 910b4e8e6a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -6,6 +6,7 @@ package syncs
import ( import (
"context" "context"
"iter"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -256,6 +257,8 @@ func (m *Map[K, V]) Delete(key K) {
// Iteration stops if f returns false. Map changes are blocked during iteration. // Iteration stops if f returns false. Map changes are blocked during iteration.
// A read lock is held for the entire duration of the iteration. // A read lock is held for the entire duration of the iteration.
// Use the [WithLock] method instead to mutate the map during iteration. // Use the [WithLock] method instead to mutate the map during iteration.
//
// Deprecated: Use [All], [Keys], or [Values] instead.
func (m *Map[K, V]) Range(f func(key K, value V) bool) { func (m *Map[K, V]) Range(f func(key K, value V) bool) {
m.mu.RLock() m.mu.RLock()
defer m.mu.RUnlock() defer m.mu.RUnlock()
@ -266,6 +269,51 @@ func (m *Map[K, V]) Range(f func(key K, value V) bool) {
} }
} }
// Keys iterates over all keys in the map in an undefined order.
// A read lock is held for the entire duration of the iteration.
// Use the [WithLock] method instead to mutate the map during iteration.
func (m *Map[K, V]) Keys() iter.Seq[K] {
return func(yield func(K) bool) {
m.mu.RLock()
defer m.mu.RUnlock()
for k := range m.m {
if !yield(k) {
return
}
}
}
}
// Values iterates over all values in the map in an undefined order.
// A read lock is held for the entire duration of the iteration.
// Use the [WithLock] method instead to mutate the map during iteration.
func (m *Map[K, V]) Values() iter.Seq[V] {
return func(yield func(V) bool) {
m.mu.RLock()
defer m.mu.RUnlock()
for _, v := range m.m {
if !yield(v) {
return
}
}
}
}
// All iterates over all entries in the map in an undefined order.
// A read lock is held for the entire duration of the iteration.
// Use the [WithLock] method instead to mutate the map during iteration.
func (m *Map[K, V]) All() iter.Seq2[K, V] {
return func(yield func(K, V) bool) {
m.mu.RLock()
defer m.mu.RUnlock()
for k, v := range m.m {
if !yield(k, v) {
return
}
}
}
}
// WithLock calls f with the underlying map. // WithLock calls f with the underlying map.
// Use of m2 must not escape the duration of this call. // Use of m2 must not escape the duration of this call.
// The write-lock is held for the entire duration of this call. // The write-lock is held for the entire duration of this call.

Loading…
Cancel
Save