ProcCacheChunk cc = new ProcCacheChunk(cbStartOffset, cbEndOffset, !isUncompressed, fullCompressionBlock, futureAlloc, cacheBuffers.size() - 1); toDecompress.add(cc);
for (ProcCacheChunk chunk : toDecompress) { targetBuffers[ix] = chunk.getBuffer(); ++ix; ByteBuffer dest = chunk.getBuffer().getByteBufferRaw(); if (chunk.isOriginalDataCompressed) { decompressChunk(chunk.originalData, codec, dest); LOG.trace("Locking " + chunk.getBuffer() + " due to reuse (after decompression)"); cacheWrapper.reuseBuffer(chunk.getBuffer());
cc.init(cbStartOffset, cbEndOffset, !isUncompressed, fullCompressionBlock, futureAlloc, cacheBuffers.size() - 1); toDecompress.add(cc);
for (ProcCacheChunk chunk : toDecompress) { targetBuffers[ix] = chunk.getBuffer(); ++ix; while (decompressedIx < toDecompress.size()) { ProcCacheChunk chunk = toDecompress.get(decompressedIx); ByteBuffer dest = chunk.getBuffer().getByteBufferRaw(); if (chunk.isOriginalDataCompressed) { boolean isOk = false; LOG.trace("Locking " + chunk.getBuffer() + " due to reuse (after decompression)"); cacheWrapper.reuseBuffer(chunk.getBuffer()); } finally { chunk.originalData = null; csd.getCacheBuffers().remove(chunk.getBuffer()); try { cacheWrapper.getAllocator().deallocate(chunk.getBuffer()); } catch (Throwable t) { LOG.error("Ignoring the cleanup error after another error", t); chunk.setBuffer(null); ++decompressedIx;
private void releaseInitialRefcounts(DiskRangeList current) { while (current != null) { DiskRangeList toFree = current; current = current.next; if (toFree instanceof ProcCacheChunk) { ProcCacheChunk pcc = (ProcCacheChunk)toFree; if (pcc.originalData != null) { // TODO: can this still happen? we now clean these up explicitly to avoid other issues. // This can only happen in case of failure - we read some data, but didn't decompress // it. Deallocate the buffer directly, do not decref. if (pcc.getBuffer() != null) { cacheWrapper.getAllocator().deallocate(pcc.getBuffer()); } continue; } } if (!(toFree instanceof CacheChunk)) continue; CacheChunk cc = (CacheChunk)toFree; if (cc.getBuffer() == null) continue; MemoryBuffer buffer = cc.getBuffer(); cacheWrapper.releaseBuffer(buffer); cc.setBuffer(null); } }
@Override public void handleCacheCollision(DataCache cacheWrapper, MemoryBuffer replacementBuffer, List<MemoryBuffer> cacheBuffers) { assert originalCbIndex >= 0; // Had the put succeeded for our new buffer, it would have refcount of 2 - 1 from put, // and 1 from notifyReused call above. "Old" buffer now has the 1 from put; new buffer // is not in cache. cacheWrapper.getAllocator().deallocate(getBuffer()); cacheWrapper.reuseBuffer(replacementBuffer); // Replace the buffer in our big range list, as well as in current results. this.buffer = replacementBuffer; cacheBuffers.set(originalCbIndex, replacementBuffer); originalCbIndex = -1; // This can only happen once at decompress time. }
@Override public ProcCacheChunk create() { return new ProcCacheChunk(); } @Override
@Override public void resetBeforeOffer(ProcCacheChunk t) { t.reset(); } });