aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/sync/map.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/sync/map.go')
-rw-r--r--libgo/go/sync/map.go45
1 files changed, 23 insertions, 22 deletions
diff --git a/libgo/go/sync/map.go b/libgo/go/sync/map.go
index dfb62dd..2fa3253 100644
--- a/libgo/go/sync/map.go
+++ b/libgo/go/sync/map.go
@@ -48,7 +48,7 @@ type Map struct {
//
// If the dirty map is nil, the next write to the map will initialize it by
// making a shallow copy of the clean map, omitting stale entries.
- dirty map[interface{}]*entry
+ dirty map[any]*entry
// misses counts the number of loads since the read map was last updated that
// needed to lock mu to determine whether the key was present.
@@ -61,13 +61,13 @@ type Map struct {
// readOnly is an immutable struct stored atomically in the Map.read field.
type readOnly struct {
- m map[interface{}]*entry
+ m map[any]*entry
amended bool // true if the dirty map contains some key not in m.
}
// expunged is an arbitrary pointer that marks entries which have been deleted
// from the dirty map.
-var expunged = unsafe.Pointer(new(interface{}))
+var expunged = unsafe.Pointer(new(any))
// An entry is a slot in the map corresponding to a particular key.
type entry struct {
@@ -93,14 +93,14 @@ type entry struct {
p unsafe.Pointer // *interface{}
}
-func newEntry(i interface{}) *entry {
+func newEntry(i any) *entry {
return &entry{p: unsafe.Pointer(&i)}
}
// Load returns the value stored in the map for a key, or nil if no
// value is present.
// The ok result indicates whether value was found in the map.
-func (m *Map) Load(key interface{}) (value interface{}, ok bool) {
+func (m *Map) Load(key any) (value any, ok bool) {
read, _ := m.read.Load().(readOnly)
e, ok := read.m[key]
if !ok && read.amended {
@@ -125,16 +125,16 @@ func (m *Map) Load(key interface{}) (value interface{}, ok bool) {
return e.load()
}
-func (e *entry) load() (value interface{}, ok bool) {
+func (e *entry) load() (value any, ok bool) {
p := atomic.LoadPointer(&e.p)
if p == nil || p == expunged {
return nil, false
}
- return *(*interface{})(p), true
+ return *(*any)(p), true
}
// Store sets the value for a key.
-func (m *Map) Store(key, value interface{}) {
+func (m *Map) Store(key, value any) {
read, _ := m.read.Load().(readOnly)
if e, ok := read.m[key]; ok && e.tryStore(&value) {
return
@@ -167,7 +167,7 @@ func (m *Map) Store(key, value interface{}) {
//
// If the entry is expunged, tryStore returns false and leaves the entry
// unchanged.
-func (e *entry) tryStore(i *interface{}) bool {
+func (e *entry) tryStore(i *any) bool {
for {
p := atomic.LoadPointer(&e.p)
if p == expunged {
@@ -190,14 +190,14 @@ func (e *entry) unexpungeLocked() (wasExpunged bool) {
// storeLocked unconditionally stores a value to the entry.
//
// The entry must be known not to be expunged.
-func (e *entry) storeLocked(i *interface{}) {
+func (e *entry) storeLocked(i *any) {
atomic.StorePointer(&e.p, unsafe.Pointer(i))
}
// LoadOrStore returns the existing value for the key if present.
// Otherwise, it stores and returns the given value.
// The loaded result is true if the value was loaded, false if stored.
-func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {
+func (m *Map) LoadOrStore(key, value any) (actual any, loaded bool) {
// Avoid locking if it's a clean hit.
read, _ := m.read.Load().(readOnly)
if e, ok := read.m[key]; ok {
@@ -237,13 +237,13 @@ func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bo
//
// If the entry is expunged, tryLoadOrStore leaves the entry unchanged and
// returns with ok==false.
-func (e *entry) tryLoadOrStore(i interface{}) (actual interface{}, loaded, ok bool) {
+func (e *entry) tryLoadOrStore(i any) (actual any, loaded, ok bool) {
p := atomic.LoadPointer(&e.p)
if p == expunged {
return nil, false, false
}
if p != nil {
- return *(*interface{})(p), true, true
+ return *(*any)(p), true, true
}
// Copy the interface after the first load to make this method more amenable
@@ -259,14 +259,14 @@ func (e *entry) tryLoadOrStore(i interface{}) (actual interface{}, loaded, ok bo
return nil, false, false
}
if p != nil {
- return *(*interface{})(p), true, true
+ return *(*any)(p), true, true
}
}
}
// LoadAndDelete deletes the value for a key, returning the previous value if any.
// The loaded result reports whether the key was present.
-func (m *Map) LoadAndDelete(key interface{}) (value interface{}, loaded bool) {
+func (m *Map) LoadAndDelete(key any) (value any, loaded bool) {
read, _ := m.read.Load().(readOnly)
e, ok := read.m[key]
if !ok && read.amended {
@@ -290,18 +290,18 @@ func (m *Map) LoadAndDelete(key interface{}) (value interface{}, loaded bool) {
}
// Delete deletes the value for a key.
-func (m *Map) Delete(key interface{}) {
+func (m *Map) Delete(key any) {
m.LoadAndDelete(key)
}
-func (e *entry) delete() (value interface{}, ok bool) {
+func (e *entry) delete() (value any, ok bool) {
for {
p := atomic.LoadPointer(&e.p)
if p == nil || p == expunged {
return nil, false
}
if atomic.CompareAndSwapPointer(&e.p, p, nil) {
- return *(*interface{})(p), true
+ return *(*any)(p), true
}
}
}
@@ -311,12 +311,13 @@ func (e *entry) delete() (value interface{}, ok bool) {
//
// Range does not necessarily correspond to any consistent snapshot of the Map's
// contents: no key will be visited more than once, but if the value for any key
-// is stored or deleted concurrently, Range may reflect any mapping for that key
-// from any point during the Range call.
+// is stored or deleted concurrently (including by f), Range may reflect any
+// mapping for that key from any point during the Range call. Range does not
+// block other methods on the receiver; even f itself may call any method on m.
//
// Range may be O(N) with the number of elements in the map even if f returns
// false after a constant number of calls.
-func (m *Map) Range(f func(key, value interface{}) bool) {
+func (m *Map) Range(f func(key, value any) bool) {
// We need to be able to iterate over all of the keys that were already
// present at the start of the call to Range.
// If read.amended is false, then read.m satisfies that property without
@@ -365,7 +366,7 @@ func (m *Map) dirtyLocked() {
}
read, _ := m.read.Load().(readOnly)
- m.dirty = make(map[interface{}]*entry, len(read.m))
+ m.dirty = make(map[any]*entry, len(read.m))
for k, e := range read.m {
if !e.tryExpungeLocked() {
m.dirty[k] = e