1 21 package com.db4o; 22 23 import java.util.*; 24 25 import com.db4o.foundation.*; 26 import com.db4o.inside.*; 27 import com.db4o.types.*; 28 29 33 public class P2HashMap extends P1Collection implements Db4oMap, TransactionListener { 34 35 private static final float FILL = 0.6F; 36 37 private transient int i_changes; 38 private transient boolean i_dontStoreOnDeactivate; 39 40 public P1HashElement[] i_entries; 41 public int i_mask; 42 public int i_maximumSize; 43 public int i_size; 44 45 public int i_type; 47 48 transient P1HashElement[] i_table; 49 50 public int i_tableSize; 51 52 P2HashMap() { 53 } 54 55 P2HashMap(int a_size) { 56 a_size = (int) (a_size / FILL); 57 i_tableSize = 1; 58 while (i_tableSize < a_size) { 59 i_tableSize = i_tableSize << 1; 60 } 61 i_mask = i_tableSize - 1; 62 i_maximumSize = (int) (i_tableSize * FILL); 63 i_table = new P1HashElement[i_tableSize]; 64 } 65 66 public int activationDepth() { 67 return 2; 68 } 69 70 public int adjustReadDepth(int a_depth) { 71 return 2; 72 } 73 74 public void checkActive() { 75 super.checkActive(); 76 if (i_table == null) { 77 i_table = new P1HashElement[i_tableSize]; 78 if (i_entries != null) { 79 for (int i = 0; i < i_entries.length; i++) { 80 if(i_entries[i] != null){ 81 i_entries[i].checkActive(); 82 i_table[i_entries[i].i_position] = i_entries[i]; 83 } 84 } 85 } 86 i_changes = 0; 87 88 91 97 } 98 } 99 100 public void clear() { 101 synchronized (streamLock()) { 102 checkActive(); 103 if (i_size != 0) { 104 for (int i = 0; i < i_table.length; i++) { 105 deleteAllElements(i_table[i]); 106 i_table[i] = null; 107 } 108 if(i_entries != null){ 109 for (int i = 0; i < i_entries.length; i++) { 110 i_entries[i] = null; 111 } 112 } 113 i_size = 0; 114 modified(); 115 } 116 } 117 } 118 119 public boolean containsKey(Object key) { 120 return get(key) != null; 121 } 122 123 public boolean containsValue(Object value) { 124 throw new UnsupportedOperationException (); 125 } 126 127 public Object createDefault(Transaction a_trans) { 128 checkActive(); 129 P2HashMap m4 = new P2HashMap(i_size); 130 m4.i_type = i_type; 131 m4.setTrans(a_trans); 132 P2HashMapIterator i = new P2HashMapIterator(this); 133 while (i.hasNext()) { 134 Object key = i.next(); 135 if(key != null){ 136 m4.put4(key, get4(key)); 137 } 138 } 139 return m4; 140 } 141 142 private void deleteAllElements(P1HashElement a_entry) { 143 if (a_entry != null) { 144 a_entry.checkActive(); 145 deleteAllElements((P1HashElement)a_entry.i_next); 146 a_entry.delete(i_deleteRemoved); 147 } 148 } 149 150 public Set entrySet() { 151 final HashSet out = new HashSet(size()); 152 153 Iterator itor = keySet().iterator(); 154 155 while (itor.hasNext()){ 156 final Object key = itor.next(); 157 final Object value = get(key); 158 final MapEntry entry = new MapEntry(key); 159 entry.setValue(value); 160 out.add(entry); 161 } 162 163 return out; 164 } 165 166 private boolean equals(P1HashElement phe, int hashCode, Object key) { 167 return phe.i_hashCode == hashCode && phe.activatedKey(elementActivationDepth()).equals(key); 168 } 169 170 public Object get(Object key) { 171 synchronized (streamLock()) { 172 checkActive(); 173 return get4(key); 174 } 175 } 176 177 Object get4(Object key) { 178 if(key == null){ 179 return null; 180 } 181 int hash = hashOf(key); 182 P1HashElement phe = i_table[hash & i_mask]; 183 while (phe != null) { 184 phe.checkActive(); 185 if (equals(phe, hash, key)) { 186 return phe.activatedObject(elementActivationDepth()); 187 } 188 phe = (P1HashElement)phe.i_next; 189 } 190 return null; 191 } 192 193 private int hashOf(Object key) { 194 if(i_type == 1) { 195 int id = (int)getIDOf(key); 196 if(id == 0) { 197 store(key); 198 } 199 id = (int)getIDOf(key); 200 if(id == 0) { 201 Exceptions4.throwRuntimeException(62); 202 } 203 return id; 204 } 205 return key.hashCode(); 206 } 207 208 209 private void increaseSize() { 210 i_tableSize = i_tableSize << 1; 211 i_maximumSize = (int) (i_tableSize * FILL); 212 i_mask = i_tableSize - 1; 213 P1HashElement[] temp = i_table; 214 i_table = new P1HashElement[i_tableSize]; 215 for (int i = 0; i < temp.length; i++) { 216 reposition(temp[i]); 217 } 218 } 219 220 public boolean isEmpty() { 221 return size() == 0; 222 } 223 224 public Set keySet() { 225 return new P2HashMapKeySet(this); 226 } 227 228 void modified() { 229 if (getTrans() != null) { 230 if (i_changes == 0) { 231 getTrans().addTransactionListener(this); 232 } 233 i_changes++; 234 } 235 } 236 237 public void postRollback() { 238 i_dontStoreOnDeactivate = true; 239 deactivate(); 240 i_dontStoreOnDeactivate = false; 241 } 242 243 public void preCommit() { 244 if (i_changes > 0) { 245 Collection4 col = new Collection4(); 246 for (int i = 0; i < i_table.length; i++) { 247 if (i_table[i] != null) { 248 i_table[i].checkActive(); 249 if (i_table[i].i_position != i) { 250 i_table[i].i_position = i; 251 i_table[i].update(); 252 } 253 col.add(i_table[i]); 254 } 255 } 256 if (i_entries == null || i_entries.length != col.size()) { 257 i_entries = new P1HashElement[col.size()]; 258 } 259 int i = 0; 260 Iterator4 it = col.iterator(); 261 while (it.moveNext()) { 262 i_entries[i++] = (P1HashElement)it.current(); 263 } 264 store(2); 265 } 266 i_changes = 0; 267 } 268 269 public void preDeactivate() { 270 if (!i_dontStoreOnDeactivate) { 271 preCommit(); 272 } 273 i_table = null; 274 } 275 276 public Object put(Object key, Object value) { 277 synchronized (streamLock()) { 278 checkActive(); 279 return put4(key, value); 280 } 281 } 282 283 private Object put4(Object key, Object value) { 284 int hash = hashOf(key); 285 P1HashElement entry = new P1HashElement(getTrans(), null, key, hash, value); 286 i_size++; 287 if (i_size > i_maximumSize) { 288 increaseSize(); 289 } 290 modified(); 291 int index = entry.i_hashCode & i_mask; 292 P1HashElement phe = i_table[index]; 293 P1HashElement last = null; 294 while (phe != null) { 295 phe.checkActive(); 296 if (equals(phe, entry.i_hashCode, key)) { 297 i_size--; 298 Object ret = phe.activatedObject(elementActivationDepth()); 299 entry.i_next = phe.i_next; 300 store(entry); 301 if (last != null) { 302 last.i_next = entry; 303 last.update(); 304 } else { 305 i_table[index] = entry; 306 } 307 phe.delete(i_deleteRemoved); 308 return ret; 309 } 310 last = phe; 311 phe = (P1HashElement)phe.i_next; 312 } 313 entry.i_next = i_table[index]; 314 i_table[index] = entry; 315 store(entry); 316 return null; 317 } 318 319 public void putAll(Map t) { 320 synchronized (streamLock()) { 321 checkActive(); 322 Iterator i = t.keySet().iterator(); 323 while (i.hasNext()) { 324 Object key = i.next(); 325 if (key != null) { 326 put4(key, t.get(key)); 327 } 328 } 329 } 330 } 331 332 public Object remove(Object key) { 333 synchronized (streamLock()) { 334 checkActive(); 335 return remove4(key); 336 } 337 } 338 339 Object remove4(Object key) { 340 int hash = hashOf(key); 341 P1HashElement phe = i_table[hash & i_mask]; 342 P1HashElement last = null; 343 while (phe != null) { 344 phe.checkActive(); 345 if (equals(phe, hash, key)) { 346 if (last != null) { 347 last.i_next = phe.i_next; 348 last.update(); 349 } else { 350 i_table[hash & i_mask] = (P1HashElement)phe.i_next; 351 } 352 modified(); 353 i_size--; 354 Object obj = phe.activatedObject(elementActivationDepth()); 355 phe.delete(i_deleteRemoved); 356 return obj; 357 } 358 last = phe; 359 phe = (P1HashElement)phe.i_next; 360 } 361 return null; 362 } 363 364 public void replicateFrom(Object obj) { 365 checkActive(); 366 if(i_entries != null){ 367 for (int i = 0; i < i_entries.length; i++) { 368 if(i_entries[i] != null){ 369 i_entries[i].delete(false); 370 } 371 i_entries[i] = null; 372 } 373 } 374 if(i_table != null){ 375 for (int i = 0; i < i_table.length; i++) { 376 i_table[i] = null; 377 } 378 } 379 i_size = 0; 380 381 P2HashMap m4 = (P2HashMap)obj; 382 m4.checkActive(); 383 P2HashMapIterator i = new P2HashMapIterator(m4); 384 while (i.hasNext()) { 385 Object key = i.next(); 386 put4(key, m4.get4(key)); 387 } 388 389 modified(); 390 } 391 392 393 private void reposition(P1HashElement a_entry) { 394 if (a_entry != null) { 395 reposition((P1HashElement)a_entry.i_next); 396 a_entry.checkActive(); 397 Object oldNext = a_entry.i_next; 398 a_entry.i_next = i_table[a_entry.i_hashCode & i_mask]; 399 if (a_entry.i_next != oldNext) { 400 a_entry.update(); 401 } 402 i_table[a_entry.i_hashCode & i_mask] = a_entry; 403 } 404 } 405 406 public int size() { 407 synchronized (streamLock()) { 408 checkActive(); 409 return i_size; 410 } 411 } 412 413 public Object storedTo(Transaction a_trans) { 414 if (getTrans() == null) { 415 setTrans(a_trans); 416 modified(); 417 } else { 418 if (a_trans != getTrans()) { 419 return replicate(getTrans(), a_trans); 420 421 423 } 428 } 429 return this; 430 } 431 432 public Collection values() { 433 throw new UnsupportedOperationException (); 434 } 435 436 private class MapEntry implements Map.Entry { 437 private Object key; 438 439 private Object value; 440 441 public MapEntry(Object key) { 442 this.key = key; 443 } 444 445 public Object getKey() { 446 return key; 447 } 448 449 public Object getValue() { 450 return value; 451 } 452 453 public Object setValue(Object value) { 454 Object result = this.value; 455 this.value = value; 456 return result; 457 } 458 459 public boolean equals(Object obj) { 460 if (!(obj instanceof MapEntry)) 461 return false; 462 463 MapEntry other = (MapEntry) obj; 464 465 return (key.equals(other.key)) && (value.equals(other.value)); 466 } 467 468 public int hashCode() { 469 return key.hashCode() ^ value.hashCode(); 470 } 471 } 472 } 473 | Popular Tags |