/** * Frees the supplied buffer. * <p> * If the given buffer was not allocated by this source or has already been * freed then an {@code AssertionError} is thrown. */ @Override public synchronized void free(Page page) { if (page.isFreeable()) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Freeing a {}B buffer from chunk {} &{}", DebuggingUtils.toBase2SuffixedString(page.size()), page.index(), page.address()); } markAllAvailable(); sliceAllocators.get(page.index()).free(page.address(), page.size()); victims.get(page.index()).remove(page); victimAllocators.get(page.index()).tryFree(page.address(), page.size()); if (!fallingThresholds.isEmpty()) { long allocated = getAllocatedSize(); fireThresholds(allocated + page.size(), allocated); } } }
@Override public MappedByteBuffer asByteBuffer() { return (MappedByteBuffer) super.asByteBuffer(); } }
victimAllocator.claim(p.address(), p.size()); int claimSize = p.address() - claimAddress; if (claimSize > 0) { tempHolds.add(new AllocatedRegion(claimAddress, claimSize)); victimAllocator.claim(claimAddress, claimSize); claimAddress = p.address() + p.size(); OffHeapStorageArea a = p.binding(); Collection<Page> c = releases.get(a); if (c == null) { victimAllocator.free(p.address(), p.size()); free(p); for (Page p : targets) { if (results.contains(p)) { victimAllocator.free(p.address(), p.size()); free(p); } else { for (Page p : failedReleases) { if (victims.get(p.index()).floor(p) == p) { victimAllocator.free(p.address(), p.size());
private boolean tryExpandTable() { if (tableResizing.get()) { throw new AssertionError("Expand requested in context of an existing resize - this should be impossible"); } else { tableResizing.set(Boolean.TRUE); try { Page newTablePage = expandTable(1); if (newTablePage == null) { return false; } else { freeTable(hashTablePage, hashtable, reprobeLimit()); hashTablePage = newTablePage; hashtable = newTablePage.asIntBuffer(); removedSlots = 0; return true; } } finally { tableResizing.remove(); } } }
@Override public String toString() { return "Asynchronous flush of Page[" + System.identityHashCode(page) + "] (size=" + page.size() + ")"; } });
for (int i = pages.size() - 1; i >= 0; i--) { Page free = pages.get(i); allocator.expand(-free.size()); pages.remove(i); if (targets.remove(free)) { Page f = freePageSource.next(); validate(!VALIDATING || f != t); validate(!VALIDATING || f.size() == t.size()); ((ByteBuffer) f.asByteBuffer().clear()).put((ByteBuffer) t.asByteBuffer().clear()); pages.put(index, f); recovered.add(t);
victimAllocator.claim(p.address(), p.size()); int claimSize = p.address() - claimAddress; if (claimSize > 0) { tempHolds.add(new AllocatedRegion(claimAddress, claimSize)); victimAllocator.claim(claimAddress, claimSize); claimAddress = p.address() + p.size(); OffHeapStorageArea a = p.binding(); Collection<Page> c = releases.get(a); if (c == null) { victimAllocator.free(p.address(), p.size()); free(p); for (Page p : targets) { if (results.contains(p)) { victimAllocator.free(p.address(), p.size()); free(p); } else { for (Page p : failedReleases) { if (victims.get(p.index()).floor(p) == p) { victimAllocator.free(p.address(), p.size());
private boolean tryExpandTable() { if (tableResizing.get()) { throw new AssertionError("Expand requested in context of an existing resize - this should be impossible"); } else { tableResizing.set(Boolean.TRUE); try { Page newTablePage = expandTable(1); if (newTablePage == null) { return false; } else { freeTable(hashTablePage, hashtable, reprobeLimit()); hashTablePage = newTablePage; hashtable = newTablePage.asIntBuffer(); removedSlots = 0; return true; } } finally { tableResizing.remove(); } } }
@Override public String toString() { return "Asynchronous flush of Page[" + System.identityHashCode(page) + "] (size=" + page.size() + ")"; } });
for (int i = pages.size() - 1; i >= 0; i--) { Page free = pages.get(i); allocator.expand(-free.size()); pages.remove(i); if (targets.remove(free)) { Page f = freePageSource.next(); validate(!VALIDATING || f != t); validate(!VALIDATING || f.size() == t.size()); ((ByteBuffer) f.asByteBuffer().clear()).put((ByteBuffer) t.asByteBuffer().clear()); pages.put(index, f); recovered.add(t);
/** * Frees the supplied buffer. * <p> * If the given buffer was not allocated by this source or has already been * freed then an {@code AssertionError} is thrown. */ @Override public synchronized void free(Page page) { if (page.isFreeable()) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Freeing a {}B buffer from chunk {} &{}", DebuggingUtils.toBase2SuffixedString(page.size()), page.index(), page.address()); } markAllAvailable(); sliceAllocators.get(page.index()).free(page.address(), page.size()); victims.get(page.index()).remove(page); victimAllocators.get(page.index()).tryFree(page.address(), page.size()); if (!fallingThresholds.isEmpty()) { long allocated = getAllocatedSize(); fireThresholds(allocated + page.size(), allocated); } } }
@Override public MappedByteBuffer asByteBuffer() { return (MappedByteBuffer) super.asByteBuffer(); } }
private void shrinkTableImpl() { if (tableResizing.get()) { LOGGER.debug("Shrink request ignored in the context of an in-process expand - likely self stealing"); } else { tableResizing.set(Boolean.TRUE); try { float shrinkRatio = (TABLE_RESIZE_THRESHOLD * getTableCapacity()) / size; int shrinkShift = Integer.numberOfTrailingZeros(Integer.highestOneBit(Math.max(2, (int) shrinkRatio))); Page newTablePage = shrinkTableImpl(shrinkShift); if (newTablePage == null) { currentTableShrinkThreshold = currentTableShrinkThreshold / 2; } else { currentTableShrinkThreshold = TABLE_SHRINK_THRESHOLD; freeTable(hashTablePage, hashtable, reprobeLimit()); hashTablePage = newTablePage; hashtable = newTablePage.asIntBuffer(); removedSlots = 0; } } finally { tableResizing.remove(); } } }
@Override public String toString() { StringBuilder sb = new StringBuilder("OffHeapStorageArea\n"); for (int i = 0; i < pages.size(); ) { Page p = pages.get(i++); if (p == null) { break; } else { int size = p.size(); int count = 1; while (i < pages.size()) { Page q = pages.get(i); if (q != null && q.size() == size) { count++; i++; } else { break; } } sb.append("\t").append(count).append(" ").append(toBase2SuffixedString(size)).append("B page").append(count == 1 ? "\n" : "s\n"); } } sb.append("Allocator: ").append(allocator).append('\n'); sb.append("Page Source: ").append(pageSource); return sb.toString(); }
private Page allocateTable(int size) { Page newTablePage = tableSource.allocate(size * ENTRY_SIZE * (Integer.SIZE / Byte.SIZE), tableAllocationsSteal, false, null); if (newTablePage != null) { ByteBuffer buffer = newTablePage.asByteBuffer(); byte[] zeros = new byte[1024]; buffer.clear(); while (buffer.hasRemaining()) { if (buffer.remaining() < zeros.length) { buffer.put(zeros, 0, buffer.remaining()); } else { buffer.put(zeros); } } buffer.clear(); } return newTablePage; }
private void shrinkTableImpl() { if (tableResizing.get()) { LOGGER.debug("Shrink request ignored in the context of an in-process expand - likely self stealing"); } else { tableResizing.set(Boolean.TRUE); try { float shrinkRatio = (TABLE_RESIZE_THRESHOLD * getTableCapacity()) / size; int shrinkShift = Integer.numberOfTrailingZeros(Integer.highestOneBit(Math.max(2, (int) shrinkRatio))); Page newTablePage = shrinkTableImpl(shrinkShift); if (newTablePage == null) { currentTableShrinkThreshold = currentTableShrinkThreshold / 2; } else { currentTableShrinkThreshold = TABLE_SHRINK_THRESHOLD; freeTable(hashTablePage, hashtable, reprobeLimit()); hashTablePage = newTablePage; hashtable = newTablePage.asIntBuffer(); removedSlots = 0; } } finally { tableResizing.remove(); } } }
@Override public void persist(ObjectOutput output) throws IOException { Lock l = writeLock(); l.lock(); try { output.writeInt(MAGIC); output.writeLong(((MappedPageSource) tableSource).getAddress(hashTablePage)); output.writeInt(hashTablePage.size()); output.writeInt(reprobeLimit); ((Persistent) storageEngine).persist(output); } finally { l.unlock(); } }
@Override public Page allocate(final int size, boolean thief, boolean victim, OffHeapStorageArea owner) { ByteBuffer buffer = source.allocateBuffer(size); if (buffer == null) { return null; } else { return new Page(buffer, owner); } }