1 28 29 package com.caucho.util; 30 31 import java.util.AbstractMap ; 32 import java.util.AbstractSet ; 33 import java.util.Collection ; 34 import java.util.Iterator ; 35 import java.util.Map ; 36 import java.util.Set ; 37 38 41 public class HashMapImpl<K,V> extends AbstractMap <K,V> { 42 private K []_keys; 44 45 private V []_values; 47 48 private V _nullValue; 49 50 private int _capacity; 52 private int _size; 54 private int _mask; 55 56 61 public HashMapImpl() 62 { 63 this(16); 64 } 65 66 71 public HashMapImpl(int initialCapacity) 72 { 73 int capacity; 74 75 for (capacity = 16; capacity < 2 * initialCapacity; capacity *= 2) { 76 } 77 78 _keys = (K []) new Object [capacity]; 79 _values = (V []) new Object [capacity]; 80 _mask = capacity - 1; 81 82 _capacity = initialCapacity; 83 } 84 85 88 public int size() 89 { 90 return _size; 91 } 92 93 96 public void clear() 97 { 98 if (_size > 0) { 99 for (int i = 0; i < _values.length; i++) { 100 _keys[i] = null; 101 _values[i] = null; 102 } 103 104 _size = 0; 105 } 106 107 _nullValue = null; 108 } 109 110 116 public V get(Object key) 117 { 118 if (key == null) 119 return _nullValue; 120 121 int hash = key.hashCode() & _mask; 122 int count = _size + 1; 123 124 K []keys = _keys; 125 126 for (; count > 0; count--) { 127 K mapKey = keys[hash]; 128 129 if (mapKey == null) 130 return null; 131 132 if (key.equals(_keys[hash])) 133 return _values[hash]; 134 135 hash = (hash + 1) & _mask; 136 } 137 138 return null; 139 } 140 141 149 public V put(K key, V value) 150 { 151 if (key == null) { 152 V item = _nullValue; 153 154 _nullValue = value; 155 156 return item; 157 } 158 159 V item = putImpl(key, value); 160 161 if (3 * _values.length <= 4 * _size) { 163 K []oldKeys = _keys; 164 V []oldValues = _values; 165 166 _keys = (K []) new Object [2 * oldKeys.length]; 167 _values = (V []) new Object [2 * oldValues.length]; 168 169 _mask = _values.length - 1; 170 _size = 0; 171 172 for (int i = oldValues.length - 1; i >= 0; i--) { 173 K oldKey = oldKeys[i]; 174 V oldValue = oldValues[i]; 175 176 if (oldValue != null) 177 putImpl(oldKey, oldValue); 178 } 179 } 180 181 return item; 182 } 183 184 187 private V putImpl(K key, V value) 188 { 189 V item = null; 190 191 int hash = key.hashCode() & _mask; 192 int count = _size + 1; 193 194 for (; count > 0; count--) { 195 item = _values[hash]; 196 197 if (item == null) { 199 _keys[hash] = key; 200 _values[hash] = value; 201 _size++; 202 203 return null; 204 } 205 206 if (_keys[hash].equals(key)) { 208 _values[hash] = value; 209 210 return item; 211 } 212 213 hash = (hash + 1) & _mask; 214 } 215 216 throw new IllegalStateException (); 217 } 218 219 226 public V remove(Object key) 227 { 228 if (key == null) { 229 V value = _nullValue; 230 _nullValue = null; 231 return value; 232 } 233 234 int hash = key.hashCode() & _mask; 235 int count = _size + 1; 236 237 V item = null; 238 239 for (; count > 0; count--) { 240 item = _values[hash]; 241 242 if (item == null) 243 return null; 244 245 if (_keys[hash].equals(key)) { 246 _keys[hash] = null; 247 _values[hash] = null; 248 _size--; 249 250 refillEntries(hash); 251 break; 252 } 253 254 hash = (hash + 1) & _mask; 255 } 256 257 if (count < 0) 258 throw new RuntimeException ("internal cache error"); 259 260 return item; 261 } 262 263 266 private void refillEntries(int hash) 267 { 268 for (int count = _size; count >= 0; count--) { 269 hash = (hash + 1) & _mask; 270 271 if (_values[hash] == null) 272 return; 273 274 refillEntry(hash); 275 } 276 } 277 278 281 private void refillEntry(int baseHash) 282 { 283 K key = _keys[baseHash]; 284 V value = _values[baseHash]; 285 286 _keys[baseHash] = null; 287 _values[baseHash] = null; 288 289 int hash = key.hashCode() & _mask; 290 291 for (int count = _size; count >= 0; count--) { 292 if (_values[hash] == null) { 293 _keys[hash] = key; 294 _values[hash] = value; 295 return; 296 } 297 298 hash = (hash + 1) & _mask; 299 } 300 } 301 302 305 public Set <K> keySet() 306 { 307 return new KeySet(this); 308 } 309 310 313 static class KeySet<K1,V1> extends AbstractSet <K1> { 314 private HashMapImpl<K1,V1> _map; 315 316 KeySet(HashMapImpl<K1,V1> map) 317 { 318 _map = map; 319 } 320 321 324 public int size() 325 { 326 return _map.size(); 327 } 328 329 332 public boolean contains(Object key) 333 { 334 if (key == null) 335 return _map._nullValue != null; 336 337 K1 []keys = _map._keys; 338 339 for (int i = keys.length - 1 ; i >= 0; i--) { 340 K1 testKey = keys[i]; 341 342 if (key.equals(testKey)) 343 return true; 344 } 345 346 return false; 347 } 348 349 352 public boolean removeAll(Collection <?> keys) 353 { 354 if (keys == null) 355 return false; 356 357 Iterator <?> iter = keys.iterator(); 358 while (iter.hasNext()) { 359 Object key = iter.next(); 360 361 _map.remove(key); 362 } 363 364 return true; 365 } 366 367 370 public Iterator <K1> iterator() 371 { 372 return new KeyIterator<K1,V1>(_map); 373 } 374 } 375 376 379 static class KeyIterator<K1,V1> implements Iterator <K1> { 380 private HashMapImpl<K1,V1> _map; 381 private int _i; 382 383 KeyIterator(HashMapImpl<K1,V1> map) 384 { 385 init(map); 386 } 387 388 void init(HashMapImpl<K1,V1> map) 389 { 390 _map = map; 391 _i = 0; 392 } 393 394 public boolean hasNext() 395 { 396 K1 []keys = _map._keys; 397 int len = keys.length; 398 399 for (; _i < len; _i++) { 400 if (keys[_i] != null) 401 return true; 402 } 403 404 return false; 405 } 406 407 public K1 next() 408 { 409 K1 []keys = _map._keys; 410 int len = keys.length; 411 412 for (; _i < len; _i++) { 413 K1 key = keys[_i]; 414 415 if (key != null) { 416 _i++; 417 418 return key; 419 } 420 } 421 422 return null; 423 } 424 425 public void remove() 426 { 427 if (_i > 0) 428 _map.remove(_map._keys[_i - 1]); 429 } 430 } 431 432 435 public Set <Map.Entry <K,V>> entrySet() 436 { 437 return new EntrySet(this); 438 } 439 440 443 static class EntrySet<K1,V1> extends AbstractSet <Map.Entry <K1,V1>> { 444 private HashMapImpl<K1,V1> _map; 445 446 EntrySet(HashMapImpl<K1,V1> map) 447 { 448 _map = map; 449 } 450 451 454 public int size() 455 { 456 return _map.size(); 457 } 458 459 462 public Iterator <Map.Entry <K1,V1>> iterator() 463 { 464 return new EntryIterator(_map); 465 } 466 } 467 468 471 static class EntryIterator<K1,V1> implements Iterator <Map.Entry <K1,V1>> { 472 private final Entry<K1,V1> _entry = new Entry<K1,V1>(); 473 474 private HashMapImpl<K1,V1> _map; 475 private int _i; 476 477 EntryIterator(HashMapImpl<K1,V1> map) 478 { 479 init(map); 480 } 481 482 void init(HashMapImpl<K1,V1> map) 483 { 484 _map = map; 485 _i = 0; 486 } 487 488 public boolean hasNext() 489 { 490 K1 []keys = _map._keys; 491 int len = keys.length; 492 493 for (; _i < len; _i++) { 494 if (keys[_i] != null) 495 return true; 496 } 497 498 return false; 499 } 500 501 public Map.Entry <K1,V1> next() 502 { 503 K1 []keys = _map._keys; 504 int len = keys.length; 505 506 for (; _i < len; _i++) { 507 if (keys[_i] != null) { 508 _entry.init(_map, _i++); 509 510 return _entry; 511 } 512 } 513 514 return null; 515 } 516 517 public void remove() 518 { 519 if (_i > 0) 520 _map.remove(_map._keys[_i - 1]); 521 } 522 } 523 524 static class Entry<K1,V1> implements Map.Entry <K1,V1> { 525 private HashMapImpl<K1,V1> _map; 526 private int _i; 527 528 void init(HashMapImpl<K1,V1> map, int i) 529 { 530 _map = map; 531 _i = i; 532 } 533 534 537 public K1 getKey() 538 { 539 return _map._keys[_i]; 540 } 541 542 545 public V1 getValue() 546 { 547 return _map._values[_i]; 548 } 549 550 553 public V1 setValue(V1 value) 554 { 555 V1 oldValue = _map._values[_i]; 556 557 _map._values[_i] = value; 558 559 return oldValue; 560 } 561 } 562 } 563 | Popular Tags |