github.com/whatap/golib@v0.0.22/util/hmap/LongKeyLinkedMap.go (about) 1 package hmap 2 3 import ( 4 "bytes" 5 "sort" 6 "sync" 7 ) 8 9 type LongKeyLinkedMap struct { 10 table []*LongKeyLinkedEntry 11 header *LongKeyLinkedEntry 12 count int 13 threshold int 14 loadFactor float32 15 lock sync.Mutex 16 max int 17 } 18 19 func NewLongKeyLinkedMapDefault() *LongKeyLinkedMap { 20 21 initCapacity := DEFAULT_CAPACITY 22 loadFactor := DEFAULT_LOAD_FACTOR 23 24 this := new(LongKeyLinkedMap) 25 this.loadFactor = float32(loadFactor) 26 this.table = make([]*LongKeyLinkedEntry, initCapacity) 27 this.header = &LongKeyLinkedEntry{} 28 this.header.link_next = this.header 29 this.header.link_prev = this.header 30 this.threshold = int(float64(initCapacity) * loadFactor) 31 return this 32 } 33 34 func NewLongKeyLinkedMap(initCapacity int, loadFactor float32) *LongKeyLinkedMap { 35 this := new(LongKeyLinkedMap) 36 this.loadFactor = float32(loadFactor) 37 this.table = make([]*LongKeyLinkedEntry, initCapacity) 38 this.header = &LongKeyLinkedEntry{} 39 this.header.link_next = this.header 40 this.header.link_prev = this.header 41 this.threshold = int(float32(initCapacity) * loadFactor) 42 return this 43 } 44 45 func (this *LongKeyLinkedMap) Size() int { 46 return this.count 47 } 48 49 func (this *LongKeyLinkedMap) KeyArray() []int64 { 50 this.lock.Lock() 51 defer this.lock.Unlock() 52 53 _keys := make([]int64, this.Size()) 54 en := this.Keys() 55 for i := 0; i < len(_keys); i++ { 56 _keys[i] = en.NextLong() 57 } 58 return _keys 59 } 60 61 type LongKeyEnumerImpl struct { 62 parent *LongKeyLinkedMap 63 entry *LongKeyLinkedEntry 64 isEntry bool 65 } 66 67 func (this *LongKeyEnumerImpl) HasMoreElements() bool { 68 return this.entry != nil && this.parent.header != this.entry 69 } 70 func (this *LongKeyEnumerImpl) NextLong() int64 { 71 if this.HasMoreElements() { 72 e := this.entry 73 this.entry = e.link_next 74 return e.key 75 } 76 return 0 77 } 78 79 func (this *LongKeyEnumerImpl) NextElement() interface{} { 80 if this.HasMoreElements() { 81 e := this.entry 82 this.entry = e.link_next 83 if this.isEntry { 84 return e 85 } else { 86 return e.GetValue() 87 } 88 } 89 return "" 90 } 91 func (this *LongKeyLinkedMap) Keys() LongEnumer { 92 return &LongKeyEnumerImpl{parent: this, entry: this.header.link_next} 93 } 94 func (this *LongKeyLinkedMap) Values() Enumeration { 95 return &LongKeyEnumerImpl{parent: this, entry: this.header.link_next, isEntry: false} 96 } 97 func (this *LongKeyLinkedMap) Entries() Enumeration { 98 return &LongKeyEnumerImpl{parent: this, entry: this.header.link_next, isEntry: true} 99 } 100 101 func (this *LongKeyLinkedMap) ContainsKey(key int64) bool { 102 this.lock.Lock() 103 defer this.lock.Unlock() 104 105 tab := this.table 106 index := this.hash(key) % uint(len(tab)) 107 for e := tab[index]; e != nil; e = e.hash_next { 108 if e.key == key { 109 return true 110 } 111 } 112 return false 113 114 } 115 func (this *LongKeyLinkedMap) Get(key int64) interface{} { 116 this.lock.Lock() 117 defer this.lock.Unlock() 118 119 tab := this.table 120 index := this.hash(key) % uint(len(tab)) 121 for e := tab[index]; e != nil; e = e.hash_next { 122 if e.key == key { 123 return e.value 124 } 125 } 126 return nil 127 } 128 func (this *LongKeyLinkedMap) GetFirstKey() int64 { 129 this.lock.Lock() 130 defer this.lock.Unlock() 131 132 return this.header.link_next.key 133 } 134 135 func (this *LongKeyLinkedMap) GetLastKey() int64 { 136 this.lock.Lock() 137 defer this.lock.Unlock() 138 return this.header.link_prev.key 139 } 140 141 func (this *LongKeyLinkedMap) GetFirstValue() interface{} { 142 this.lock.Lock() 143 defer this.lock.Unlock() 144 145 return this.header.link_next.value 146 } 147 148 func (this *LongKeyLinkedMap) GetLastValue() interface{} { 149 this.lock.Lock() 150 defer this.lock.Unlock() 151 152 return this.header.link_prev.value 153 } 154 func (this *LongKeyLinkedMap) hash(key int64) uint { 155 return uint(key ^ key>>32) 156 } 157 158 func (this *LongKeyLinkedMap) rehash() { 159 oldCapacity := len(this.table) 160 oldMap := this.table 161 newCapacity := oldCapacity*2 + 1 162 newMap := make([]*LongKeyLinkedEntry, newCapacity) 163 this.threshold = int(float32(newCapacity) * this.loadFactor) 164 this.table = newMap 165 166 for i := oldCapacity; i > 0; i-- { 167 for old := oldMap[i-1]; old != nil; { 168 e := old 169 old = old.hash_next 170 index := uint(e.keyHash % uint(newCapacity)) 171 e.hash_next = newMap[index] 172 newMap[index] = e 173 } 174 } 175 } 176 177 func (this *LongKeyLinkedMap) SetMax(max int) *LongKeyLinkedMap { 178 this.max = max 179 return this 180 } 181 func (this *LongKeyLinkedMap) Put(key int64, value interface{}) interface{} { 182 this.lock.Lock() 183 defer this.lock.Unlock() 184 return this.put(key, value, PUT_LAST) 185 } 186 func (this *LongKeyLinkedMap) PutLast(key int64, value interface{}) interface{} { 187 this.lock.Lock() 188 defer this.lock.Unlock() 189 return this.put(key, value, PUT_FORCE_LAST) 190 } 191 func (this *LongKeyLinkedMap) PutFirst(key int64, value interface{}) interface{} { 192 this.lock.Lock() 193 defer this.lock.Unlock() 194 return this.put(key, value, PUT_FORCE_FIRST) 195 } 196 func (this *LongKeyLinkedMap) put(key int64, value interface{}, m PUT_MODE) interface{} { 197 tab := this.table 198 keyHash := this.hash(key) 199 200 index := keyHash % uint(len(tab)) 201 for e := tab[index]; e != nil; e = e.hash_next { 202 if e.key == key { 203 old := e.value 204 e.value = value 205 switch m { 206 case PUT_FORCE_FIRST: 207 if this.header.link_next != e { 208 this.unchain(e) 209 this.chain(this.header, this.header.link_next, e) 210 } 211 case PUT_FORCE_LAST: 212 if this.header.link_prev != e { 213 this.unchain(e) 214 this.chain(this.header.link_prev, this.header, e) 215 } 216 } 217 //log.Println(">>>>", "Put Dup Txid=", key) 218 return old 219 } 220 } 221 if this.max > 0 { 222 switch m { 223 case PUT_FORCE_FIRST, PUT_FIRST: 224 for this.count >= this.max { 225 k := this.header.link_prev.key 226 this.remove(k) 227 } 228 case PUT_FORCE_LAST, PUT_LAST: 229 for this.count >= this.max { 230 // removeFirst(); 231 k := this.header.link_next.key 232 this.remove(k) 233 } 234 } 235 } 236 if this.count >= this.threshold { 237 this.rehash() 238 tab = this.table 239 index = keyHash % uint(len(tab)) 240 } 241 e := &LongKeyLinkedEntry{key: key, keyHash: keyHash, value: value, hash_next: tab[index]} 242 tab[index] = e 243 switch m { 244 case PUT_FORCE_FIRST, PUT_FIRST: 245 this.chain(this.header, this.header.link_next, e) 246 case PUT_FORCE_LAST, PUT_LAST: 247 this.chain(this.header.link_prev, this.header, e) 248 } 249 this.count++ 250 return "" 251 } 252 253 func (this *LongKeyLinkedMap) Remove(key int64) interface{} { 254 this.lock.Lock() 255 defer this.lock.Unlock() 256 257 return this.remove(key) 258 } 259 func (this *LongKeyLinkedMap) RemoveFirst() interface{} { 260 if this.IsEmpty() { 261 return 0 262 } 263 this.lock.Lock() 264 defer this.lock.Unlock() 265 return this.remove(this.header.link_next.key) 266 } 267 268 func (this *LongKeyLinkedMap) RemoveLast() interface{} { 269 if this.IsEmpty() { 270 return 0 271 } 272 this.lock.Lock() 273 defer this.lock.Unlock() 274 return this.remove(this.header.link_prev.key) 275 } 276 277 func (this *LongKeyLinkedMap) remove(key int64) interface{} { 278 tab := this.table 279 index := this.hash(key) % uint(len(tab)) 280 e := tab[index] 281 var prev *LongKeyLinkedEntry = nil 282 for e != nil { 283 if e.key == key { 284 if prev != nil { 285 prev.hash_next = e.hash_next 286 } else { 287 tab[index] = e.hash_next 288 } 289 this.count-- 290 oldValue := e.value 291 e.value = nil 292 // 293 this.unchain(e) 294 return oldValue 295 } 296 prev = e 297 e = e.hash_next 298 } 299 return nil 300 } 301 302 func (this *LongKeyLinkedMap) IsEmpty() bool { 303 return this.count == 0 304 } 305 func (this *LongKeyLinkedMap) IsFull() bool { 306 return this.max > 0 && this.max <= this.count 307 } 308 309 func (this *LongKeyLinkedMap) Clear() { 310 this.lock.Lock() 311 defer this.lock.Unlock() 312 this.clear() 313 } 314 func (this *LongKeyLinkedMap) clear() { 315 tab := this.table 316 for index := len(tab) - 1; index >= 0; index-- { 317 tab[index] = nil 318 } 319 this.header.link_next = this.header 320 this.header.link_prev = this.header 321 this.count = 0 322 } 323 324 func (this *LongKeyLinkedMap) chain(link_prev *LongKeyLinkedEntry, link_next *LongKeyLinkedEntry, e *LongKeyLinkedEntry) { 325 e.link_prev = link_prev 326 e.link_next = link_next 327 link_prev.link_next = e 328 link_next.link_prev = e 329 } 330 331 func (this *LongKeyLinkedMap) unchain(e *LongKeyLinkedEntry) { 332 e.link_prev.link_next = e.link_next 333 e.link_next.link_prev = e.link_prev 334 e.link_prev = nil 335 e.link_next = nil 336 } 337 338 type LongKeySortable struct { 339 compare func(a, b int64) bool 340 data []*LongKeyLinkedEntry 341 } 342 343 func (this LongKeySortable) Len() int { 344 return len(this.data) 345 } 346 func (this LongKeySortable) Less(i, j int) bool { 347 return this.compare(this.data[i].GetKey(), this.data[j].GetKey()) 348 } 349 350 func (this LongKeySortable) Swap(i, j int) { 351 this.data[i], this.data[j] = this.data[j], this.data[i] 352 } 353 354 func (this *LongKeyLinkedMap) Sort(c func(k1, k2 int64) bool) { 355 this.lock.Lock() 356 defer this.lock.Unlock() 357 358 sz := this.Size() 359 list := make([]*LongKeyLinkedEntry, sz) 360 en := this.Entries() 361 for i := 0; i < sz; i++ { 362 list[i] = en.NextElement().(*LongKeyLinkedEntry) 363 } 364 sort.Sort(LongKeySortable{compare: c, data: list}) 365 366 this.clear() 367 for i := 0; i < sz; i++ { 368 this.put(list[i].GetKey(), list[i].GetValue(), PUT_LAST) 369 } 370 } 371 372 func (this *LongKeyLinkedMap) ToString() string { 373 this.lock.Lock() 374 defer this.lock.Unlock() 375 376 var buffer bytes.Buffer 377 x := this.Entries() 378 buffer.WriteString("{") 379 for i := 0; x.HasMoreElements(); i++ { 380 if i > 0 { 381 buffer.WriteString(", ") 382 } 383 e := x.NextElement().(*LongKeyLinkedEntry) 384 buffer.WriteString(e.ToString()) 385 } 386 buffer.WriteString("}") 387 return buffer.String() 388 }