package it.cavallium.strangedb.database.references; import it.cavallium.strangedb.database.IReferencesIO; import it.cavallium.strangedb.database.blocks.DatabaseBlocksIO; import java.io.IOException; import java.nio.ByteBuffer; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import static it.cavallium.strangedb.database.IBlocksMetadata.EMPTY_BLOCK_ID; public class DatabaseReferencesIO implements IReferencesIO { private final DatabaseBlocksIO blocksIO; private final DatabaseReferencesMetadata referencesMetadata; private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false); public DatabaseReferencesIO(DatabaseBlocksIO blocksIO, DatabaseReferencesMetadata referencesMetadata) { this.blocksIO = blocksIO; this.referencesMetadata = referencesMetadata; } @Override public long allocateReference() throws IOException { return referencesMetadata.newReference(EMPTY_BLOCK_ID); } @Override public long allocateReference(int size, ByteBuffer data) throws IOException { long blockId = (size == 0) ? EMPTY_BLOCK_ID : blocksIO.newBlock(size, data); return referencesMetadata.newReference(blockId); } @Override public void writeToReference(long reference, byte cleanerId, int size, ByteBuffer data) throws IOException { lock.writeLock().lock(); try { long blockId = (size == 0) ? EMPTY_BLOCK_ID : blocksIO.newBlock(size, data); referencesMetadata.editReference(reference, cleanerId, blockId); } finally { lock.writeLock().unlock(); } } @Override public ByteBuffer readFromReference(long reference) throws IOException { lock.readLock().lock(); try { long blockId = referencesMetadata.getReferenceBlockId(reference); return blocksIO.readBlock(blockId); } finally { lock.readLock().unlock(); } } }