public PinnableSegment<K, V> newInstance() { StorageEngine<? super K, ? super V> storageEngine = storageEngineFactory.newInstance(); try { return new EhcacheSegment<>(tableSource, storageEngine, tableSize, evictionAdvisor, evictionListener); } catch (RuntimeException e) { storageEngine.destroy(); throw e; } }
storageEngine.attachedMapping(readLong(newEntry, ENCODING), hash, metadata); storageEngine.invalidateCache(); for (IntBuffer laterEntry = entry; i < limit; i++) { if (isTerminating(laterEntry)) { break; } else if (isPresent(laterEntry) && keyEquals(key, hash, readLong(laterEntry, ENCODING), laterEntry.get(KEY_HASHCODE))) { V old = (V) storageEngine.readValue(readLong(laterEntry, ENCODING)); storageEngine.freeMapping(readLong(laterEntry, ENCODING), laterEntry.get(KEY_HASHCODE), false); long oldEncoding = readLong(laterEntry, ENCODING); laterEntry.put(newEntry); return null; } else if (keyEquals(key, hash, readLong(entry, ENCODING), entry.get(KEY_HASHCODE))) { storageEngine.attachedMapping(readLong(newEntry, ENCODING), hash, metadata); storageEngine.invalidateCache(); V old = (V) storageEngine.readValue(readLong(entry, ENCODING)); storageEngine.freeMapping(readLong(entry, ENCODING), entry.get(KEY_HASHCODE), false); long oldEncoding = readLong(entry, ENCODING); entry.put(newEntry); storageEngine.freeMapping(readLong(newEntry, ENCODING), newEntry[KEY_HASHCODE], true);
} else if (isPresent(entry) && hash == entry.get(KEY_HASHCODE)) { @SuppressWarnings("unchecked") V removedValue = (V) storageEngine.readValue(readLong(entry, ENCODING)); @SuppressWarnings("unchecked") K removedKey = (K) storageEngine.readKey(readLong(entry, ENCODING), hash); storageEngine.freeMapping(readLong(entry, ENCODING), entry.get(KEY_HASHCODE), true);
@Override public void remove() { throw new UnsupportedOperationException(); }
@SuppressWarnings("unchecked") protected boolean removeMapping(Object o) { freePendingTables(); if (!(o instanceof Entry<?, ?>)) { return false; } Entry<K, V> e = (Entry<K, V>) o; Object key = e.getKey(); int hash = key.hashCode(); hashtable.position(indexFor(spread(hash))); for (int i = 0; i < reprobeLimit(); i++) { if (!hashtable.hasRemaining()) { hashtable.rewind(); } IntBuffer entry = (IntBuffer) hashtable.slice().limit(ENTRY_SIZE); if (isTerminating(entry)) { return false; } else if (isPresent(entry) && keyEquals(key, hash, readLong(entry, ENCODING), entry.get(KEY_HASHCODE)) && storageEngine.equalsValue(e.getValue(), readLong(entry, ENCODING))) { storageEngine.freeMapping(readLong(entry, ENCODING), entry.get(KEY_HASHCODE), true); entry.put(STATUS_REMOVED); slotRemoved(entry); shrink(); return true; } else { hashtable.position(hashtable.position() + ENTRY_SIZE); } } return false; }
protected void removeAtTableOffset(int offset, boolean shrink) { IntBuffer entry = ((IntBuffer) hashtable.duplicate().position(offset).limit(offset + ENTRY_SIZE)).slice(); if (isPresent(entry)) { storageEngine.freeMapping(readLong(entry, ENCODING), entry.get(KEY_HASHCODE), true); entry.put(STATUS, STATUS_REMOVED); slotRemoved(entry); if (shrink) { shrink(); } } else { throw new AssertionError(); } }
@Override @FindbugsSuppressWarnings("VO_VOLATILE_INCREMENT") public void clear() { if (hashtable != DESTROYED_TABLE) { freePendingTables(); modCount++; removedSlots = 0; size = 0; storageEngine.clear(); allocateOrClearTable(initialTableSize); } }
@Override public long getDataAllocatedMemory() { return storageEngine.getAllocatedMemory(); }
@Override public long getDataSize() { return storageEngine.getDataSize(); }
private boolean keyEquals(Object probeKey, int probeHash, long targetEncoding, int targetHash) { return probeHash == targetHash && storageEngine.equalsKey(probeKey, targetEncoding); }
@FindbugsSuppressWarnings("ICAST_INTEGER_MULTIPLY_CAST_TO_LONG") protected OffHeapHashMap(PageSource source, boolean tableAllocationsSteal, StorageEngine<? super K, ? super V> storageEngine, int tableSize, boolean bootstrap) { if (storageEngine == null) { throw new NullPointerException("StorageEngine implementation must be non-null"); } this.storageEngine = storageEngine; this.tableSource = source; this.tableAllocationsSteal = tableAllocationsSteal; // Find a power of 2 >= initialCapacity int capacity = 1; while (capacity < tableSize) { capacity <<= 1; } this.initialTableSize = capacity; if (bootstrap) { this.hashTablePage = allocateTable(initialTableSize); if (hashTablePage == null) { String msg = "Initial table allocation failed.\n" + "Initial Table Size (slots) : " + initialTableSize + '\n' + "Allocation Will Require : " + DebuggingUtils.toBase2SuffixedString(initialTableSize * ENTRY_SIZE * (Integer.SIZE / Byte.SIZE)) + "B\n" + "Table Page Source : " + tableSource; throw new IllegalArgumentException(msg); } hashtable = hashTablePage.asIntBuffer(); } this.storageEngine.bind(this); }
storageEngine.attachedMapping(readLong(newEntry, ENCODING), hash, metadata); storageEngine.invalidateCache(); for (IntBuffer laterEntry = entry; i < limit; i++) { if (isTerminating(laterEntry)) { break; } else if (isPresent(laterEntry) && keyEquals(key, hash, readLong(laterEntry, ENCODING), laterEntry.get(KEY_HASHCODE))) { V old = (V) storageEngine.readValue(readLong(laterEntry, ENCODING)); storageEngine.freeMapping(readLong(laterEntry, ENCODING), laterEntry.get(KEY_HASHCODE), false); long oldEncoding = readLong(laterEntry, ENCODING); laterEntry.put(newEntry); return null; } else if (keyEquals(key, hash, readLong(entry, ENCODING), entry.get(KEY_HASHCODE))) { storageEngine.attachedMapping(readLong(newEntry, ENCODING), hash, metadata); storageEngine.invalidateCache(); V old = (V) storageEngine.readValue(readLong(entry, ENCODING)); storageEngine.freeMapping(readLong(entry, ENCODING), entry.get(KEY_HASHCODE), false); long oldEncoding = readLong(entry, ENCODING); entry.put(newEntry); storageEngine.freeMapping(readLong(newEntry, ENCODING), newEntry[KEY_HASHCODE], false); //XXX: further contemplate the boolean value here
} else if (isPresent(entry) && hash == entry.get(KEY_HASHCODE)) { @SuppressWarnings("unchecked") V removedValue = (V) storageEngine.readValue(readLong(entry, ENCODING)); @SuppressWarnings("unchecked") K removedKey = (K) storageEngine.readKey(readLong(entry, ENCODING), hash); storageEngine.freeMapping(readLong(entry, ENCODING), entry.get(KEY_HASHCODE), true);
@Override public void remove() { throw new UnsupportedOperationException(); }
@SuppressWarnings("unchecked") protected boolean removeMapping(Object o) { freePendingTables(); if (!(o instanceof Entry<?, ?>)) { return false; } Entry<K, V> e = (Entry<K, V>) o; Object key = e.getKey(); int hash = key.hashCode(); hashtable.position(indexFor(spread(hash))); for (int i = 0; i < reprobeLimit(); i++) { if (!hashtable.hasRemaining()) { hashtable.rewind(); } IntBuffer entry = (IntBuffer) hashtable.slice().limit(ENTRY_SIZE); if (isTerminating(entry)) { return false; } else if (isPresent(entry) && keyEquals(key, hash, readLong(entry, ENCODING), entry.get(KEY_HASHCODE)) && storageEngine.equalsValue(e.getValue(), readLong(entry, ENCODING))) { storageEngine.freeMapping(readLong(entry, ENCODING), entry.get(KEY_HASHCODE), true); entry.put(STATUS, STATUS_REMOVED); slotRemoved(entry); shrink(); return true; } else { hashtable.position(hashtable.position() + ENTRY_SIZE); } } return false; }
protected void removeAtTableOffset(int offset, boolean shrink) { IntBuffer entry = ((IntBuffer) hashtable.duplicate().position(offset).limit(offset + ENTRY_SIZE)).slice(); if (isPresent(entry)) { storageEngine.freeMapping(readLong(entry, ENCODING), entry.get(KEY_HASHCODE), true); entry.put(STATUS, STATUS_REMOVED); slotRemoved(entry); if (shrink) { shrink(); } } else { throw new AssertionError(); } }
@Override @FindbugsSuppressWarnings("VO_VOLATILE_INCREMENT") public void clear() { if (hashtable != DESTROYED_TABLE) { freePendingTables(); modCount++; removedSlots = 0; size = 0; storageEngine.clear(); allocateOrClearTable(initialTableSize); } }
@Override public long getDataAllocatedMemory() { return storageEngine.getAllocatedMemory(); }
@Override public long getDataSize() { return storageEngine.getDataSize(); }
private boolean keyEquals(Object probeKey, int probeHash, long targetEncoding, int targetHash) { return probeHash == targetHash && storageEngine.equalsKey(probeKey, targetEncoding); }