github.com/whatap/golib@v0.0.22/util/hmap/IntKeyMap.go (about) 1 package hmap 2 3 import ( 4 "fmt" 5 //"log" 6 "math" 7 "sync" 8 9 "github.com/whatap/golib/util/stringutil" 10 ) 11 12 type IntKeyMap struct { 13 // []*IntKeyEntry 14 table []*IntKeyEntry 15 // int 16 count int 17 // int 18 threshold int 19 // float32 20 loadFactor float32 21 // sync.Mutex 22 lock sync.Mutex 23 24 // create func(int32) interface{]// create, intern 함수 사용 안함 25 //Create func(int32) interface{} 26 } 27 28 func NewIntKeyMapDefault() *IntKeyMap { 29 30 p := NewIntKeyMap(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR) 31 32 return p 33 } 34 35 func NewIntKeyMap(initCapacity int, loadFactor float32) *IntKeyMap { 36 defer func() { 37 if r := recover(); r != nil { 38 // TODO 추후 hmap 에서 recover 는 없애고 panic 처리. 호출하는 쪽에서 recover 할 것 39 //logutil.Println("WA823", "Recover:",r) 40 //return NewIntKeyMap(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR) 41 } 42 }() 43 44 p := new(IntKeyMap) 45 46 if initCapacity < 0 { 47 panic(fmt.Sprintf("Capacity Error: %d", initCapacity)) 48 //throw new RuntimeException("Capacity Error: " + initCapacity); 49 } 50 if loadFactor <= 0 { 51 panic(fmt.Sprintf("Load Count Error: %f", loadFactor)) 52 //throw new RuntimeException("Load Count Error: " + loadFactor); 53 } 54 if initCapacity == 0 { 55 initCapacity = 1 56 } 57 p.loadFactor = loadFactor 58 p.table = make([]*IntKeyEntry, initCapacity) 59 p.threshold = int(float32(initCapacity) * loadFactor) 60 61 return p 62 } 63 64 func (this *IntKeyMap) Size() int { 65 return this.count 66 } 67 68 func (this *IntKeyMap) Keys() IntEnumer { 69 this.lock.Lock() 70 defer this.lock.Unlock() 71 72 return NewIntKeyEnumer(ELEMENT_TYPE_KEYS, this.table) 73 } 74 75 func (this *IntKeyMap) Values() Enumeration { 76 //public synchronized Enumeration<V> values() { 77 this.lock.Lock() 78 defer this.lock.Unlock() 79 return NewIntKeyEnumer(ELEMENT_TYPE_VALUES, this.table) 80 } 81 82 func (this *IntKeyMap) Entries() Enumeration { 83 //public synchronized Enumeration<IntKeyEntry<V>> entries() { 84 this.lock.Lock() 85 defer this.lock.Unlock() 86 return NewIntKeyEnumer(ELEMENT_TYPE_ENTRIES, this.table) 87 } 88 89 func (this *IntKeyMap) ContainsValue(value interface{}) bool { 90 //public synchronized boolean containsValue(V value) { 91 this.lock.Lock() 92 defer this.lock.Unlock() 93 if value == nil { 94 return false 95 } 96 97 // TODO 98 //IntKeyEntry<V> tab[] = this.table; 99 // tab := this.table 100 // i := len(tab) 101 // for i> 0 ; i-- { 102 // //for (IntKeyEntry<V> e = tab[i]; e != null; e = e.next) { 103 // for e := tab[i]; e != nil; e = e.Next() { 104 // if CompareUtil.equals(e.value, value) { 105 // return true 106 // } 107 // } 108 // } 109 return false 110 } 111 112 func (this *IntKeyMap) ContainsKey(key int32) bool { 113 this.lock.Lock() 114 defer this.lock.Unlock() 115 116 tab := this.table 117 index := int(this.hash(key)) % len(tab) 118 119 //for (IntKeyEntry<V> e = tab[index]; e != null; e = e.next) { 120 for e := tab[index]; e != nil; e = e.Next { 121 if e.Key == key { 122 return true 123 } 124 } 125 return false 126 } 127 128 func (this *IntKeyMap) hash(h int32) uint { 129 ret := uint(h) 130 // TODO 131 ret ^= (uint(h) >> 20) ^ (uint(h) >> 12) 132 ret = ret ^ (uint(h) >> 7) ^ (uint(h) >> 4) 133 134 return ret & uint(math.MaxInt32) 135 } 136 137 func (this *IntKeyMap) Get(key int32) interface{} { 138 this.lock.Lock() 139 defer this.lock.Unlock() 140 141 tab := this.table 142 index := int(this.hash(key)) % len(tab) 143 144 //for (IntKeyEntry<V> e = tab[index]; e != null; e = e.next) { 145 for e := tab[index]; e != nil; e = e.Next { 146 if e.Key == key { 147 return e.Value 148 } 149 } 150 return nil 151 } 152 153 func (this *IntKeyMap) rehash() { 154 oldCapacity := len(this.table) 155 oldMap := this.table 156 newCapacity := oldCapacity*2 + 1 157 158 newMap := make([]*IntKeyEntry, newCapacity) 159 this.threshold = int(float32(newCapacity) * this.loadFactor) 160 this.table = newMap 161 162 for i := oldCapacity; i > 0; i-- { 163 for old := oldMap[i-1]; old != nil; { 164 e := old 165 old = old.Next 166 index := int(this.hash(e.Key)) % newCapacity 167 e.Next = newMap[index] 168 newMap[index] = e 169 } 170 } 171 } 172 173 func (this *IntKeyMap) KeyArray() []int32 { 174 this.lock.Lock() 175 defer this.lock.Unlock() 176 177 _keys := make([]int32, this.Size()) 178 179 //IntEnumer en = this.keys(); 180 en := this.Keys() 181 182 for i := 0; i < len(_keys); i++ { 183 _keys[i] = en.NextInt() 184 } 185 return _keys 186 } 187 188 func (this *IntKeyMap) Put(key int32, value interface{}) interface{} { 189 this.lock.Lock() 190 defer this.lock.Unlock() 191 192 tab := this.table 193 _hash := this.hash(key) 194 index := _hash % uint(len(tab)) 195 196 e := tab[index] 197 for e = tab[index]; e != nil; e = e.Next { 198 if e.Key == key { 199 old := e.Value 200 e.Value = value 201 return old 202 } 203 } 204 205 if this.count >= this.threshold { 206 this.rehash() 207 tab = this.table 208 index = _hash % uint(len(tab)) 209 } 210 e = NewIntKeyEntry(key, value, tab[index]) 211 tab[index] = e 212 this.count++ 213 214 return nil 215 } 216 217 // intern 함수 사용 안함 218 //func (this *IntKeyMap) Intern(key int32) interface{} { 219 // this.lock.Lock() 220 // defer this.lock.Unlock() 221 // tab := this.table 222 // _hash := this.hash(key) 223 // index := _hash % uint(len(tab)) 224 // 225 // for e := tab[index]; e != nil; e = e.Next { 226 // if e.Key == key { 227 // return e.Value 228 // } 229 // } 230 // 231 // //var value interface{} 232 // value := this.create(key) 233 // 234 // if value == nil { 235 // return nil 236 // } 237 // 238 // if this.count >= this.threshold { 239 // this.rehash() 240 // tab = this.table 241 // index = _hash % uint(len(tab)) 242 // } 243 // e := NewIntKeyEntry(key, value, tab[index]) 244 // tab[index] = e 245 // this.count++ 246 // return value 247 //} 248 249 //Override create , intern 함수 사용 안함 250 //func (this *IntKeyMap) create(key int32) interface{} { 251 // if this.Create == nil { 252 // panic("Error IntKeyMap.Count is nil") 253 // } 254 // 255 // return this.Create(key) 256 // //throw new RuntimeException("not implemented create()") 257 // //return interface{} 258 // //return nil 259 //} 260 261 func (this *IntKeyMap) Remove(key int32) interface{} { 262 this.lock.Lock() 263 defer this.lock.Unlock() 264 265 tab := this.table 266 index := this.hash(key) % uint(len(tab)) 267 var prev *IntKeyEntry 268 prev = nil 269 //for e := tab[index], prev := nil; e != nil; prev = e, e = e.Next) { 270 for e := tab[index]; e != nil; { 271 if e.Key == key { 272 if prev != nil { 273 prev.Next = e.Next 274 } else { 275 tab[index] = e.Next 276 } 277 this.count-- 278 oldValue := e.Value 279 e.Value = nil 280 return oldValue 281 } 282 283 prev = e 284 e = e.Next 285 } 286 return nil 287 } 288 289 func (this *IntKeyMap) Clear() { 290 this.lock.Lock() 291 defer this.lock.Unlock() 292 tab := this.table 293 294 for index := len(tab) - 1; index >= 0; index-- { 295 tab[index] = nil 296 } 297 this.count = 0 298 299 } 300 301 func (this *IntKeyMap) ToString() string { 302 buf := stringutil.NewStringBuffer() 303 304 it := this.Entries() 305 buf.Append("{") 306 307 for i := 0; it.HasMoreElements(); i++ { 308 e := it.NextElement().(*IntKeyEntry) 309 310 if i > 0 { 311 buf.Append(", ") 312 } 313 buf.Append(e.ToString()) 314 } 315 buf.Append("}") 316 317 return buf.ToString() 318 } 319 320 func (this *IntKeyMap) ToFormatString() string { 321 buf := stringutil.NewStringBuffer() 322 323 it := this.Entries() 324 buf.Append("{\n") 325 for it.HasMoreElements() { 326 e := it.NextElement().(*IntKeyEntry) 327 buf.Append("\t").Append(e.ToString()).Append("\n") 328 } 329 buf.Append("}") 330 return buf.ToString() 331 } 332 333 func (this *IntKeyMap) PutAll(other *IntKeyMap) { 334 if other == nil { 335 return 336 } 337 it := other.Entries() 338 339 for it.HasMoreElements() { 340 e := it.NextElement().(*IntKeyEntry) 341 this.Put(e.GetKey(), e.GetValue()) 342 } 343 } 344 345 type IntKeyEnumer struct { 346 table []*IntKeyEntry 347 entry *IntKeyEntry 348 index int 349 lastReturned *IntKeyEntry 350 Type int 351 } 352 353 func NewIntKeyEnumer(Type int, table []*IntKeyEntry) *IntKeyEnumer { 354 p := new(IntKeyEnumer) 355 p.table = table 356 p.index = len(table) 357 p.entry = nil 358 p.lastReturned = nil 359 p.Type = Type 360 return p 361 } 362 363 func (this *IntKeyEnumer) HasMoreElements() bool { 364 for this.entry == nil && this.index > 0 { 365 this.index-- 366 this.entry = this.table[this.index] 367 } 368 //fmt.Println("IntKeyMap.IntKeyEnumer HasMoreElements index=", this.index, ",return =", (this.entry != nil)) 369 return (this.entry != nil) 370 } 371 372 func (this *IntKeyEnumer) NextElement() interface{} { 373 //fmt.Println("IntKeyMap.IntKeyEnumer NextElement index=", this.index, ",entry =", this.entry) 374 375 for this.entry == nil && this.index > 0 { 376 this.index-- 377 this.entry = this.table[this.index] 378 } 379 380 if this.entry != nil { 381 //fmt.Println("IntKeyMap.IntKeyEnumer NextElement this.entry != nil , index=", this.index, ",entry =", this.entry) 382 this.lastReturned = this.entry 383 e := this.lastReturned 384 385 this.entry = e.Next 386 387 switch this.Type { 388 case ELEMENT_TYPE_KEYS: 389 return e.Key 390 case ELEMENT_TYPE_VALUES: 391 return e.Value 392 default: 393 return e 394 } 395 } 396 //fmt.Println("IntKeyMap.IntKeyEnumer NextElement for , index=", this.index, ",entry =", this.entry) 397 398 //throw new NoSuchElementException("no more next"); 399 panic("Panic NextElement no more next") 400 401 } 402 403 func (this *IntKeyEnumer) NextInt() int32 { 404 for this.entry == nil && this.index > 0 { 405 this.index-- 406 this.entry = this.table[this.index] 407 } 408 409 if this.entry != nil { 410 this.lastReturned = this.entry 411 e := this.lastReturned 412 this.entry = e.Next 413 return e.Key 414 } 415 //throw new NoSuchElementException("no more next"); 416 panic("Panic NextInt no more next") 417 418 }