github.com/searKing/golang/go@v1.2.117/exp/maps/nested.go (about) 1 // Copyright 2023 The searKing Author. 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 package maps 6 7 // A NestedMap is a map which, when it cannot find an element in itself, defers to another map. 8 // Modifications, however, are passed on to the supermap. 9 // It is used to implement nested namespaces, such as those which store local-variable bindings. 10 type NestedMap[K comparable] map[K]any 11 12 // Load returns the value stored in the map for a key, or nil if no 13 // value is present. 14 // The ok result indicates whether value was found in the map. 15 func (m NestedMap[K]) Load(keys []K) (value any, ok bool) { 16 nm := m 17 l := len(keys) - 1 18 for i, k := range keys { 19 m2, ok := nm[k] 20 // last key 21 if i == l { 22 return m2, ok 23 } 24 25 if !ok { 26 return nil, false 27 } 28 m3, ok := m2.(NestedMap[K]) 29 if !ok { 30 return nil, false 31 } 32 // continue search from here 33 nm = m3 34 } 35 return nil, false 36 } 37 38 // Store sets the value for a key. 39 func (m NestedMap[K]) Store(keys []K, value any) { 40 nm := m 41 l := len(keys) - 1 42 for i, k := range keys { 43 // last key 44 if i == l { 45 nm[k] = value 46 return 47 } 48 49 m2, ok := nm[k] 50 if !ok { 51 // intermediate key does not exist 52 // => create it and continue from there 53 m3 := make(NestedMap[K]) 54 nm[k] = m3 55 nm = m3 56 continue 57 } 58 59 m3, ok := m2.(NestedMap[K]) 60 if !ok { 61 // intermediate key is a value 62 // => replace with a new map 63 m3 = make(NestedMap[K]) 64 nm[k] = m3 65 } 66 // continue search from here 67 nm = m3 68 } 69 } 70 71 // LoadOrStore returns the existing value for the key if present. 72 // Otherwise, it stores and returns the given value. 73 // The loaded result is true if the value was loaded, false if stored. 74 func (m NestedMap[K]) LoadOrStore(keys []K, value any) (actual any, loaded bool) { 75 nm := m 76 l := len(keys) - 1 77 for i, k := range keys { 78 m2, ok := nm[k] 79 // last key 80 if i == l { 81 if ok { 82 return m2, true 83 } 84 if !ok { 85 nm[k] = value 86 return value, false 87 } 88 } 89 if !ok { 90 // intermediate key does not exist 91 // => create it and continue from there 92 m3 := make(NestedMap[K]) 93 nm[k] = m3 94 nm = m3 95 continue 96 } 97 98 m3, ok := m2.(NestedMap[K]) 99 if !ok { 100 // intermediate key is a value 101 // => replace with a new map 102 m3 = make(NestedMap[K]) 103 nm[k] = m3 104 } 105 // continue search from here 106 nm = m3 107 } 108 return nil, false 109 } 110 111 // LoadAndDelete deletes the value for a key, returning the previous value if any. 112 // The loaded result reports whether the key was present. 113 func (m NestedMap[K]) LoadAndDelete(keys []K) (value any, loaded bool) { 114 nm := m 115 l := len(keys) - 1 116 for i, k := range keys { 117 m2, ok := nm[k] 118 if !ok { 119 return 120 } 121 // last key 122 if i == l { 123 delete(nm, k) 124 return m2, true 125 } 126 m3, ok := m2.(NestedMap[K]) 127 if !ok { 128 return 129 } 130 // continue search from here 131 nm = m3 132 } 133 return nil, false 134 } 135 136 // Delete deletes the value for a key. 137 func (m NestedMap[K]) Delete(keys []K) { 138 nm := m 139 l := len(keys) - 1 140 for i, k := range keys { 141 m2, ok := nm[k] 142 if !ok { 143 return 144 } 145 // last key 146 if i == l { 147 delete(nm, k) 148 return 149 } 150 m3, ok := m2.(NestedMap[K]) 151 if !ok { 152 return 153 } 154 // continue search from here 155 nm = m3 156 } 157 } 158 159 // Swap swaps the value for a key and returns the previous value if any. 160 // The loaded result reports whether the key was present. 161 func (m NestedMap[K]) Swap(keys []K, value any) (previous any, loaded bool) { 162 nm := m 163 l := len(keys) - 1 164 for i, k := range keys { 165 m2, ok := nm[k] 166 // last key 167 if i == l { 168 nm[k] = value 169 return m2, ok 170 } 171 if !ok { 172 // intermediate key does not exist 173 // => create it and continue from there 174 m3 := make(NestedMap[K]) 175 nm[k] = m3 176 nm = m3 177 continue 178 } 179 m3, ok := m2.(NestedMap[K]) 180 if !ok { 181 // intermediate key is a value 182 // => replace with a new map 183 m3 = make(NestedMap[K]) 184 nm[k] = m3 185 } 186 // continue search from here 187 nm = m3 188 } 189 return nil, false 190 } 191 192 // CompareAndSwap swaps the old and new values for key 193 // if the value stored in the map is equal to old. 194 // The old value must be of a comparable type. 195 func (m NestedMap[K]) CompareAndSwap(keys []K, old, new any) bool { 196 nm := m 197 l := len(keys) - 1 198 for i, k := range keys { 199 m2, ok := nm[k] 200 // last key 201 if i == l { 202 if ok && m2 == old { 203 nm[k] = new 204 return true 205 } 206 return false 207 } 208 if !ok { 209 // intermediate key does not exist 210 // => create it and continue from there 211 m3 := make(NestedMap[K]) 212 nm[k] = m3 213 nm = m3 214 continue 215 } 216 m3, ok := m2.(NestedMap[K]) 217 if !ok { 218 // intermediate key is a value 219 // => replace with a new map 220 m3 = make(NestedMap[K]) 221 nm[k] = m3 222 } 223 // continue search from here 224 nm = m3 225 } 226 return false 227 } 228 229 // CompareAndDelete deletes the entry for key if its value is equal to old. 230 // The old value must be of a comparable type. 231 // 232 // If there is no current value for key in the map, CompareAndDelete 233 // returns false (even if the old value is the nil interface value). 234 func (m NestedMap[K]) CompareAndDelete(keys []K, old any) (deleted bool) { 235 nm := m 236 l := len(keys) - 1 237 for i, k := range keys { 238 m2, ok := nm[k] 239 if !ok { 240 return false 241 } 242 // last key 243 if i == l { 244 if m2 == old { 245 delete(nm, k) 246 return true 247 } 248 return false 249 } 250 m3, ok := m2.(NestedMap[K]) 251 if !ok { 252 return false 253 } 254 // continue search from here 255 nm = m3 256 } 257 return false 258 } 259 260 // Range calls f sequentially for each key and value present in the map. 261 // If f returns false, range stops the iteration. 262 // 263 // Range does not necessarily correspond to any consistent snapshot of the Map's 264 // contents: no key will be visited more than once, but if the value for any key 265 // is stored or deleted concurrently (including by f), Range may reflect any 266 // mapping for that key from any point during the Range call. Range does not 267 // block other methods on the receiver; even f itself may call any method on m. 268 // 269 // Range may be O(N) with the number of elements in the map even if f returns 270 // false after a constant number of calls. 271 func (m NestedMap[K]) Range(f func(keys []K, value any) bool) { 272 m.ranges(nil, f) 273 } 274 275 func (m NestedMap[K]) ranges(ks []K, f func(keys []K, value any) bool) { 276 for k, v := range m { 277 ks2 := append(ks, k) 278 m2, ok := v.(NestedMap[K]) 279 if !ok { 280 f(ks2, v) 281 continue 282 } 283 m2.ranges(ks2, f) 284 } 285 }