github.com/TeaOSLab/EdgeNode@v1.3.8/internal/utils/sync/map_int.go (about) 1 // Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn . 2 3 package syncutils 4 5 import ( 6 "runtime" 7 "sync" 8 ) 9 10 type KType interface { 11 int | int16 | int32 | int64 | uint | uint16 | uint32 | uint64 | uintptr 12 } 13 14 type VType interface { 15 any 16 } 17 18 type IntMap[K KType, V VType] struct { 19 count int 20 m []map[K]V 21 lockers []*sync.RWMutex 22 } 23 24 func NewIntMap[K KType, V VType]() *IntMap[K, V] { 25 var count = runtime.NumCPU() * 8 26 if count <= 0 { 27 count = 32 28 } 29 30 var m = []map[K]V{} 31 var lockers = []*sync.RWMutex{} 32 for i := 0; i < count; i++ { 33 m = append(m, map[K]V{}) 34 lockers = append(lockers, &sync.RWMutex{}) 35 } 36 37 return &IntMap[K, V]{ 38 count: count, 39 m: m, 40 lockers: lockers, 41 } 42 } 43 44 func (this *IntMap[K, V]) Put(k K, v V) { 45 var index = this.index(k) 46 this.lockers[index].Lock() 47 this.m[index][k] = v 48 this.lockers[index].Unlock() 49 } 50 51 func (this *IntMap[K, V]) PutCompact(k K, v V, compactFunc func(oldV V, newV V) V) { 52 var index = this.index(k) 53 this.lockers[index].Lock() 54 // 再次检查是否已经存在,如果已经存在则合并 55 oldV, ok := this.m[index][k] 56 if ok { 57 this.m[index][k] = compactFunc(oldV, v) 58 } else { 59 this.m[index][k] = v 60 } 61 this.lockers[index].Unlock() 62 } 63 64 func (this *IntMap[K, V]) Has(k K) bool { 65 var index = this.index(k) 66 this.lockers[index].RLock() 67 _, ok := this.m[index][k] 68 this.lockers[index].RUnlock() 69 return ok 70 } 71 72 func (this *IntMap[K, V]) Get(k K) (value V) { 73 var index = this.index(k) 74 this.lockers[index].RLock() 75 value = this.m[index][k] 76 this.lockers[index].RUnlock() 77 return 78 } 79 80 func (this *IntMap[K, V]) GetOk(k K) (value V, ok bool) { 81 var index = this.index(k) 82 this.lockers[index].RLock() 83 value, ok = this.m[index][k] 84 this.lockers[index].RUnlock() 85 return 86 } 87 88 func (this *IntMap[K, V]) Delete(k K) { 89 var index = this.index(k) 90 this.lockers[index].Lock() 91 delete(this.m[index], k) 92 this.lockers[index].Unlock() 93 } 94 95 func (this *IntMap[K, V]) DeleteUnsafe(k K) { 96 var index = this.index(k) 97 delete(this.m[index], k) 98 } 99 100 func (this *IntMap[K, V]) Len() int { 101 var l int 102 for i := 0; i < this.count; i++ { 103 this.lockers[i].RLock() 104 l += len(this.m[i]) 105 this.lockers[i].RUnlock() 106 } 107 return l 108 } 109 110 func (this *IntMap[K, V]) ForEachRead(iterator func(k K, v V)) { 111 for i := 0; i < this.count; i++ { 112 this.lockers[i].RLock() 113 for k, v := range this.m[i] { 114 iterator(k, v) 115 } 116 this.lockers[i].RUnlock() 117 } 118 } 119 120 func (this *IntMap[K, V]) ForEachWrite(iterator func(k K, v V)) { 121 for i := 0; i < this.count; i++ { 122 this.lockers[i].Lock() 123 for k, v := range this.m[i] { 124 iterator(k, v) 125 } 126 this.lockers[i].Unlock() 127 } 128 } 129 130 func (this *IntMap[K, V]) index(k K) int { 131 var index = int(k % K(this.count)) 132 if index < 0 { 133 index = -index 134 } 135 return index 136 }