github.com/fufuok/utils@v1.0.10/xsync/DOC.md (about) 1 <!-- Code generated by gomarkdoc. DO NOT EDIT --> 2 3 # xsync 4 5 ```go 6 import "github.com/fufuok/utils/xsync" 7 ``` 8 9 ## Index 10 11 - [type Counter](<#Counter>) 12 - [func NewCounter\(\) \*Counter](<#NewCounter>) 13 - [func \(c \*Counter\) Add\(delta int64\)](<#Counter.Add>) 14 - [func \(c \*Counter\) Dec\(\)](<#Counter.Dec>) 15 - [func \(c \*Counter\) Inc\(\)](<#Counter.Inc>) 16 - [func \(c \*Counter\) Reset\(\)](<#Counter.Reset>) 17 - [func \(c \*Counter\) Value\(\) int64](<#Counter.Value>) 18 - [type HashMapOf](<#HashMapOf>) 19 - [type MPMCQueue](<#MPMCQueue>) 20 - [func NewMPMCQueue\(capacity int\) \*MPMCQueue](<#NewMPMCQueue>) 21 - [func \(q \*MPMCQueue\) Dequeue\(\) interface\{\}](<#MPMCQueue.Dequeue>) 22 - [func \(q \*MPMCQueue\) Enqueue\(item interface\{\}\)](<#MPMCQueue.Enqueue>) 23 - [func \(q \*MPMCQueue\) TryDequeue\(\) \(item interface\{\}, ok bool\)](<#MPMCQueue.TryDequeue>) 24 - [func \(q \*MPMCQueue\) TryEnqueue\(item interface\{\}\) bool](<#MPMCQueue.TryEnqueue>) 25 - [type MPMCQueueOf](<#MPMCQueueOf>) 26 - [func NewMPMCQueueOf\[I any\]\(capacity int\) \*MPMCQueueOf\[I\]](<#NewMPMCQueueOf>) 27 - [func \(q \*MPMCQueueOf\[I\]\) Dequeue\(\) I](<#MPMCQueueOf[I].Dequeue>) 28 - [func \(q \*MPMCQueueOf\[I\]\) Enqueue\(item I\)](<#MPMCQueueOf[I].Enqueue>) 29 - [func \(q \*MPMCQueueOf\[I\]\) TryDequeue\(\) \(item I, ok bool\)](<#MPMCQueueOf[I].TryDequeue>) 30 - [func \(q \*MPMCQueueOf\[I\]\) TryEnqueue\(item I\) bool](<#MPMCQueueOf[I].TryEnqueue>) 31 - [type Map](<#Map>) 32 - [func NewMap\(\) \*Map](<#NewMap>) 33 - [func NewMapPresized\(sizeHint int\) \*Map](<#NewMapPresized>) 34 - [func \(m \*Map\) Clear\(\)](<#Map.Clear>) 35 - [func \(m \*Map\) Compute\(key string, valueFn func\(oldValue interface\{\}, loaded bool\) \(newValue interface\{\}, delete bool\)\) \(actual interface\{\}, ok bool\)](<#Map.Compute>) 36 - [func \(m \*Map\) Delete\(key string\)](<#Map.Delete>) 37 - [func \(m \*Map\) Load\(key string\) \(value interface\{\}, ok bool\)](<#Map.Load>) 38 - [func \(m \*Map\) LoadAndDelete\(key string\) \(value interface\{\}, loaded bool\)](<#Map.LoadAndDelete>) 39 - [func \(m \*Map\) LoadAndStore\(key string, value interface\{\}\) \(actual interface\{\}, loaded bool\)](<#Map.LoadAndStore>) 40 - [func \(m \*Map\) LoadOrCompute\(key string, valueFn func\(\) interface\{\}\) \(actual interface\{\}, loaded bool\)](<#Map.LoadOrCompute>) 41 - [func \(m \*Map\) LoadOrStore\(key string, value interface\{\}\) \(actual interface\{\}, loaded bool\)](<#Map.LoadOrStore>) 42 - [func \(m \*Map\) Range\(f func\(key string, value interface\{\}\) bool\)](<#Map.Range>) 43 - [func \(m \*Map\) Size\(\) int](<#Map.Size>) 44 - [func \(m \*Map\) Store\(key string, value interface\{\}\)](<#Map.Store>) 45 - [type MapOf](<#MapOf>) 46 - [func NewMapOf\[K comparable, V any\]\(\) \*MapOf\[K, V\]](<#NewMapOf>) 47 - [func NewMapOfPresized\[K comparable, V any\]\(sizeHint int\) \*MapOf\[K, V\]](<#NewMapOfPresized>) 48 - [func \(m \*MapOf\[K, V\]\) Clear\(\)](<#MapOf[K, V].Clear>) 49 - [func \(m \*MapOf\[K, V\]\) Compute\(key K, valueFn func\(oldValue V, loaded bool\) \(newValue V, delete bool\)\) \(actual V, ok bool\)](<#MapOf[K, V].Compute>) 50 - [func \(m \*MapOf\[K, V\]\) Delete\(key K\)](<#MapOf[K, V].Delete>) 51 - [func \(m \*MapOf\[K, V\]\) Load\(key K\) \(value V, ok bool\)](<#MapOf[K, V].Load>) 52 - [func \(m \*MapOf\[K, V\]\) LoadAndDelete\(key K\) \(value V, loaded bool\)](<#MapOf[K, V].LoadAndDelete>) 53 - [func \(m \*MapOf\[K, V\]\) LoadAndStore\(key K, value V\) \(actual V, loaded bool\)](<#MapOf[K, V].LoadAndStore>) 54 - [func \(m \*MapOf\[K, V\]\) LoadOrCompute\(key K, valueFn func\(\) V\) \(actual V, loaded bool\)](<#MapOf[K, V].LoadOrCompute>) 55 - [func \(m \*MapOf\[K, V\]\) LoadOrStore\(key K, value V\) \(actual V, loaded bool\)](<#MapOf[K, V].LoadOrStore>) 56 - [func \(m \*MapOf\[K, V\]\) Range\(f func\(key K, value V\) bool\)](<#MapOf[K, V].Range>) 57 - [func \(m \*MapOf\[K, V\]\) Size\(\) int](<#MapOf[K, V].Size>) 58 - [func \(m \*MapOf\[K, V\]\) Store\(key K, value V\)](<#MapOf[K, V].Store>) 59 - [type RBMutex](<#RBMutex>) 60 - [func NewRBMutex\(\) \*RBMutex](<#NewRBMutex>) 61 - [func \(mu \*RBMutex\) Lock\(\)](<#RBMutex.Lock>) 62 - [func \(mu \*RBMutex\) RLock\(\) \*RToken](<#RBMutex.RLock>) 63 - [func \(mu \*RBMutex\) RUnlock\(t \*RToken\)](<#RBMutex.RUnlock>) 64 - [func \(mu \*RBMutex\) Unlock\(\)](<#RBMutex.Unlock>) 65 - [type RToken](<#RToken>) 66 67 68 <a name="Counter"></a> 69 ## type Counter 70 71 A Counter is a striped int64 counter. 72 73 Should be preferred over a single atomically updated int64 counter in high contention scenarios. 74 75 A Counter must not be copied after first use. 76 77 ```go 78 type Counter struct { 79 // contains filtered or unexported fields 80 } 81 ``` 82 83 <a name="NewCounter"></a> 84 ### func NewCounter 85 86 ```go 87 func NewCounter() *Counter 88 ``` 89 90 NewCounter creates a new Counter instance. 91 92 <a name="Counter.Add"></a> 93 ### func \(\*Counter\) Add 94 95 ```go 96 func (c *Counter) Add(delta int64) 97 ``` 98 99 Add adds the delta to the counter. 100 101 <a name="Counter.Dec"></a> 102 ### func \(\*Counter\) Dec 103 104 ```go 105 func (c *Counter) Dec() 106 ``` 107 108 Dec decrements the counter by 1. 109 110 <a name="Counter.Inc"></a> 111 ### func \(\*Counter\) Inc 112 113 ```go 114 func (c *Counter) Inc() 115 ``` 116 117 Inc increments the counter by 1. 118 119 <a name="Counter.Reset"></a> 120 ### func \(\*Counter\) Reset 121 122 ```go 123 func (c *Counter) Reset() 124 ``` 125 126 Reset resets the counter to zero. This method should only be used when it is known that there are no concurrent modifications of the counter. 127 128 <a name="Counter.Value"></a> 129 ### func \(\*Counter\) Value 130 131 ```go 132 func (c *Counter) Value() int64 133 ``` 134 135 Value returns the current counter value. The returned value may not include all of the latest operations in presence of concurrent modifications of the counter. 136 137 <a name="HashMapOf"></a> 138 ## type HashMapOf 139 140 141 142 ```go 143 type HashMapOf[K comparable, V any] interface { 144 // Load returns the value stored in the map for a key, or nil if no 145 // value is present. 146 // The ok result indicates whether value was found in the map. 147 Load(key K) (value V, ok bool) 148 149 // Store sets the value for a key. 150 Store(key K, value V) 151 152 // LoadOrStore returns the existing value for the key if present. 153 // Otherwise, it stores and returns the given value. 154 // The loaded result is true if the value was loaded, false if stored. 155 LoadOrStore(key K, value V) (actual V, loaded bool) 156 157 // LoadAndStore returns the existing value for the key if present, 158 // while setting the new value for the key. 159 // It stores the new value and returns the existing one, if present. 160 // The loaded result is true if the existing value was loaded, 161 // false otherwise. 162 LoadAndStore(key K, value V) (actual V, loaded bool) 163 164 // LoadOrCompute returns the existing value for the key if present. 165 // Otherwise, it computes the value using the provided function and 166 // returns the computed value. The loaded result is true if the value 167 // was loaded, false if stored. 168 LoadOrCompute(key K, valueFn func() V) (actual V, loaded bool) 169 170 // Compute either sets the computed new value for the key or deletes 171 // the value for the key. When the delete result of the valueFn function 172 // is set to true, the value will be deleted, if it exists. When delete 173 // is set to false, the value is updated to the newValue. 174 // The ok result indicates whether value was computed and stored, thus, is 175 // present in the map. The actual result contains the new value in cases where 176 // the value was computed and stored. See the example for a few use cases. 177 Compute( 178 key K, 179 valueFn func(oldValue V, loaded bool) (newValue V, delete bool), 180 ) (actual V, ok bool) 181 182 // LoadAndDelete deletes the value for a key, returning the previous 183 // value if any. The loaded result reports whether the key was 184 // present. 185 LoadAndDelete(key K) (value V, loaded bool) 186 187 // Delete deletes the value for a key. 188 Delete(key K) 189 190 // Range calls f sequentially for each key and value present in the 191 // map. If f returns false, range stops the iteration. 192 // 193 // Range does not necessarily correspond to any consistent snapshot 194 // of the Map's contents: no key will be visited more than once, but 195 // if the value for any key is stored or deleted concurrently, Range 196 // may reflect any mapping for that key from any point during the 197 // Range call. 198 // 199 // It is safe to modify the map while iterating it. However, the 200 // concurrent modification rule apply, i.e. the changes may be not 201 // reflected in the subsequently iterated entries. 202 Range(f func(key K, value V) bool) 203 204 // Clear deletes all keys and values currently stored in the map. 205 Clear() 206 207 // Size returns current size of the map. 208 Size() int 209 } 210 ``` 211 212 <a name="MPMCQueue"></a> 213 ## type MPMCQueue 214 215 A MPMCQueue is a bounded multi\-producer multi\-consumer concurrent queue. 216 217 MPMCQueue instances must be created with NewMPMCQueue function. A MPMCQueue must not be copied after first use. 218 219 Based on the data structure from the following C\+\+ library: https://github.com/rigtorp/MPMCQueue 220 221 ```go 222 type MPMCQueue struct { 223 // contains filtered or unexported fields 224 } 225 ``` 226 227 <a name="NewMPMCQueue"></a> 228 ### func NewMPMCQueue 229 230 ```go 231 func NewMPMCQueue(capacity int) *MPMCQueue 232 ``` 233 234 NewMPMCQueue creates a new MPMCQueue instance with the given capacity. 235 236 <a name="MPMCQueue.Dequeue"></a> 237 ### func \(\*MPMCQueue\) Dequeue 238 239 ```go 240 func (q *MPMCQueue) Dequeue() interface{} 241 ``` 242 243 Dequeue retrieves and removes the item from the head of the queue. Blocks, if the queue is empty. 244 245 <a name="MPMCQueue.Enqueue"></a> 246 ### func \(\*MPMCQueue\) Enqueue 247 248 ```go 249 func (q *MPMCQueue) Enqueue(item interface{}) 250 ``` 251 252 Enqueue inserts the given item into the queue. Blocks, if the queue is full. 253 254 <a name="MPMCQueue.TryDequeue"></a> 255 ### func \(\*MPMCQueue\) TryDequeue 256 257 ```go 258 func (q *MPMCQueue) TryDequeue() (item interface{}, ok bool) 259 ``` 260 261 TryDequeue retrieves and removes the item from the head of the queue. Does not block and returns immediately. The ok result indicates that the queue isn't empty and an item was retrieved. 262 263 <a name="MPMCQueue.TryEnqueue"></a> 264 ### func \(\*MPMCQueue\) TryEnqueue 265 266 ```go 267 func (q *MPMCQueue) TryEnqueue(item interface{}) bool 268 ``` 269 270 TryEnqueue inserts the given item into the queue. Does not block and returns immediately. The result indicates that the queue isn't full and the item was inserted. 271 272 <a name="MPMCQueueOf"></a> 273 ## type MPMCQueueOf 274 275 A MPMCQueueOf is a bounded multi\-producer multi\-consumer concurrent queue. It's a generic version of MPMCQueue. 276 277 MPMCQueue instances must be created with NewMPMCQueueOf function. A MPMCQueueOf must not be copied after first use. 278 279 Based on the data structure from the following C\+\+ library: https://github.com/rigtorp/MPMCQueue 280 281 ```go 282 type MPMCQueueOf[I any] struct { 283 // contains filtered or unexported fields 284 } 285 ``` 286 287 <a name="NewMPMCQueueOf"></a> 288 ### func NewMPMCQueueOf 289 290 ```go 291 func NewMPMCQueueOf[I any](capacity int) *MPMCQueueOf[I] 292 ``` 293 294 NewMPMCQueueOf creates a new MPMCQueueOf instance with the given capacity. 295 296 <a name="MPMCQueueOf[I].Dequeue"></a> 297 ### func \(\*MPMCQueueOf\[I\]\) Dequeue 298 299 ```go 300 func (q *MPMCQueueOf[I]) Dequeue() I 301 ``` 302 303 Dequeue retrieves and removes the item from the head of the queue. Blocks, if the queue is empty. 304 305 <a name="MPMCQueueOf[I].Enqueue"></a> 306 ### func \(\*MPMCQueueOf\[I\]\) Enqueue 307 308 ```go 309 func (q *MPMCQueueOf[I]) Enqueue(item I) 310 ``` 311 312 Enqueue inserts the given item into the queue. Blocks, if the queue is full. 313 314 <a name="MPMCQueueOf[I].TryDequeue"></a> 315 ### func \(\*MPMCQueueOf\[I\]\) TryDequeue 316 317 ```go 318 func (q *MPMCQueueOf[I]) TryDequeue() (item I, ok bool) 319 ``` 320 321 TryDequeue retrieves and removes the item from the head of the queue. Does not block and returns immediately. The ok result indicates that the queue isn't empty and an item was retrieved. 322 323 <a name="MPMCQueueOf[I].TryEnqueue"></a> 324 ### func \(\*MPMCQueueOf\[I\]\) TryEnqueue 325 326 ```go 327 func (q *MPMCQueueOf[I]) TryEnqueue(item I) bool 328 ``` 329 330 TryEnqueue inserts the given item into the queue. Does not block and returns immediately. The result indicates that the queue isn't full and the item was inserted. 331 332 <a name="Map"></a> 333 ## type Map 334 335 Map is like a Go map\[string\]interface\{\} but is safe for concurrent use by multiple goroutines without additional locking or coordination. It follows the interface of sync.Map with a number of valuable extensions like Compute or Size. 336 337 A Map must not be copied after first use. 338 339 Map uses a modified version of Cache\-Line Hash Table \(CLHT\) data structure: https://github.com/LPD-EPFL/CLHT 340 341 CLHT is built around idea to organize the hash table in cache\-line\-sized buckets, so that on all modern CPUs update operations complete with at most one cache\-line transfer. Also, Get operations involve no write to memory, as well as no mutexes or any other sort of locks. Due to this design, in all considered scenarios Map outperforms sync.Map. 342 343 One important difference with sync.Map is that only string keys are supported. That's because Golang standard library does not expose the built\-in hash functions for interface\{\} values. 344 345 ```go 346 type Map struct { 347 // contains filtered or unexported fields 348 } 349 ``` 350 351 <a name="NewMap"></a> 352 ### func NewMap 353 354 ```go 355 func NewMap() *Map 356 ``` 357 358 NewMap creates a new Map instance. 359 360 <a name="NewMapPresized"></a> 361 ### func NewMapPresized 362 363 ```go 364 func NewMapPresized(sizeHint int) *Map 365 ``` 366 367 NewMapPresized creates a new Map instance with capacity enough to hold sizeHint entries. The capacity is treated as the minimal capacity meaning that the underlying hash table will never shrink to a smaller capacity. If sizeHint is zero or negative, the value is ignored. 368 369 <a name="Map.Clear"></a> 370 ### func \(\*Map\) Clear 371 372 ```go 373 func (m *Map) Clear() 374 ``` 375 376 Clear deletes all keys and values currently stored in the map. 377 378 <a name="Map.Compute"></a> 379 ### func \(\*Map\) Compute 380 381 ```go 382 func (m *Map) Compute(key string, valueFn func(oldValue interface{}, loaded bool) (newValue interface{}, delete bool)) (actual interface{}, ok bool) 383 ``` 384 385 Compute either sets the computed new value for the key or deletes the value for the key. When the delete result of the valueFn function is set to true, the value will be deleted, if it exists. When delete is set to false, the value is updated to the newValue. The ok result indicates whether value was computed and stored, thus, is present in the map. The actual result contains the new value in cases where the value was computed and stored. See the example for a few use cases. 386 387 This call locks a hash table bucket while the compute function is executed. It means that modifications on other entries in the bucket will be blocked until the valueFn executes. Consider this when the function includes long\-running operations. 388 389 <a name="Map.Delete"></a> 390 ### func \(\*Map\) Delete 391 392 ```go 393 func (m *Map) Delete(key string) 394 ``` 395 396 Delete deletes the value for a key. 397 398 <a name="Map.Load"></a> 399 ### func \(\*Map\) Load 400 401 ```go 402 func (m *Map) Load(key string) (value interface{}, ok bool) 403 ``` 404 405 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. 406 407 <a name="Map.LoadAndDelete"></a> 408 ### func \(\*Map\) LoadAndDelete 409 410 ```go 411 func (m *Map) LoadAndDelete(key string) (value interface{}, loaded bool) 412 ``` 413 414 LoadAndDelete deletes the value for a key, returning the previous value if any. The loaded result reports whether the key was present. 415 416 <a name="Map.LoadAndStore"></a> 417 ### func \(\*Map\) LoadAndStore 418 419 ```go 420 func (m *Map) LoadAndStore(key string, value interface{}) (actual interface{}, loaded bool) 421 ``` 422 423 LoadAndStore returns the existing value for the key if present, while setting the new value for the key. It stores the new value and returns the existing one, if present. The loaded result is true if the existing value was loaded, false otherwise. 424 425 <a name="Map.LoadOrCompute"></a> 426 ### func \(\*Map\) LoadOrCompute 427 428 ```go 429 func (m *Map) LoadOrCompute(key string, valueFn func() interface{}) (actual interface{}, loaded bool) 430 ``` 431 432 LoadOrCompute returns the existing value for the key if present. Otherwise, it computes the value using the provided function and returns the computed value. The loaded result is true if the value was loaded, false if stored. 433 434 This call locks a hash table bucket while the compute function is executed. It means that modifications on other entries in the bucket will be blocked until the valueFn executes. Consider this when the function includes long\-running operations. 435 436 <a name="Map.LoadOrStore"></a> 437 ### func \(\*Map\) LoadOrStore 438 439 ```go 440 func (m *Map) LoadOrStore(key string, value interface{}) (actual interface{}, loaded bool) 441 ``` 442 443 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. 444 445 <a name="Map.Range"></a> 446 ### func \(\*Map\) Range 447 448 ```go 449 func (m *Map) Range(f func(key string, value interface{}) bool) 450 ``` 451 452 Range calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration. 453 454 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. 455 456 It is safe to modify the map while iterating it, including entry creation, modification and deletion. However, the concurrent modification rule apply, i.e. the changes may be not reflected in the subsequently iterated entries. 457 458 <a name="Map.Size"></a> 459 ### func \(\*Map\) Size 460 461 ```go 462 func (m *Map) Size() int 463 ``` 464 465 Size returns current size of the map. 466 467 <a name="Map.Store"></a> 468 ### func \(\*Map\) Store 469 470 ```go 471 func (m *Map) Store(key string, value interface{}) 472 ``` 473 474 Store sets the value for a key. 475 476 <a name="MapOf"></a> 477 ## type MapOf 478 479 MapOf is like a Go map\[K\]V but is safe for concurrent use by multiple goroutines without additional locking or coordination. It follows the interface of sync.Map with a number of valuable extensions like Compute or Size. 480 481 A MapOf must not be copied after first use. 482 483 MapOf uses a modified version of Cache\-Line Hash Table \(CLHT\) data structure: https://github.com/LPD-EPFL/CLHT 484 485 CLHT is built around idea to organize the hash table in cache\-line\-sized buckets, so that on all modern CPUs update operations complete with at most one cache\-line transfer. Also, Get operations involve no write to memory, as well as no mutexes or any other sort of locks. Due to this design, in all considered scenarios MapOf outperforms sync.Map. 486 487 ```go 488 type MapOf[K comparable, V any] struct { 489 // contains filtered or unexported fields 490 } 491 ``` 492 493 <a name="NewMapOf"></a> 494 ### func NewMapOf 495 496 ```go 497 func NewMapOf[K comparable, V any]() *MapOf[K, V] 498 ``` 499 500 NewMapOf creates a new MapOf instance. 501 502 <a name="NewMapOfPresized"></a> 503 ### func NewMapOfPresized 504 505 ```go 506 func NewMapOfPresized[K comparable, V any](sizeHint int) *MapOf[K, V] 507 ``` 508 509 NewMapOfPresized creates a new MapOf instance with capacity enough to hold sizeHint entries. The capacity is treated as the minimal capacity meaning that the underlying hash table will never shrink to a smaller capacity. If sizeHint is zero or negative, the value is ignored. 510 511 <a name="MapOf[K, V].Clear"></a> 512 ### func \(\*MapOf\[K, V\]\) Clear 513 514 ```go 515 func (m *MapOf[K, V]) Clear() 516 ``` 517 518 Clear deletes all keys and values currently stored in the map. 519 520 <a name="MapOf[K, V].Compute"></a> 521 ### func \(\*MapOf\[K, V\]\) Compute 522 523 ```go 524 func (m *MapOf[K, V]) Compute(key K, valueFn func(oldValue V, loaded bool) (newValue V, delete bool)) (actual V, ok bool) 525 ``` 526 527 Compute either sets the computed new value for the key or deletes the value for the key. When the delete result of the valueFn function is set to true, the value will be deleted, if it exists. When delete is set to false, the value is updated to the newValue. The ok result indicates whether value was computed and stored, thus, is present in the map. The actual result contains the new value in cases where the value was computed and stored. See the example for a few use cases. 528 529 This call locks a hash table bucket while the compute function is executed. It means that modifications on other entries in the bucket will be blocked until the valueFn executes. Consider this when the function includes long\-running operations. 530 531 <details><summary>Example</summary> 532 <p> 533 534 535 536 ```go 537 package main 538 539 import ( 540 "errors" 541 "fmt" 542 543 "github.com/fufuok/utils/xsync" 544 ) 545 546 func main() { 547 counts := xsync.NewMapOf[int, int]() 548 549 // Store a new value. 550 v, ok := counts.Compute(42, func(oldValue int, loaded bool) (newValue int, delete bool) { 551 // loaded is false here. 552 newValue = 42 553 delete = false 554 return 555 }) 556 // v: 42, ok: true 557 fmt.Printf("v: %v, ok: %v\n", v, ok) 558 559 // Update an existing value. 560 v, ok = counts.Compute(42, func(oldValue int, loaded bool) (newValue int, delete bool) { 561 // loaded is true here. 562 newValue = oldValue + 42 563 delete = false 564 return 565 }) 566 // v: 84, ok: true 567 fmt.Printf("v: %v, ok: %v\n", v, ok) 568 569 // Set a new value or keep the old value conditionally. 570 var oldVal int 571 minVal := 63 572 v, ok = counts.Compute(42, func(oldValue int, loaded bool) (newValue int, delete bool) { 573 oldVal = oldValue 574 if !loaded || oldValue < minVal { 575 newValue = minVal 576 delete = false 577 return 578 } 579 newValue = oldValue 580 delete = false 581 return 582 }) 583 // v: 84, ok: true, oldVal: 84 584 fmt.Printf("v: %v, ok: %v, oldVal: %v\n", v, ok, oldVal) 585 586 // Delete an existing value. 587 v, ok = counts.Compute(42, func(oldValue int, loaded bool) (newValue int, delete bool) { 588 // loaded is true here. 589 delete = true 590 return 591 }) 592 // v: 84, ok: false 593 fmt.Printf("v: %v, ok: %v\n", v, ok) 594 595 // Propagate an error from the compute function to the outer scope. 596 var err error 597 v, ok = counts.Compute(42, func(oldValue int, loaded bool) (newValue int, delete bool) { 598 if oldValue == 42 { 599 err = errors.New("something went wrong") 600 return 0, true // no need to create a key/value pair 601 } 602 newValue = 0 603 delete = false 604 return 605 }) 606 fmt.Printf("err: %v\n", err) 607 } 608 ``` 609 610 </p> 611 </details> 612 613 <a name="MapOf[K, V].Delete"></a> 614 ### func \(\*MapOf\[K, V\]\) Delete 615 616 ```go 617 func (m *MapOf[K, V]) Delete(key K) 618 ``` 619 620 Delete deletes the value for a key. 621 622 <a name="MapOf[K, V].Load"></a> 623 ### func \(\*MapOf\[K, V\]\) Load 624 625 ```go 626 func (m *MapOf[K, V]) Load(key K) (value V, ok bool) 627 ``` 628 629 Load returns the value stored in the map for a key, or zero value of type V if no value is present. The ok result indicates whether value was found in the map. 630 631 <a name="MapOf[K, V].LoadAndDelete"></a> 632 ### func \(\*MapOf\[K, V\]\) LoadAndDelete 633 634 ```go 635 func (m *MapOf[K, V]) LoadAndDelete(key K) (value V, loaded bool) 636 ``` 637 638 LoadAndDelete deletes the value for a key, returning the previous value if any. The loaded result reports whether the key was present. 639 640 <a name="MapOf[K, V].LoadAndStore"></a> 641 ### func \(\*MapOf\[K, V\]\) LoadAndStore 642 643 ```go 644 func (m *MapOf[K, V]) LoadAndStore(key K, value V) (actual V, loaded bool) 645 ``` 646 647 LoadAndStore returns the existing value for the key if present, while setting the new value for the key. It stores the new value and returns the existing one, if present. The loaded result is true if the existing value was loaded, false otherwise. 648 649 <a name="MapOf[K, V].LoadOrCompute"></a> 650 ### func \(\*MapOf\[K, V\]\) LoadOrCompute 651 652 ```go 653 func (m *MapOf[K, V]) LoadOrCompute(key K, valueFn func() V) (actual V, loaded bool) 654 ``` 655 656 LoadOrCompute returns the existing value for the key if present. Otherwise, it computes the value using the provided function and returns the computed value. The loaded result is true if the value was loaded, false if stored. 657 658 This call locks a hash table bucket while the compute function is executed. It means that modifications on other entries in the bucket will be blocked until the valueFn executes. Consider this when the function includes long\-running operations. 659 660 <a name="MapOf[K, V].LoadOrStore"></a> 661 ### func \(\*MapOf\[K, V\]\) LoadOrStore 662 663 ```go 664 func (m *MapOf[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) 665 ``` 666 667 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. 668 669 <a name="MapOf[K, V].Range"></a> 670 ### func \(\*MapOf\[K, V\]\) Range 671 672 ```go 673 func (m *MapOf[K, V]) Range(f func(key K, value V) bool) 674 ``` 675 676 Range calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration. 677 678 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. 679 680 It is safe to modify the map while iterating it, including entry creation, modification and deletion. However, the concurrent modification rule apply, i.e. the changes may be not reflected in the subsequently iterated entries. 681 682 <a name="MapOf[K, V].Size"></a> 683 ### func \(\*MapOf\[K, V\]\) Size 684 685 ```go 686 func (m *MapOf[K, V]) Size() int 687 ``` 688 689 Size returns current size of the map. 690 691 <a name="MapOf[K, V].Store"></a> 692 ### func \(\*MapOf\[K, V\]\) Store 693 694 ```go 695 func (m *MapOf[K, V]) Store(key K, value V) 696 ``` 697 698 Store sets the value for a key. 699 700 <a name="RBMutex"></a> 701 ## type RBMutex 702 703 A RBMutex is a reader biased reader/writer mutual exclusion lock. The lock can be held by an many readers or a single writer. The zero value for a RBMutex is an unlocked mutex. 704 705 A RBMutex must not be copied after first use. 706 707 RBMutex is based on a modified version of BRAVO \(Biased Locking for Reader\-Writer Locks\) algorithm: https://arxiv.org/pdf/1810.01553.pdf 708 709 RBMutex is a specialized mutex for scenarios, such as caches, where the vast majority of locks are acquired by readers and write lock acquire attempts are infrequent. In such scenarios, RBMutex performs better than sync.RWMutex on large multicore machines. 710 711 RBMutex extends sync.RWMutex internally and uses it as the "reader bias disabled" fallback, so the same semantics apply. The only noticeable difference is in reader tokens returned from the RLock/RUnlock methods. 712 713 ```go 714 type RBMutex struct { 715 // contains filtered or unexported fields 716 } 717 ``` 718 719 <a name="NewRBMutex"></a> 720 ### func NewRBMutex 721 722 ```go 723 func NewRBMutex() *RBMutex 724 ``` 725 726 NewRBMutex creates a new RBMutex instance. 727 728 <a name="RBMutex.Lock"></a> 729 ### func \(\*RBMutex\) Lock 730 731 ```go 732 func (mu *RBMutex) Lock() 733 ``` 734 735 Lock locks m for writing. If the lock is already locked for reading or writing, Lock blocks until the lock is available. 736 737 <a name="RBMutex.RLock"></a> 738 ### func \(\*RBMutex\) RLock 739 740 ```go 741 func (mu *RBMutex) RLock() *RToken 742 ``` 743 744 RLock locks m for reading and returns a reader token. The token must be used in the later RUnlock call. 745 746 Should not be used for recursive read locking; a blocked Lock call excludes new readers from acquiring the lock. 747 748 <a name="RBMutex.RUnlock"></a> 749 ### func \(\*RBMutex\) RUnlock 750 751 ```go 752 func (mu *RBMutex) RUnlock(t *RToken) 753 ``` 754 755 RUnlock undoes a single RLock call. A reader token obtained from the RLock call must be provided. RUnlock does not affect other simultaneous readers. A panic is raised if m is not locked for reading on entry to RUnlock. 756 757 <a name="RBMutex.Unlock"></a> 758 ### func \(\*RBMutex\) Unlock 759 760 ```go 761 func (mu *RBMutex) Unlock() 762 ``` 763 764 Unlock unlocks m for writing. A panic is raised if m is not locked for writing on entry to Unlock. 765 766 As with RWMutex, a locked RBMutex is not associated with a particular goroutine. One goroutine may RLock \(Lock\) a RBMutex and then arrange for another goroutine to RUnlock \(Unlock\) it. 767 768 <a name="RToken"></a> 769 ## type RToken 770 771 RToken is a reader lock token. 772 773 ```go 774 type RToken struct { 775 // contains filtered or unexported fields 776 } 777 ``` 778 779 Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)