67 lines
2.0 KiB
Java
67 lines
2.0 KiB
Java
package org.warp.cowdb.database;
|
|
|
|
import org.warp.cowdb.IReferencesMetadata;
|
|
import org.warp.jcwdb.ann.DBClass;
|
|
|
|
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;
|
|
|
|
import static org.warp.cowdb.IBlocksMetadata.EMPTY_BLOCK_ID;
|
|
|
|
public class DatabaseReferencesMetadata implements IReferencesMetadata {
|
|
private final SeekableByteChannel metaFileChannel;
|
|
private final int REF_META_BYTES_COUNT = Long.BYTES;
|
|
private long firstFreeReference;
|
|
|
|
public DatabaseReferencesMetadata(Path refMetaFile) throws IOException {
|
|
metaFileChannel = Files.newByteChannel(refMetaFile, StandardOpenOption.READ, StandardOpenOption.WRITE);
|
|
firstFreeReference = metaFileChannel.size() / REF_META_BYTES_COUNT;
|
|
}
|
|
|
|
@Override
|
|
public long getReference(long reference) throws IOException {
|
|
ByteBuffer buffer = ByteBuffer.allocate(REF_META_BYTES_COUNT);
|
|
if (reference >= firstFreeReference) {
|
|
return EMPTY_BLOCK_ID;
|
|
}
|
|
SeekableByteChannel currentFileChannel = metaFileChannel.position(reference * REF_META_BYTES_COUNT);
|
|
currentFileChannel.read(buffer);
|
|
buffer.flip();
|
|
long block = buffer.getLong();
|
|
if (buffer.limit() == 0 || block == 0xFFFFFFFFFFFFFFFFL) {
|
|
return EMPTY_BLOCK_ID;
|
|
}
|
|
return block;
|
|
}
|
|
|
|
@Override
|
|
public long newReference(long blockId) throws IOException {
|
|
long newReference = firstFreeReference++;
|
|
editReference(newReference, blockId);
|
|
return newReference;
|
|
}
|
|
|
|
@Override
|
|
public void editReference(long reference, long blockId) throws IOException {
|
|
ByteBuffer data = ByteBuffer.allocate(REF_META_BYTES_COUNT);
|
|
data.putLong(blockId);
|
|
SeekableByteChannel currentFileChannel = metaFileChannel.position(reference * REF_META_BYTES_COUNT);
|
|
data.flip();
|
|
currentFileChannel.write(data);
|
|
}
|
|
|
|
@Override
|
|
public void close() throws IOException {
|
|
metaFileChannel.close();
|
|
}
|
|
|
|
@Override
|
|
public long getFirstFreeReference() {
|
|
return firstFreeReference;
|
|
}
|
|
}
|