Source file src/sync/hashtriemap.go
1 // Copyright 2024 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build goexperiment.synchashtriemap 6 7 package sync 8 9 import ( 10 isync "internal/sync" 11 ) 12 13 // Map is like a Go map[any]any but is safe for concurrent use 14 // by multiple goroutines without additional locking or coordination. 15 // Loads, stores, and deletes run in amortized constant time. 16 // 17 // The Map type is specialized. Most code should use a plain Go map instead, 18 // with separate locking or coordination, for better type safety and to make it 19 // easier to maintain other invariants along with the map content. 20 // 21 // The Map type is optimized for two common use cases: (1) when the entry for a given 22 // key is only ever written once but read many times, as in caches that only grow, 23 // or (2) when multiple goroutines read, write, and overwrite entries for disjoint 24 // sets of keys. In these two cases, use of a Map may significantly reduce lock 25 // contention compared to a Go map paired with a separate [Mutex] or [RWMutex]. 26 // 27 // The zero Map is empty and ready for use. A Map must not be copied after first use. 28 // 29 // In the terminology of [the Go memory model], Map arranges that a write operation 30 // “synchronizes before” any read operation that observes the effect of the write, where 31 // read and write operations are defined as follows. 32 // [Map.Load], [Map.LoadAndDelete], [Map.LoadOrStore], [Map.Swap], [Map.CompareAndSwap], 33 // and [Map.CompareAndDelete] are read operations; 34 // [Map.Delete], [Map.LoadAndDelete], [Map.Store], and [Map.Swap] are write operations; 35 // [Map.LoadOrStore] is a write operation when it returns loaded set to false; 36 // [Map.CompareAndSwap] is a write operation when it returns swapped set to true; 37 // and [Map.CompareAndDelete] is a write operation when it returns deleted set to true. 38 // 39 // [the Go memory model]: https://go.dev/ref/mem 40 type Map struct { 41 _ noCopy 42 43 m isync.HashTrieMap[any, any] 44 } 45 46 // Load returns the value stored in the map for a key, or nil if no 47 // value is present. 48 // The ok result indicates whether value was found in the map. 49 func (m *Map) Load(key any) (value any, ok bool) { 50 return m.m.Load(key) 51 } 52 53 // Store sets the value for a key. 54 func (m *Map) Store(key, value any) { 55 m.m.Store(key, value) 56 } 57 58 // Clear deletes all the entries, resulting in an empty Map. 59 func (m *Map) Clear() { 60 m.m.Clear() 61 } 62 63 // LoadOrStore returns the existing value for the key if present. 64 // Otherwise, it stores and returns the given value. 65 // The loaded result is true if the value was loaded, false if stored. 66 func (m *Map) LoadOrStore(key, value any) (actual any, loaded bool) { 67 return m.m.LoadOrStore(key, value) 68 } 69 70 // LoadAndDelete deletes the value for a key, returning the previous value if any. 71 // The loaded result reports whether the key was present. 72 func (m *Map) LoadAndDelete(key any) (value any, loaded bool) { 73 return m.m.LoadAndDelete(key) 74 } 75 76 // Delete deletes the value for a key. 77 func (m *Map) Delete(key any) { 78 m.m.Delete(key) 79 } 80 81 // Swap swaps the value for a key and returns the previous value if any. 82 // The loaded result reports whether the key was present. 83 func (m *Map) Swap(key, value any) (previous any, loaded bool) { 84 return m.m.Swap(key, value) 85 } 86 87 // CompareAndSwap swaps the old and new values for key 88 // if the value stored in the map is equal to old. 89 // The old value must be of a comparable type. 90 func (m *Map) CompareAndSwap(key, old, new any) (swapped bool) { 91 return m.m.CompareAndSwap(key, old, new) 92 } 93 94 // CompareAndDelete deletes the entry for key if its value is equal to old. 95 // The old value must be of a comparable type. 96 // 97 // If there is no current value for key in the map, CompareAndDelete 98 // returns false (even if the old value is the nil interface value). 99 func (m *Map) CompareAndDelete(key, old any) (deleted bool) { 100 return m.m.CompareAndDelete(key, old) 101 } 102 103 // Range calls f sequentially for each key and value present in the map. 104 // If f returns false, range stops the iteration. 105 // 106 // Range does not necessarily correspond to any consistent snapshot of the Map's 107 // contents: no key will be visited more than once, but if the value for any key 108 // is stored or deleted concurrently (including by f), Range may reflect any 109 // mapping for that key from any point during the Range call. Range does not 110 // block other methods on the receiver; even f itself may call any method on m. 111 // 112 // Range may be O(N) with the number of elements in the map even if f returns 113 // false after a constant number of calls. 114 func (m *Map) Range(f func(key, value any) bool) { 115 m.m.Range(f) 116 } 117