Fixed memory leak

This commit is contained in:
Andrea Cavalli 2018-11-26 14:50:44 +01:00
parent 69951ebc50
commit 0473fa4313
1 changed files with 37 additions and 27 deletions

View File

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