1 28 29 package com.caucho.util; 30 31 import java.util.Iterator ; 32 39 public class LongMap<K> { 40 44 public final static long NULL = 0xffffffffffffffedL; 45 private static int DELETED = 0x1; 46 private K []_keys; 47 private long _nullValue; 48 private long []_values; 49 private byte []_flags; 50 private int _size; 51 private int _mask; 52 53 56 public LongMap() 57 { 58 _keys = (K []) new Object [16]; 59 _values = new long[16]; 60 _flags = new byte[16]; 61 62 _mask = _keys.length - 1; 63 _size = 0; 64 65 _nullValue = NULL; 66 } 67 68 71 private LongMap(boolean dummy) 72 { 73 } 74 75 78 public void clear() 79 { 80 _nullValue = NULL; 81 82 for (int i = 0; i < _values.length; i++) { 83 _keys[i] = null; 84 _flags[i] = 0; 85 _values[i] = 0; 86 } 87 88 _size = 0; 89 } 90 93 public int size() 94 { 95 return _size; 96 } 97 98 101 public long get(K key) 102 { 103 if (key == null) 104 return _nullValue; 105 106 int hash = key.hashCode() & _mask; 107 108 while (true) { 109 K mapKey = _keys[hash]; 110 111 if (mapKey == key) 112 return _values[hash]; 113 else if (mapKey == null) { 114 if ((_flags[hash] & DELETED) == 0) 115 return NULL; 116 } 117 else if (mapKey.equals(key)) 118 return _values[hash]; 119 120 hash = (hash + 1) & _mask; 121 } 122 } 123 124 127 private void resize(int newSize) 128 { 129 K []newKeys = (K []) new Object [newSize]; 130 long []newValues = new long[newSize]; 131 byte []newFlags = new byte[newSize]; 132 133 _mask = newKeys.length - 1; 134 135 for (int i = 0; i < _keys.length; i++) { 136 if (_keys[i] == null || (_flags[i] & DELETED) != 0) 137 continue; 138 139 int hash = _keys[i].hashCode() & _mask; 140 141 while (true) { 142 if (newKeys[hash] == null) { 143 newKeys[hash] = _keys[i]; 144 newValues[hash] = _values[i]; 145 newFlags[hash] = _flags[i]; 146 break; 147 } 148 hash = (hash + 1) & _mask; 149 } 150 } 151 152 _keys = newKeys; 153 _values = newValues; 154 _flags = newFlags; 155 } 156 157 160 public long put(K key, long value) 161 { 162 return put(key, value, false); 163 } 164 165 168 public long putIfNew(K key, long value) 169 { 170 return put(key, value, true); 171 } 172 173 176 private long put(K key, long value, boolean ifNew) 177 { 178 if (key == null) { 179 long old = _nullValue; 180 _nullValue = value; 181 return old; 182 } 183 184 int hash = key.hashCode() & _mask; 185 186 while (true) { 187 K testKey = _keys[hash]; 188 189 if (testKey == null || (_flags[hash] & DELETED) != 0) { 190 _keys[hash] = key; 191 _values[hash] = value; 192 _flags[hash] = 0; 193 194 _size++; 195 196 if (_keys.length <= 2 * _size) 197 resize(2 * _keys.length); 198 199 return NULL; 200 } 201 else if (key != testKey && ! testKey.equals(key)) { 202 hash = (hash + 1) & _mask; 203 continue; 204 } 205 else if (ifNew) { 206 return _values[hash]; 207 } 208 else { 209 long old = _values[hash]; 210 211 _values[hash] = value; 212 213 return old; 214 } 215 } 216 } 217 218 221 public long remove(K key) 222 { 223 if (key == null) { 224 long old = _nullValue; 225 _nullValue = NULL; 226 return old; 227 } 228 229 int hash = key.hashCode() & _mask; 230 231 while (true) { 232 Object mapKey = _keys[hash]; 233 234 if (mapKey == null) 235 return NULL; 236 else if (mapKey.equals(key)) { 237 _flags[hash] |= DELETED; 238 239 _size--; 240 241 _keys[hash] = null; 242 243 return _values[hash]; 244 } 245 246 hash = (hash + 1) & _mask; 247 } 248 } 249 252 public Iterator iterator() 253 { 254 return new LongMapIterator(); 255 } 256 257 public Object clone() 258 { 259 LongMap clone = new LongMap(true); 260 261 clone._keys = new Object [_keys.length]; 262 System.arraycopy(_keys, 0, clone._keys, 0, _keys.length); 263 264 clone._values = new long[_values.length]; 265 System.arraycopy(_values, 0, clone._values, 0, _values.length); 266 267 clone._flags = new byte[_flags.length]; 268 System.arraycopy(_flags, 0, clone._flags, 0, _flags.length); 269 270 clone._mask = _mask; 271 clone._size = _size; 272 273 clone._nullValue = _nullValue; 274 275 return clone; 276 } 277 278 public String toString() 279 { 280 StringBuffer sbuf = new StringBuffer (); 281 282 sbuf.append("LongMap["); 283 284 boolean isFirst = true; 285 286 for (int i = 0; i <= _mask; i++) { 287 if ((_flags[i] & DELETED) == 0 && _keys[i] != null) { 288 if (! isFirst) 289 sbuf.append(", "); 290 isFirst = false; 291 sbuf.append(_keys[i]); 292 sbuf.append(":"); 293 sbuf.append(_values[i]); 294 } 295 } 296 sbuf.append("]"); 297 298 return sbuf.toString(); 299 } 300 301 class LongMapIterator implements Iterator { 302 int _index; 303 304 public boolean hasNext() 305 { 306 for (; _index < _keys.length; _index++) 307 if (_keys[_index] != null && (_flags[_index] & DELETED) == 0) 308 return true; 309 310 return false; 311 } 312 313 public Object next() 314 { 315 for (; _index < _keys.length; _index++) 316 if (_keys[_index] != null && (_flags[_index] & DELETED) == 0) 317 return _keys[_index++]; 318 319 return null; 320 } 321 322 public void remove() 323 { 324 throw new RuntimeException (); 325 } 326 } 327 } 328 | Popular Tags |