Fixed memory leak

This commit is contained in:
Andrea Cavalli 2018-11-26 14:50:44 +01:00
parent 69951ebc50
commit 0473fa4313

View File

@ -20,8 +20,12 @@ public class FileIndexManager implements IndexManager {
private final TypesManager typesManager; private final TypesManager typesManager;
private final SeekableByteChannel dataFileChannel, metadataFileChannel; private final SeekableByteChannel dataFileChannel, metadataFileChannel;
private final FileAllocator fileAllocator; private final FileAllocator fileAllocator;
private final ByteBuffer metadataByteBuffer = ByteBuffer.allocateDirect(IndexDetails.TOTAL_BYTES);
private final ByteBuffer maskByteBuffer = ByteBuffer.allocateDirect(Integer.BYTES);
private volatile boolean closed; private volatile boolean closed;
private final Object closeLock = new Object(); private final Object closeLock = new Object();
private final Object metadataByteBufferLock = new Object();
private final Object maskByteBufferBufferLock = new Object();
/** /**
* Edit this using editIndex() * Edit this using editIndex()
@ -104,12 +108,13 @@ public class FileIndexManager implements IndexManager {
* @throws IOException * @throws IOException
*/ */
private void writeExact(final IndexDetails indexDetails, DBDataOutput<?> data) throws IOException { private void writeExact(final IndexDetails indexDetails, DBDataOutput<?> data) throws IOException {
if (indexDetails.getSize() != data.getSize()) { final int dataSize = data.getSize();
throw new IOException("Unable to write " + data.getSize() + " in a space of " + indexDetails.getSize()); if (indexDetails.getSize() != dataSize) {
throw new IOException("Unable to write " + dataSize + " in a space of " + indexDetails.getSize());
} }
final long offset = indexDetails.getOffset(); final long offset = indexDetails.getOffset();
final Output o = new Output(Channels.newOutputStream(dataFileChannel.position(offset))); final Output o = new Output(Channels.newOutputStream(dataFileChannel.position(offset)), dataSize);
data.getWriter().write(o); data.getWriter().write(o);
o.flush(); o.flush();
} }
@ -157,7 +162,7 @@ public class FileIndexManager implements IndexManager {
} }
private long createIndexMetadata(IndexDetails indexDetails) { private long createIndexMetadata(IndexDetails indexDetails) {
long newIndex = firstAllocableIndex++; Long newIndex = firstAllocableIndex++;
loadedIndices.put(newIndex, indexDetails); loadedIndices.put(newIndex, indexDetails);
dirtyLoadedIndices.add(newIndex); dirtyLoadedIndices.add(newIndex);
removedIndices.remove(newIndex); removedIndices.remove(newIndex);
@ -176,17 +181,19 @@ public class FileIndexManager implements IndexManager {
return null; return null;
} }
SeekableByteChannel currentMetadataFileChannel = metadataFileChannel.position(metadataPosition); SeekableByteChannel currentMetadataFileChannel = metadataFileChannel.position(metadataPosition);
ByteBuffer currentMetadataByteBuffer = ByteBuffer.allocateDirect(IndexDetails.TOTAL_BYTES); synchronized (metadataByteBufferLock) {
currentMetadataFileChannel.read(currentMetadataByteBuffer); metadataByteBuffer.rewind();
currentMetadataByteBuffer.flip(); currentMetadataFileChannel.read(metadataByteBuffer);
// If it's not deleted continue metadataByteBuffer.rewind();
if ((currentMetadataByteBuffer.getInt() & IndexDetails.MASK_DELETED) == 0) { // If it's not deleted continue
final long offset = currentMetadataByteBuffer.getLong(); if ((metadataByteBuffer.getInt() & IndexDetails.MASK_DELETED) == 0) {
final int size = currentMetadataByteBuffer.getInt(); final long offset = metadataByteBuffer.getLong();
final int type = currentMetadataByteBuffer.getInt(); final int size = metadataByteBuffer.getInt();
final IndexDetails indexDetails = new IndexDetails(offset, size, type); final int type = metadataByteBuffer.getInt();
editIndex(index, indexDetails); final IndexDetails indexDetails = new IndexDetails(offset, size, type);
return indexDetails; editIndex(index, indexDetails);
return indexDetails;
}
} }
// No results found. Returning null // No results found. Returning null
@ -215,30 +222,33 @@ public class FileIndexManager implements IndexManager {
// Update indices metadata // Update indices metadata
SeekableByteChannel metadata = metadataFileChannel; SeekableByteChannel metadata = metadataFileChannel;
ByteBuffer metadataEntryBuffer = ByteBuffer.allocateDirect(IndexDetails.TOTAL_BYTES);
long lastIndex = -2; long lastIndex = -2;
for (Long index : dirtyLoadedIndices) { for (Long index : dirtyLoadedIndices) {
IndexDetails indexDetails = loadedIndices.get(index); IndexDetails indexDetails = loadedIndices.get(index);
if (index - lastIndex != 1) { if (index - lastIndex != 1) {
metadata = metadata.position(index * IndexDetails.TOTAL_BYTES); metadata = metadata.position(index * IndexDetails.TOTAL_BYTES);
} }
metadataEntryBuffer.clear(); synchronized (metadataByteBufferLock) {
metadataEntryBuffer.putInt(0); metadataByteBuffer.rewind();
metadataEntryBuffer.putLong(indexDetails.getOffset()); metadataByteBuffer.putInt(0);
metadataEntryBuffer.putInt(indexDetails.getSize()); metadataByteBuffer.putLong(indexDetails.getOffset());
metadataEntryBuffer.putInt(indexDetails.getType()); metadataByteBuffer.putInt(indexDetails.getSize());
metadataEntryBuffer.flip(); metadataByteBuffer.putInt(indexDetails.getType());
metadata.write(metadataEntryBuffer); metadataByteBuffer.rewind();
metadata.write(metadataByteBuffer);
}
lastIndex = index; lastIndex = index;
} }
// Remove removed indices // Remove removed indices
ByteBuffer updatedMaskBuffer = ByteBuffer.allocateDirect(1);
for (Long index : removedIndices) { for (Long index : removedIndices) {
metadata = metadata.position(index * IndexDetails.TOTAL_BYTES); metadata = metadata.position(index * IndexDetails.TOTAL_BYTES);
updatedMaskBuffer.putInt(IndexDetails.MASK_DELETED); synchronized (maskByteBufferBufferLock) {
updatedMaskBuffer.flip(); maskByteBuffer.rewind();
metadata.write(updatedMaskBuffer); maskByteBuffer.putInt(IndexDetails.MASK_DELETED);
maskByteBuffer.rewind();
metadata.write(maskByteBuffer);
}
} }
fileAllocator.close(); fileAllocator.close();
} }