53 lines
1.6 KiB
Java
53 lines
1.6 KiB
Java
package org.warp.cowdb.database;
|
|
|
|
|
|
import org.warp.cowdb.BlockInfo;
|
|
import org.warp.cowdb.IBlocksMetadata;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.channels.SeekableByteChannel;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.StandardOpenOption;
|
|
|
|
public class DatabaseBlocksMetadata implements IBlocksMetadata {
|
|
private final SeekableByteChannel metaFileChannel;
|
|
private final int BLOCK_META_BYTES_COUNT = Long.BYTES + Integer.BYTES;
|
|
private long firstFreeBlock;
|
|
|
|
public DatabaseBlocksMetadata(Path metaFile) throws IOException {
|
|
metaFileChannel = Files.newByteChannel(metaFile, StandardOpenOption.READ, StandardOpenOption.WRITE);
|
|
firstFreeBlock = metaFileChannel.size() / BLOCK_META_BYTES_COUNT;
|
|
}
|
|
|
|
@Override
|
|
public BlockInfo getBlockInfo(long blockId) throws IOException {
|
|
if (blockId == EMPTY_BLOCK_ID) {
|
|
return EMPTY_BLOCK_INFO;
|
|
}
|
|
ByteBuffer buffer = ByteBuffer.allocate(BLOCK_META_BYTES_COUNT);
|
|
metaFileChannel.position(blockId * BLOCK_META_BYTES_COUNT).read(buffer);
|
|
buffer.flip();
|
|
long index = buffer.getLong();
|
|
int size = buffer.getInt();
|
|
return new BlockInfo(index, size);
|
|
}
|
|
|
|
@Override
|
|
public long newBlock(long index, int size) throws IOException {
|
|
long newBlockId = firstFreeBlock++;
|
|
ByteBuffer data = ByteBuffer.allocate(BLOCK_META_BYTES_COUNT);
|
|
data.putLong(index);
|
|
data.putInt(size);
|
|
data.flip();
|
|
metaFileChannel.position(newBlockId * BLOCK_META_BYTES_COUNT).write(data);
|
|
return newBlockId;
|
|
}
|
|
|
|
@Override
|
|
public void close() throws IOException {
|
|
metaFileChannel.close();
|
|
}
|
|
}
|