mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-16 18:08:40 +00:00
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>
This commit is contained in:
parent
89ee6bbdae
commit
910b4e8e6a
@ -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…
x
Reference in New Issue
Block a user