Version 1.5.5
This commit is contained in:
parent
67c21e382b
commit
ca03ef4791
10
pom.xml
10
pom.xml
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
<groupId>it.cavallium</groupId>
|
<groupId>it.cavallium</groupId>
|
||||||
<artifactId>strangedb</artifactId>
|
<artifactId>strangedb</artifactId>
|
||||||
<version>1.5.4</version>
|
<version>1.5.5</version>
|
||||||
|
|
||||||
<name>strangedb</name>
|
<name>strangedb-java</name>
|
||||||
<url>https://git.ignuranza.net/andreacavalli/strangedb</url>
|
<url>https://git.ignuranza.net/andreacavalli/strangedb</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@ -43,9 +43,9 @@
|
|||||||
<version>5.0.0-RC1</version>
|
<version>5.0.0-RC1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.openhft</groupId>
|
<groupId>it.cavallium</groupId>
|
||||||
<artifactId>zero-allocation-hashing</artifactId>
|
<artifactId>strangedb-core</artifactId>
|
||||||
<version>0.8</version>
|
<version>1.5.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
|
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
package it.cavallium.strangedb;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.StringJoiner;
|
|
||||||
|
|
||||||
public class BlockInfo {
|
|
||||||
private final long index;
|
|
||||||
private final int size;
|
|
||||||
|
|
||||||
public BlockInfo(long index, int size) {
|
|
||||||
this.index = index;
|
|
||||||
this.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getIndex() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
BlockInfo blockInfo = (BlockInfo) o;
|
|
||||||
return index == blockInfo.index &&
|
|
||||||
size == blockInfo.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(index, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new StringJoiner(", ", BlockInfo.class.getSimpleName() + "[", "]")
|
|
||||||
.add("index=" + index)
|
|
||||||
.add("size=" + size)
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package it.cavallium.strangedb;
|
|
||||||
|
|
||||||
public class VariableWrapper<T> {
|
|
||||||
|
|
||||||
public T var;
|
|
||||||
|
|
||||||
public VariableWrapper(T value) {
|
|
||||||
this.var = value;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,140 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import it.cavallium.strangedb.functionalinterfaces.FunctionWithIO;
|
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.StandardCopyOption;
|
|
||||||
|
|
||||||
public class Database implements IDatabase, IDatabaseTools {
|
|
||||||
|
|
||||||
private final IDatabaseTools databaseTools;
|
|
||||||
private final DatabaseFileIO fileIO;
|
|
||||||
private final DatabaseBlocksIO blocksIO;
|
|
||||||
private final DatabaseBlocksMetadata blocksMetadata;
|
|
||||||
private final DatabaseReferencesIO referencesIO;
|
|
||||||
private final DatabaseReferencesMetadata referencesMetadata;
|
|
||||||
private final DatabaseObjectsIO objectsIO;
|
|
||||||
private final Path dataFile;
|
|
||||||
private final Path blocksMetaFile;
|
|
||||||
private final Path referencesMetaFile;
|
|
||||||
private EnhancedObject loadedRootObject;
|
|
||||||
private volatile boolean closed;
|
|
||||||
|
|
||||||
public Database(Path dataFile, Path blocksMetaFile, Path referencesMetaFile) throws IOException {
|
|
||||||
if (Files.notExists(dataFile)) {
|
|
||||||
Files.createFile(dataFile);
|
|
||||||
}
|
|
||||||
if (Files.notExists(blocksMetaFile)) {
|
|
||||||
Files.createFile(blocksMetaFile);
|
|
||||||
}
|
|
||||||
if (Files.notExists(referencesMetaFile)) {
|
|
||||||
Files.createFile(referencesMetaFile);
|
|
||||||
}
|
|
||||||
this.dataFile = dataFile;
|
|
||||||
this.blocksMetaFile = blocksMetaFile;
|
|
||||||
this.referencesMetaFile = referencesMetaFile;
|
|
||||||
this.databaseTools = this;
|
|
||||||
this.fileIO = new DatabaseFileIO(dataFile);
|
|
||||||
this.blocksMetadata = new DatabaseBlocksMetadata(blocksMetaFile);
|
|
||||||
this.blocksIO = new DatabaseBlocksIO(fileIO, blocksMetadata);
|
|
||||||
this.referencesMetadata = new DatabaseReferencesMetadata(referencesMetaFile);
|
|
||||||
this.referencesIO = new DatabaseReferencesIO(blocksIO, referencesMetadata);
|
|
||||||
this.objectsIO = new DatabaseObjectsIO(databaseTools, referencesIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void close() throws IOException {
|
|
||||||
if (this.closed) {
|
|
||||||
throw new IOException("The database has been already closed!");
|
|
||||||
}
|
|
||||||
this.objectsIO.setEnhancedObject(0, loadedRootObject);
|
|
||||||
this.referencesMetadata.close();
|
|
||||||
this.blocksMetadata.close();
|
|
||||||
this.fileIO.close();
|
|
||||||
this.closed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isClosed() {
|
|
||||||
return closed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void closeAndClean() throws IOException {
|
|
||||||
if (!this.closed) {
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
Path newDataFile = dataFile.resolveSibling("compressed-data-file.tmp");
|
|
||||||
Path newBlocksFile = blocksMetaFile.resolveSibling("compressed-blocks-file.tmp");
|
|
||||||
Path newReferencesFile = referencesMetaFile.resolveSibling("compressed-references-file.tmp");
|
|
||||||
Path backupDataFile = dataFile.resolveSibling("backup-data.db.bak");
|
|
||||||
Path backupBlocksFile = blocksMetaFile.resolveSibling("backup-blocks.dat.bak");
|
|
||||||
Path backupReferencesFile = referencesMetaFile.resolveSibling("backup-references.dat.bak");
|
|
||||||
Files.copy(dataFile, backupDataFile, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
|
|
||||||
Files.copy(blocksMetaFile, backupBlocksFile, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
|
|
||||||
Files.copy(referencesMetaFile, backupReferencesFile, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
|
|
||||||
Files.move(dataFile, newDataFile, StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
Files.move(blocksMetaFile, newBlocksFile, StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
Files.move(referencesMetaFile, newReferencesFile, StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
Database databaseToClean = new Database(newDataFile, newBlocksFile, newReferencesFile);
|
|
||||||
Database newDatabase = new Database(dataFile, blocksMetaFile, referencesMetaFile);
|
|
||||||
|
|
||||||
long referencesCount = databaseToClean.referencesMetadata.getFirstFreeReference();
|
|
||||||
long blocksCount = databaseToClean.blocksMetadata.getTotalBlocksCount();
|
|
||||||
long writtenReferences = 0;
|
|
||||||
|
|
||||||
for (int referenceID = 0; referenceID < referencesCount; referenceID++) {
|
|
||||||
try {
|
|
||||||
ByteBuffer buffer = databaseToClean.referencesIO.readFromReference(referenceID);
|
|
||||||
newDatabase.referencesIO.writeToReference(referenceID, buffer.limit(), buffer);
|
|
||||||
writtenReferences++;
|
|
||||||
} catch (IOException ex) {
|
|
||||||
System.out.println("Error while reading reference " + referenceID + ". References written: " + writtenReferences);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println("References written: " + writtenReferences + ". Removed " + (blocksCount - writtenReferences) + " blocks. Removed " + (referencesCount - writtenReferences) + " references.");
|
|
||||||
databaseToClean.close();
|
|
||||||
newDatabase.close();
|
|
||||||
Files.deleteIfExists(newDataFile);
|
|
||||||
Files.deleteIfExists(newBlocksFile);
|
|
||||||
Files.deleteIfExists(newReferencesFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends EnhancedObject> T loadRoot(Class<T> type, FunctionWithIO<IDatabaseTools, T> ifAbsent) throws IOException {
|
|
||||||
if (loadedRootObject != null) {
|
|
||||||
throw new RuntimeException("Root already set!");
|
|
||||||
}
|
|
||||||
T root;
|
|
||||||
if (referencesMetadata.getFirstFreeReference() > 0) {
|
|
||||||
root = objectsIO.loadEnhancedObject(0, type);
|
|
||||||
} else {
|
|
||||||
if (objectsIO.newNullObject() != 0) {
|
|
||||||
throw new IOException("Can't allocate root!");
|
|
||||||
} else {
|
|
||||||
root = ifAbsent.apply(Database.this);
|
|
||||||
objectsIO.setEnhancedObject(0, root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadedRootObject = root;
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void registerClass(Class<?> type, int id) {
|
|
||||||
this.objectsIO.registerClass(type, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initializeEnhancedObject(EnhancedObject enhancedObject) throws IOException {
|
|
||||||
this.objectsIO.getDataInitializer().initializeDbObject(enhancedObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IObjectsIO getObjectsIO() {
|
|
||||||
return objectsIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import it.cavallium.strangedb.BlockInfo;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
import static it.cavallium.strangedb.database.IBlocksMetadata.EMPTY_BLOCK_ID;
|
|
||||||
|
|
||||||
public class DatabaseBlocksIO implements IBlocksIO {
|
|
||||||
|
|
||||||
private final DatabaseFileIO fileIO;
|
|
||||||
private final IBlocksMetadata blocksMetadata;
|
|
||||||
|
|
||||||
public DatabaseBlocksIO(DatabaseFileIO fileIO, IBlocksMetadata blocksMetadata) {
|
|
||||||
this.fileIO = fileIO;
|
|
||||||
this.blocksMetadata = blocksMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long newBlock(int size, ByteBuffer data) throws IOException {
|
|
||||||
if (size == 0) {
|
|
||||||
return EMPTY_BLOCK_ID;
|
|
||||||
}
|
|
||||||
long index = fileIO.writeAtEnd(size, data);
|
|
||||||
return blocksMetadata.newBlock(index, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuffer readBlock(long blockId) throws IOException {
|
|
||||||
if (blockId == EMPTY_BLOCK_ID) {
|
|
||||||
return ByteBuffer.wrap(new byte[0]);
|
|
||||||
}
|
|
||||||
BlockInfo blockInfo = blocksMetadata.getBlockInfo(blockId);
|
|
||||||
return fileIO.readAt(blockInfo.getIndex(), blockInfo.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
|
|
||||||
import it.cavallium.strangedb.BlockInfo;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.channels.AsynchronousFileChannel;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
public class DatabaseBlocksMetadata implements IBlocksMetadata {
|
|
||||||
public static final BlockInfo ERROR_BLOCK_INFO = new BlockInfo(-2, 0);
|
|
||||||
|
|
||||||
private final AsynchronousFileChannel metaFileChannel;
|
|
||||||
private final int BLOCK_META_BYTES_COUNT = Long.BYTES + Integer.BYTES;
|
|
||||||
private final DatabaseBlocksMetadataCache cache;
|
|
||||||
private long firstFreeBlock;
|
|
||||||
|
|
||||||
public DatabaseBlocksMetadata(Path metaFile) throws IOException {
|
|
||||||
metaFileChannel = AsynchronousFileChannel.open(metaFile, StandardOpenOption.READ, StandardOpenOption.WRITE);
|
|
||||||
firstFreeBlock = metaFileChannel.size() / BLOCK_META_BYTES_COUNT;
|
|
||||||
this.cache = new DatabaseBlocksMetadataCache(this::writeBlockToDisk);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockInfo getBlockInfo(long blockId) throws IOException {
|
|
||||||
if (blockId == EMPTY_BLOCK_ID) {
|
|
||||||
return EMPTY_BLOCK_INFO;
|
|
||||||
}
|
|
||||||
BlockInfo blockInfo;
|
|
||||||
if ((blockInfo = cache.get(blockId)) != ERROR_BLOCK_INFO) {
|
|
||||||
return blockInfo;
|
|
||||||
}
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(BLOCK_META_BYTES_COUNT);
|
|
||||||
try {
|
|
||||||
metaFileChannel.read(buffer, blockId * BLOCK_META_BYTES_COUNT).get();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new IOException(e.getCause());
|
|
||||||
}
|
|
||||||
buffer.flip();
|
|
||||||
long index = buffer.getLong();
|
|
||||||
int size = buffer.getInt();
|
|
||||||
blockInfo = new BlockInfo(index, size);
|
|
||||||
cache.put(blockId, blockInfo);
|
|
||||||
return blockInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long newBlock(long index, int size) throws IOException {
|
|
||||||
if (size == 0) {
|
|
||||||
return EMPTY_BLOCK_ID;
|
|
||||||
}
|
|
||||||
long newBlockId = firstFreeBlock++;
|
|
||||||
BlockInfo blockInfo = new BlockInfo(index, size);
|
|
||||||
cache.put(newBlockId, blockInfo);
|
|
||||||
return newBlockId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
cache.close();
|
|
||||||
metaFileChannel.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Future<Integer> writeBlockToDisk(long blockId, long index, int size) {
|
|
||||||
ByteBuffer data = ByteBuffer.allocate(BLOCK_META_BYTES_COUNT);
|
|
||||||
data.putLong(index);
|
|
||||||
data.putInt(size);
|
|
||||||
data.flip();
|
|
||||||
return metaFileChannel.write(data, blockId * BLOCK_META_BYTES_COUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalBlocksCount() {
|
|
||||||
return firstFreeBlock;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
|
||||||
import it.cavallium.strangedb.BlockInfo;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
public class DatabaseBlocksMetadataCache {
|
|
||||||
|
|
||||||
private static final int GOOD_CACHE_SIZE = 70000;
|
|
||||||
private static final int MAX_CACHE_SIZE = 100000;
|
|
||||||
|
|
||||||
private final Long2ObjectMap<BlockInfo> blocks2Info = new Long2ObjectLinkedOpenHashMap<>(MAX_CACHE_SIZE);
|
|
||||||
private final Object readAccessLock = new Object();
|
|
||||||
private final Object writeAccessLock = new Object();
|
|
||||||
private final DatabaseBlocksMetadataCacheFlusher flusher;
|
|
||||||
private volatile boolean closed;
|
|
||||||
|
|
||||||
public DatabaseBlocksMetadataCache(DatabaseBlocksMetadataCacheFlusher flusher) {
|
|
||||||
this.flusher = flusher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockInfo get(long block) throws IOException {
|
|
||||||
if (closed) throw new IOException("Cache already closed!");
|
|
||||||
synchronized (readAccessLock) {
|
|
||||||
return blocks2Info.getOrDefault(block, DatabaseBlocksMetadata.ERROR_BLOCK_INFO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void put(long block, BlockInfo blockInfo) throws IOException {
|
|
||||||
if (closed) return;
|
|
||||||
synchronized (readAccessLock) {
|
|
||||||
synchronized (writeAccessLock) {
|
|
||||||
blocks2Info.put(block, blockInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void flush() throws IOException {
|
|
||||||
if (closed) return;
|
|
||||||
int blocks2InfoSize = blocks2Info.size();
|
|
||||||
if (blocks2InfoSize > MAX_CACHE_SIZE) {
|
|
||||||
synchronized (writeAccessLock) {
|
|
||||||
ObjectIterator<Long2ObjectMap.Entry<BlockInfo>> entriesIterator = blocks2Info.long2ObjectEntrySet().iterator();
|
|
||||||
List<Future<?>> entriesToFlush = new LinkedList<>();
|
|
||||||
while (blocks2InfoSize > GOOD_CACHE_SIZE) {
|
|
||||||
Long2ObjectMap.Entry<BlockInfo> entry = entriesIterator.next();
|
|
||||||
BlockInfo blockInfo = entry.getValue();
|
|
||||||
entriesToFlush.add(flusher.flush(entry.getLongKey(), blockInfo.getIndex(), blockInfo.getSize()));
|
|
||||||
entriesIterator.remove();
|
|
||||||
if (entriesToFlush.size() >= 1000) {
|
|
||||||
executeAsyncFlush(entriesToFlush);
|
|
||||||
}
|
|
||||||
blocks2InfoSize--;
|
|
||||||
}
|
|
||||||
executeAsyncFlush(entriesToFlush);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws IOException {
|
|
||||||
synchronized (readAccessLock) {
|
|
||||||
synchronized (writeAccessLock) {
|
|
||||||
if (!closed) {
|
|
||||||
closed = true;
|
|
||||||
int blocks2InfoSize = blocks2Info.size();
|
|
||||||
ObjectIterator<Long2ObjectMap.Entry<BlockInfo>> entriesIterator = blocks2Info.long2ObjectEntrySet().iterator();
|
|
||||||
List<Future<?>> entriesToFlush = new LinkedList<>();
|
|
||||||
while (blocks2InfoSize > 0) {
|
|
||||||
Long2ObjectMap.Entry<BlockInfo> entry = entriesIterator.next();
|
|
||||||
BlockInfo blockInfo = entry.getValue();
|
|
||||||
entriesToFlush.add(flusher.flush(entry.getLongKey(), blockInfo.getIndex(), blockInfo.getSize()));
|
|
||||||
entriesIterator.remove();
|
|
||||||
if (entriesToFlush.size() >= 1000) {
|
|
||||||
executeAsyncFlush(entriesToFlush);
|
|
||||||
}
|
|
||||||
blocks2InfoSize--;
|
|
||||||
}
|
|
||||||
executeAsyncFlush(entriesToFlush);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeAsyncFlush(List<Future<?>> entriesToFlush) throws IOException {
|
|
||||||
try {
|
|
||||||
for (Future<?> entryToFlush : entriesToFlush) {
|
|
||||||
entryToFlush.get();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new IOException(e.getCause());
|
|
||||||
} finally {
|
|
||||||
entriesToFlush.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
public interface DatabaseBlocksMetadataCacheFlusher {
|
|
||||||
Future<Integer> flush(long key, long value1, int value2) throws IOException;
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
|
|
||||||
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 DatabaseFileIO implements IFileIO {
|
|
||||||
|
|
||||||
private final SeekableByteChannel dataFileChannel;
|
|
||||||
private final Object dataAccessLock = new Object();
|
|
||||||
private long firstFreeIndex;
|
|
||||||
|
|
||||||
public DatabaseFileIO(Path dataFile) throws IOException {
|
|
||||||
synchronized (dataAccessLock) {
|
|
||||||
dataFileChannel = Files.newByteChannel(dataFile, StandardOpenOption.READ, StandardOpenOption.WRITE);
|
|
||||||
firstFreeIndex = dataFileChannel.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuffer readAt(long index, int length) throws IOException {
|
|
||||||
ByteBuffer dataBuffer = ByteBuffer.allocate(length);
|
|
||||||
dataFileChannel.position(index).read(dataBuffer);
|
|
||||||
dataBuffer.flip();
|
|
||||||
return dataBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeAt(long index, int length, ByteBuffer data) throws IOException {
|
|
||||||
synchronized (dataAccessLock) {
|
|
||||||
if (data.position() != 0) {
|
|
||||||
throw new IOException("You didn't flip the ByteBuffer!");
|
|
||||||
}
|
|
||||||
if (firstFreeIndex < index + length) {
|
|
||||||
firstFreeIndex = index + length;
|
|
||||||
}
|
|
||||||
dataFileChannel.position(index).write(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long writeAtEnd(int length, ByteBuffer data) throws IOException {
|
|
||||||
synchronized (dataAccessLock) {
|
|
||||||
long index = firstFreeIndex;
|
|
||||||
firstFreeIndex += length;
|
|
||||||
writeAt(index, length, data);
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
synchronized (dataAccessLock) {
|
|
||||||
dataFileChannel.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
import static it.cavallium.strangedb.database.IBlocksMetadata.EMPTY_BLOCK_ID;
|
|
||||||
|
|
||||||
public class DatabaseReferencesIO implements IReferencesIO {
|
|
||||||
|
|
||||||
private final DatabaseBlocksIO blocksIO;
|
|
||||||
private final DatabaseReferencesMetadata referencesMetadata;
|
|
||||||
|
|
||||||
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, int size, ByteBuffer data) throws IOException {
|
|
||||||
long blockId = (size == 0) ? EMPTY_BLOCK_ID : blocksIO.newBlock(size, data);
|
|
||||||
referencesMetadata.editReference(reference, blockId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuffer readFromReference(long reference) throws IOException {
|
|
||||||
long blockId = referencesMetadata.getReference(reference);
|
|
||||||
return blocksIO.readBlock(blockId);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.channels.AsynchronousFileChannel;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
import static it.cavallium.strangedb.database.IBlocksMetadata.EMPTY_BLOCK_ID;
|
|
||||||
import static it.cavallium.strangedb.database.IBlocksMetadata.ERROR_BLOCK_ID;
|
|
||||||
|
|
||||||
public class DatabaseReferencesMetadata implements IReferencesMetadata {
|
|
||||||
private final AsynchronousFileChannel metaFileChannel;
|
|
||||||
private final int REF_META_BYTES_COUNT = Long.BYTES;
|
|
||||||
private final DatabaseReferencesMetadataCache cache;
|
|
||||||
private long firstFreeReference;
|
|
||||||
|
|
||||||
public DatabaseReferencesMetadata(Path refMetaFile) throws IOException {
|
|
||||||
metaFileChannel = AsynchronousFileChannel.open(refMetaFile, StandardOpenOption.READ, StandardOpenOption.WRITE);
|
|
||||||
firstFreeReference = metaFileChannel.size() / REF_META_BYTES_COUNT;
|
|
||||||
this.cache = new DatabaseReferencesMetadataCache(this::writeReferenceToDisk);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getReference(long reference) throws IOException {
|
|
||||||
if (reference >= firstFreeReference) {
|
|
||||||
return EMPTY_BLOCK_ID;
|
|
||||||
}
|
|
||||||
long block;
|
|
||||||
if ((block = cache.get(reference)) != ERROR_BLOCK_ID) {
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(REF_META_BYTES_COUNT);
|
|
||||||
try {
|
|
||||||
metaFileChannel.read(buffer, reference * REF_META_BYTES_COUNT).get();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new IOException(e.getCause());
|
|
||||||
}
|
|
||||||
buffer.flip();
|
|
||||||
block = buffer.getLong();
|
|
||||||
if (buffer.limit() != 0 && block != 0xFFFFFFFFFFFFFFFFL) {
|
|
||||||
cache.put(reference, block);
|
|
||||||
return block;
|
|
||||||
} else {
|
|
||||||
cache.put(reference, EMPTY_BLOCK_ID);
|
|
||||||
return EMPTY_BLOCK_ID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long newReference(long blockId) throws IOException {
|
|
||||||
long newReference = firstFreeReference++;
|
|
||||||
cache.put(newReference, blockId);
|
|
||||||
return newReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void editReference(long reference, long blockId) throws IOException {
|
|
||||||
cache.put(reference, blockId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
cache.close();
|
|
||||||
metaFileChannel.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getFirstFreeReference() {
|
|
||||||
return firstFreeReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Future<Integer> writeReferenceToDisk(long reference, long blockId) {
|
|
||||||
ByteBuffer data = ByteBuffer.allocate(REF_META_BYTES_COUNT);
|
|
||||||
data.putLong(blockId);
|
|
||||||
data.flip();
|
|
||||||
return metaFileChannel.write(data, reference * REF_META_BYTES_COUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.*;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
import static it.cavallium.strangedb.database.IBlocksMetadata.ERROR_BLOCK_ID;
|
|
||||||
|
|
||||||
public class DatabaseReferencesMetadataCache {
|
|
||||||
|
|
||||||
private static final int GOOD_CACHE_SIZE = 70000;
|
|
||||||
private static final int MAX_CACHE_SIZE = 100000;
|
|
||||||
|
|
||||||
private final Long2LongMap references2Blocks = new Long2LongLinkedOpenHashMap(MAX_CACHE_SIZE);
|
|
||||||
private final Object readAccessLock = new Object();
|
|
||||||
private final Object writeAccessLock = new Object();
|
|
||||||
private final DatabaseReferencesMetadataCacheFlusher flusher;
|
|
||||||
private volatile boolean closed;
|
|
||||||
|
|
||||||
public DatabaseReferencesMetadataCache(DatabaseReferencesMetadataCacheFlusher flusher) {
|
|
||||||
this.flusher = flusher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long get(long reference) throws IOException {
|
|
||||||
synchronized (readAccessLock) {
|
|
||||||
if (closed) throw new IOException("Cache already closed!");
|
|
||||||
return references2Blocks.getOrDefault(reference, ERROR_BLOCK_ID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void put(long reference, long blockId) throws IOException {
|
|
||||||
synchronized (readAccessLock) {
|
|
||||||
synchronized (writeAccessLock) {
|
|
||||||
if (closed) return;
|
|
||||||
references2Blocks.put(reference, blockId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void flush() throws IOException {
|
|
||||||
synchronized (readAccessLock) {
|
|
||||||
synchronized (writeAccessLock) {
|
|
||||||
if (closed) return;
|
|
||||||
int references2BlocksSize = references2Blocks.size();
|
|
||||||
if (references2BlocksSize > MAX_CACHE_SIZE) {
|
|
||||||
synchronized (writeAccessLock) {
|
|
||||||
ObjectIterator<Long2LongMap.Entry> entriesIterator = references2Blocks.long2LongEntrySet().iterator();
|
|
||||||
List<Future<?>> entriesToFlush = new LinkedList<>();
|
|
||||||
while (references2BlocksSize > GOOD_CACHE_SIZE) {
|
|
||||||
Long2LongMap.Entry entry = entriesIterator.next();
|
|
||||||
entriesToFlush.add(flusher.flush(entry.getLongKey(), entry.getLongValue()));
|
|
||||||
entriesIterator.remove();
|
|
||||||
if (entriesToFlush.size() >= 1000) {
|
|
||||||
executeAsyncFlush(entriesToFlush);
|
|
||||||
}
|
|
||||||
references2BlocksSize--;
|
|
||||||
}
|
|
||||||
executeAsyncFlush(entriesToFlush);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws IOException {
|
|
||||||
synchronized (readAccessLock) {
|
|
||||||
synchronized (writeAccessLock) {
|
|
||||||
if (!closed) {
|
|
||||||
closed = true;
|
|
||||||
int references2BlocksSize = references2Blocks.size();
|
|
||||||
ObjectIterator<Long2LongMap.Entry> entriesIterator = references2Blocks.long2LongEntrySet().iterator();
|
|
||||||
List<Future<?>> entriesToFlush = new LinkedList<>();
|
|
||||||
while (references2BlocksSize > 0) {
|
|
||||||
Long2LongMap.Entry entry = entriesIterator.next();
|
|
||||||
entriesToFlush.add(flusher.flush(entry.getLongKey(), entry.getLongValue()));
|
|
||||||
entriesIterator.remove();
|
|
||||||
if (entriesToFlush.size() >= 1000) {
|
|
||||||
executeAsyncFlush(entriesToFlush);
|
|
||||||
}
|
|
||||||
references2BlocksSize--;
|
|
||||||
}
|
|
||||||
executeAsyncFlush(entriesToFlush);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeAsyncFlush(List<Future<?>> entriesToFlush) throws IOException {
|
|
||||||
synchronized (readAccessLock) {
|
|
||||||
synchronized (writeAccessLock) {
|
|
||||||
try {
|
|
||||||
for (Future<?> entryToFlush : entriesToFlush) {
|
|
||||||
entryToFlush.get();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new IOException(e.getCause());
|
|
||||||
} finally {
|
|
||||||
entriesToFlush.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
public interface DatabaseReferencesMetadataCacheFlusher {
|
|
||||||
Future<Integer> flush(long key, long value) throws IOException;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
public interface IBlocksIO {
|
|
||||||
/**
|
|
||||||
* Allocate a block
|
|
||||||
* @param size block size
|
|
||||||
* @param data block data
|
|
||||||
* @return the block id
|
|
||||||
*/
|
|
||||||
long newBlock(int size, ByteBuffer data) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a block
|
|
||||||
* @param blockId block id
|
|
||||||
* @return block data
|
|
||||||
*/
|
|
||||||
ByteBuffer readBlock(long blockId) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close file
|
|
||||||
*/
|
|
||||||
void close();
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import it.cavallium.strangedb.BlockInfo;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public interface IBlocksMetadata {
|
|
||||||
long EMPTY_BLOCK_ID = -1;
|
|
||||||
long ERROR_BLOCK_ID = -2;
|
|
||||||
BlockInfo EMPTY_BLOCK_INFO = new BlockInfo(0, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get block info
|
|
||||||
* @param blockId block id
|
|
||||||
* @return block metadata
|
|
||||||
*/
|
|
||||||
BlockInfo getBlockInfo(long blockId) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* New empty block info
|
|
||||||
* @return block id
|
|
||||||
*/
|
|
||||||
default long newBlock() {
|
|
||||||
return EMPTY_BLOCK_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set block info
|
|
||||||
* @param index block index
|
|
||||||
* @param size block size
|
|
||||||
* @return block id
|
|
||||||
*/
|
|
||||||
long newBlock(long index, int size) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set block info
|
|
||||||
* @param blockInfo block info
|
|
||||||
* @return block id
|
|
||||||
*/
|
|
||||||
default long newBlock(BlockInfo blockInfo) throws IOException {
|
|
||||||
return this.newBlock(blockInfo.getIndex(), blockInfo.getSize());
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Close file
|
|
||||||
*/
|
|
||||||
void close() throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get total count of blocks
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
long getTotalBlocksCount();
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public interface IDatabase {
|
|
||||||
|
|
||||||
void close() throws IOException;
|
|
||||||
|
|
||||||
boolean isClosed();
|
|
||||||
|
|
||||||
void closeAndClean() throws IOException;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
public interface IFileIO {
|
|
||||||
/**
|
|
||||||
* Read *length* bytes in position *index*
|
|
||||||
* @param index index
|
|
||||||
* @param length length
|
|
||||||
* @return bytes
|
|
||||||
*/
|
|
||||||
ByteBuffer readAt(long index, int length) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write *length* bytes in position *index*
|
|
||||||
* @param index index
|
|
||||||
* @param length length
|
|
||||||
* @param data bytes
|
|
||||||
*/
|
|
||||||
void writeAt(long index, int length, ByteBuffer data) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write *length* bytes in position *index*
|
|
||||||
* @param length length
|
|
||||||
* @param data bytes
|
|
||||||
* @return index
|
|
||||||
*/
|
|
||||||
long writeAtEnd(int length, ByteBuffer data) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the file
|
|
||||||
*/
|
|
||||||
void close() throws IOException;
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
public interface IReferencesIO {
|
|
||||||
/**
|
|
||||||
* Allocate a new empty reference
|
|
||||||
* @return the new reference
|
|
||||||
*/
|
|
||||||
long allocateReference() throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate a new reference with that data
|
|
||||||
* @param size data size
|
|
||||||
* @param data bytes
|
|
||||||
* @return the new reference
|
|
||||||
*/
|
|
||||||
long allocateReference(int size, ByteBuffer data) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write some data to the reference
|
|
||||||
* @param reference reference
|
|
||||||
* @param size data size
|
|
||||||
* @param data bytes
|
|
||||||
*/
|
|
||||||
void writeToReference(long reference, int size, ByteBuffer data) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read data from the reference
|
|
||||||
* @param reference reference
|
|
||||||
* @return bytes
|
|
||||||
*/
|
|
||||||
ByteBuffer readFromReference(long reference) throws IOException;
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public interface IReferencesMetadata {
|
|
||||||
/**
|
|
||||||
* Get block of reference
|
|
||||||
* @param reference reference
|
|
||||||
* @return block id
|
|
||||||
*/
|
|
||||||
long getReference(long reference) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate a block for a new reference
|
|
||||||
* @param blockId block id
|
|
||||||
* @return reference
|
|
||||||
*/
|
|
||||||
long newReference(long blockId) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change reference size
|
|
||||||
* @param reference reference
|
|
||||||
* @param blockId block id
|
|
||||||
*/
|
|
||||||
void editReference(long reference, long blockId) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close file
|
|
||||||
*/
|
|
||||||
void close() throws IOException;
|
|
||||||
|
|
||||||
long getFirstFreeReference();
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package it.cavallium.strangedb.database;
|
|
||||||
|
|
||||||
public interface Long2LongConsumer {
|
|
||||||
void accept(long a, long b);
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package it.cavallium.strangedb.functionalinterfaces;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ConsumerWithIO<T> {
|
|
||||||
|
|
||||||
void accept(T t) throws IOException;
|
|
||||||
|
|
||||||
default ConsumerWithIO<T> andThen(ConsumerWithIO<? super T> after) {
|
|
||||||
Objects.requireNonNull(after);
|
|
||||||
return (T t) -> { accept(t); after.accept(t); };
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
package it.cavallium.strangedb.functionalinterfaces;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a function that accepts one argument and produces a result.
|
|
||||||
*
|
|
||||||
* <p>This is a <a href="package-summary.html">functional interface</a>
|
|
||||||
* whose functional method is {@link #apply(Object)}.
|
|
||||||
*
|
|
||||||
* @param <T> the type of the input to the function
|
|
||||||
* @param <R> the type of the result of the function
|
|
||||||
*
|
|
||||||
* @since 1.8
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface FunctionWithIO<T, R> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies this function to the given argument.
|
|
||||||
*
|
|
||||||
* @param t the function argument
|
|
||||||
* @return the function result
|
|
||||||
*/
|
|
||||||
R apply(T t) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a composed function that first applies the {@code before}
|
|
||||||
* function to its input, and then applies this function to the result.
|
|
||||||
* If evaluation of either function throws an exception, it is relayed to
|
|
||||||
* the caller of the composed function.
|
|
||||||
*
|
|
||||||
* @param <V> the type of input to the {@code before} function, and to the
|
|
||||||
* composed function
|
|
||||||
* @param before the function to apply before this function is applied
|
|
||||||
* @return a composed function that first applies the {@code before}
|
|
||||||
* function and then applies this function
|
|
||||||
* @throws NullPointerException if before is null
|
|
||||||
*
|
|
||||||
* @see #andThen(FunctionWithIO)
|
|
||||||
*/
|
|
||||||
default <V> FunctionWithIO<V, R> compose(FunctionWithIO<? super V, ? extends T> before) {
|
|
||||||
Objects.requireNonNull(before);
|
|
||||||
return (V v) -> apply(before.apply(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a composed function that first applies this function to
|
|
||||||
* its input, and then applies the {@code after} function to the result.
|
|
||||||
* If evaluation of either function throws an exception, it is relayed to
|
|
||||||
* the caller of the composed function.
|
|
||||||
*
|
|
||||||
* @param <V> the type of output of the {@code after} function, and of the
|
|
||||||
* composed function
|
|
||||||
* @param after the function to apply after this function is applied
|
|
||||||
* @return a composed function that first applies this function and then
|
|
||||||
* applies the {@code after} function
|
|
||||||
* @throws NullPointerException if after is null
|
|
||||||
*
|
|
||||||
* @see #compose(FunctionWithIO)
|
|
||||||
*/
|
|
||||||
default <V> FunctionWithIO<T, V> andThen(FunctionWithIO<? super R, ? extends V> after) {
|
|
||||||
Objects.requireNonNull(after);
|
|
||||||
return (T t) -> after.apply(apply(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a function that always returns its input argument.
|
|
||||||
*
|
|
||||||
* @param <T> the type of the input and output objects to the function
|
|
||||||
* @return a function that always returns its input argument
|
|
||||||
*/
|
|
||||||
static <T> FunctionWithIO<T, T> identity() {
|
|
||||||
return t -> t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
package it.cavallium.strangedb.functionalinterfaces;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface RunnableWithIO {
|
|
||||||
/**
|
|
||||||
* When an object implementing interface <code>Runnable</code> is used
|
|
||||||
* to create a thread, starting the thread causes the object's
|
|
||||||
* <code>run</code> method to be called in that separately executing
|
|
||||||
* thread.
|
|
||||||
* <p>
|
|
||||||
* The general contract of the method <code>run</code> is that it may
|
|
||||||
* take any action whatsoever.
|
|
||||||
*
|
|
||||||
* @see java.lang.Thread#run()
|
|
||||||
*/
|
|
||||||
public abstract void run() throws IOException;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
package it.cavallium.strangedb.functionalinterfaces;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface SupplierWithIO<T> {
|
|
||||||
public T getWithIO() throws IOException;
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.strangedb.annotations;
|
package it.cavallium.strangedb.java.annotations;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.strangedb.annotations;
|
package it.cavallium.strangedb.java.annotations;
|
||||||
|
|
||||||
public enum DbDataType {
|
public enum DbDataType {
|
||||||
ENHANCED_OBJECT,
|
ENHANCED_OBJECT,
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.strangedb.annotations;
|
package it.cavallium.strangedb.java.annotations;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.strangedb.annotations;
|
package it.cavallium.strangedb.java.annotations;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.strangedb.annotations;
|
package it.cavallium.strangedb.java.annotations;
|
||||||
|
|
||||||
public enum DbPrimitiveType {
|
public enum DbPrimitiveType {
|
||||||
BOOLEAN,
|
BOOLEAN,
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.strangedb.annotations;
|
package it.cavallium.strangedb.java.annotations;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.strangedb.annotations;
|
package it.cavallium.strangedb.java.annotations;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
@ -1,8 +1,8 @@
|
|||||||
package it.cavallium.strangedb.database;
|
package it.cavallium.strangedb.java.database;
|
||||||
|
|
||||||
import it.cavallium.strangedb.annotations.*;
|
import it.cavallium.strangedb.java.annotations.*;
|
||||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
@ -1,9 +1,9 @@
|
|||||||
package it.cavallium.strangedb.database;
|
package it.cavallium.strangedb.java.database;
|
||||||
|
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.cavallium.strangedb.annotations.DbPrimitiveType;
|
import it.cavallium.strangedb.java.annotations.DbPrimitiveType;
|
||||||
import it.unimi.dsi.fastutil.longs.LongList;
|
import it.unimi.dsi.fastutil.longs.LongList;
|
||||||
import it.cavallium.strangedb.EnhancedObjectUpgrader;
|
import it.cavallium.strangedb.java.objects.EnhancedObjectUpgrader;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
@ -0,0 +1,62 @@
|
|||||||
|
package it.cavallium.strangedb.java.database;
|
||||||
|
|
||||||
|
import it.cavallium.strangedb.database.DatabaseCore;
|
||||||
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
|
import it.cavallium.strangedb.functionalinterfaces.FunctionWithIO;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class DatabaseJava extends DatabaseCore implements IDatabaseTools {
|
||||||
|
private final IDatabaseTools databaseTools;
|
||||||
|
private final DatabaseObjectsIO objectsIO;
|
||||||
|
private EnhancedObject loadedRootObject;
|
||||||
|
|
||||||
|
public DatabaseJava(Path dataFile, Path blocksMetaFile, Path referencesMetaFile) throws IOException {
|
||||||
|
super(dataFile, blocksMetaFile, referencesMetaFile);
|
||||||
|
this.databaseTools = this;
|
||||||
|
this.objectsIO = new DatabaseObjectsIO(databaseTools, referencesIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void close() throws IOException {
|
||||||
|
if (this.closed) {
|
||||||
|
throw new IOException("The database has been already closed!");
|
||||||
|
}
|
||||||
|
this.objectsIO.setEnhancedObject(0, loadedRootObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends EnhancedObject> T loadRoot(Class<T> type, FunctionWithIO<IDatabaseTools, T> ifAbsent) throws IOException {
|
||||||
|
if (loadedRootObject != null) {
|
||||||
|
throw new RuntimeException("Root already set!");
|
||||||
|
}
|
||||||
|
T root;
|
||||||
|
if (referencesMetadata.getFirstFreeReference() > 0) {
|
||||||
|
root = objectsIO.loadEnhancedObject(0, type);
|
||||||
|
} else {
|
||||||
|
if (objectsIO.newNullObject() != 0) {
|
||||||
|
throw new IOException("Can't allocate root!");
|
||||||
|
} else {
|
||||||
|
root = ifAbsent.apply(DatabaseJava.this);
|
||||||
|
objectsIO.setEnhancedObject(0, root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadedRootObject = root;
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerClass(Class<?> type, int id) {
|
||||||
|
this.objectsIO.registerClass(type, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initializeEnhancedObject(EnhancedObject enhancedObject) throws IOException {
|
||||||
|
this.objectsIO.getDataInitializer().initializeDbObject(enhancedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IObjectsIO getObjectsIO() {
|
||||||
|
return objectsIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,9 +1,12 @@
|
|||||||
package it.cavallium.strangedb.database;
|
package it.cavallium.strangedb.java.database;
|
||||||
|
|
||||||
import com.esotericsoftware.kryo.Kryo;
|
import com.esotericsoftware.kryo.Kryo;
|
||||||
import com.esotericsoftware.kryo.io.Input;
|
import com.esotericsoftware.kryo.io.Input;
|
||||||
import com.esotericsoftware.kryo.io.Output;
|
import com.esotericsoftware.kryo.io.Output;
|
||||||
import it.cavallium.strangedb.annotations.*;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
|
import it.cavallium.strangedb.java.objects.EnhancedObjectFullInfo;
|
||||||
|
import it.cavallium.strangedb.database.references.DatabaseReferencesIO;
|
||||||
|
import it.cavallium.strangedb.java.annotations.*;
|
||||||
import it.unimi.dsi.fastutil.booleans.BooleanArrayList;
|
import it.unimi.dsi.fastutil.booleans.BooleanArrayList;
|
||||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
||||||
import it.unimi.dsi.fastutil.chars.CharArrayList;
|
import it.unimi.dsi.fastutil.chars.CharArrayList;
|
||||||
@ -12,7 +15,6 @@ import it.unimi.dsi.fastutil.longs.LongArrayList;
|
|||||||
import it.unimi.dsi.fastutil.longs.LongList;
|
import it.unimi.dsi.fastutil.longs.LongList;
|
||||||
import it.unimi.dsi.fastutil.shorts.ShortArrayList;
|
import it.unimi.dsi.fastutil.shorts.ShortArrayList;
|
||||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
@ -1,6 +1,6 @@
|
|||||||
package it.cavallium.strangedb.database;
|
package it.cavallium.strangedb.java.database;
|
||||||
|
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
package it.cavallium.strangedb.database;
|
package it.cavallium.strangedb.java.database;
|
||||||
|
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
|
import it.cavallium.strangedb.java.database.IObjectsIO;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package it.cavallium.strangedb.database;
|
package it.cavallium.strangedb.java.database;
|
||||||
|
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
import it.unimi.dsi.fastutil.longs.LongList;
|
import it.unimi.dsi.fastutil.longs.LongList;
|
||||||
|
|
@ -1,14 +1,13 @@
|
|||||||
package it.cavallium.strangedb;
|
package it.cavallium.strangedb.java.objects;
|
||||||
|
|
||||||
import it.cavallium.strangedb.database.EnhancedObjectFullInfo;
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||||
import it.cavallium.strangedb.database.IDatabaseTools;
|
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.apache.commons.lang3.reflect.MethodUtils;
|
import org.apache.commons.lang3.reflect.MethodUtils;
|
||||||
import it.cavallium.strangedb.annotations.DbClass;
|
import it.cavallium.strangedb.java.annotations.DbClass;
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.cavallium.strangedb.annotations.DbPrimitiveType;
|
import it.cavallium.strangedb.java.annotations.DbPrimitiveType;
|
||||||
import it.cavallium.strangedb.annotations.DbPropertyGetter;
|
import it.cavallium.strangedb.java.annotations.DbPropertyGetter;
|
||||||
import it.cavallium.strangedb.annotations.DbPropertySetter;
|
import it.cavallium.strangedb.java.annotations.DbPropertySetter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
@ -1,7 +1,7 @@
|
|||||||
package it.cavallium.strangedb.database;
|
package it.cavallium.strangedb.java.objects;
|
||||||
|
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.cavallium.strangedb.annotations.DbPrimitiveType;
|
import it.cavallium.strangedb.java.annotations.DbPrimitiveType;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
@ -33,15 +33,15 @@ public class EnhancedObjectFullInfo {
|
|||||||
this.loadedPropertyValues = loadedPropertyValues;
|
this.loadedPropertyValues = loadedPropertyValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getVersion() {
|
public int getVersion() {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
long[] getFieldReferences() {
|
public long[] getFieldReferences() {
|
||||||
return fieldReferences;
|
return fieldReferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbDataType[] getFieldTypes() {
|
public DbDataType[] getFieldTypes() {
|
||||||
return fieldTypes;
|
return fieldTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,15 +61,15 @@ public class EnhancedObjectFullInfo {
|
|||||||
return primitiveFields;
|
return primitiveFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
long[] getPropertyReferences() {
|
public long[] getPropertyReferences() {
|
||||||
return propertyReferences;
|
return propertyReferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbDataType[] getPropertyTypes() {
|
public DbDataType[] getPropertyTypes() {
|
||||||
return propertyTypes;
|
return propertyTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object[] getLoadedPropertyValues() {
|
public Object[] getLoadedPropertyValues() {
|
||||||
return loadedPropertyValues;
|
return loadedPropertyValues;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package it.cavallium.strangedb;
|
package it.cavallium.strangedb.java.objects;
|
||||||
|
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.cavallium.strangedb.annotations.DbPrimitiveType;
|
import it.cavallium.strangedb.java.annotations.DbPrimitiveType;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
@ -1,10 +1,10 @@
|
|||||||
package it.cavallium.strangedb.lists;
|
package it.cavallium.strangedb.java.objects.lists;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
import it.cavallium.strangedb.database.IDatabaseTools;
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.cavallium.strangedb.annotations.DbField;
|
import it.cavallium.strangedb.java.annotations.DbField;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
package it.cavallium.strangedb.lists;
|
package it.cavallium.strangedb.java.objects.lists;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
import it.cavallium.strangedb.database.IDatabaseTools;
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.cavallium.strangedb.annotations.DbField;
|
import it.cavallium.strangedb.java.annotations.DbField;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -1,8 +1,8 @@
|
|||||||
package it.cavallium.strangedb.lists;
|
package it.cavallium.strangedb.java.objects.lists;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
import it.cavallium.strangedb.database.IDatabaseTools;
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
@ -3,12 +3,12 @@ package it.cavallium.strangedb.tests;
|
|||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
import it.cavallium.strangedb.database.IDatabaseTools;
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.cavallium.strangedb.annotations.DbField;
|
import it.cavallium.strangedb.java.annotations.DbField;
|
||||||
import it.cavallium.strangedb.annotations.DbPropertyGetter;
|
import it.cavallium.strangedb.java.annotations.DbPropertyGetter;
|
||||||
import it.cavallium.strangedb.annotations.DbPropertySetter;
|
import it.cavallium.strangedb.java.annotations.DbPropertySetter;
|
||||||
import it.cavallium.strangedb.utils.NTestUtils;
|
import it.cavallium.strangedb.utils.NTestUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package it.cavallium.strangedb.tests;
|
package it.cavallium.strangedb.tests;
|
||||||
|
|
||||||
|
import it.cavallium.strangedb.database.DatabaseCore;
|
||||||
|
import it.cavallium.strangedb.java.database.DatabaseJava;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import it.cavallium.strangedb.database.Database;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -16,14 +17,14 @@ public class EnhancedClassUpdate {
|
|||||||
private Path path1;
|
private Path path1;
|
||||||
private Path path2;
|
private Path path2;
|
||||||
private Path path3;
|
private Path path3;
|
||||||
private Database db;
|
private DatabaseJava db;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
path1 = Files.createTempFile("db-tests-", ".db");
|
path1 = Files.createTempFile("db-tests-", ".db");
|
||||||
path2 = Files.createTempFile("db-tests-", ".db");
|
path2 = Files.createTempFile("db-tests-", ".db");
|
||||||
path3 = Files.createTempFile("db-tests-", ".db");
|
path3 = Files.createTempFile("db-tests-", ".db");
|
||||||
db = new Database(path1, path2, path3);
|
db = new DatabaseJava(path1, path2, path3);
|
||||||
OldClass root = db.loadRoot(OldClass.class, OldClass::new);
|
OldClass root = db.loadRoot(OldClass.class, OldClass::new);
|
||||||
root.field1 = "Abc";
|
root.field1 = "Abc";
|
||||||
root.field2 = 12;
|
root.field2 = 12;
|
||||||
@ -33,7 +34,7 @@ public class EnhancedClassUpdate {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldUpdateClass() throws IOException {
|
public void shouldUpdateClass() throws IOException {
|
||||||
db = new Database(path1, path2, path3);
|
db = new DatabaseJava(path1, path2, path3);
|
||||||
V2Class root = db.loadRoot(V2Class.class, V2Class::new);
|
V2Class root = db.loadRoot(V2Class.class, V2Class::new);
|
||||||
assertEquals(root.field4, "Abc");
|
assertEquals(root.field4, "Abc");
|
||||||
assertEquals(root.field2, 12);
|
assertEquals(root.field2, 12);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package it.cavallium.strangedb.tests;
|
package it.cavallium.strangedb.tests;
|
||||||
|
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.cavallium.strangedb.annotations.DbField;
|
import it.cavallium.strangedb.java.annotations.DbField;
|
||||||
import it.cavallium.strangedb.annotations.DbPropertyGetter;
|
import it.cavallium.strangedb.java.annotations.DbPropertyGetter;
|
||||||
import it.cavallium.strangedb.annotations.DbPropertySetter;
|
import it.cavallium.strangedb.java.annotations.DbPropertySetter;
|
||||||
import it.cavallium.strangedb.database.IDatabaseTools;
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||||
import it.cavallium.strangedb.utils.NTestUtils;
|
import it.cavallium.strangedb.utils.NTestUtils;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package it.cavallium.strangedb.tests;
|
package it.cavallium.strangedb.tests;
|
||||||
|
|
||||||
import it.cavallium.strangedb.annotations.DbPrimitiveField;
|
import it.cavallium.strangedb.java.annotations.DbPrimitiveField;
|
||||||
import it.cavallium.strangedb.annotations.DbPrimitiveType;
|
import it.cavallium.strangedb.java.annotations.DbPrimitiveType;
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
import it.cavallium.strangedb.database.IDatabaseTools;
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.cavallium.strangedb.annotations.DbField;
|
import it.cavallium.strangedb.java.annotations.DbField;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package it.cavallium.strangedb.tests;
|
package it.cavallium.strangedb.tests;
|
||||||
|
|
||||||
import it.cavallium.strangedb.annotations.*;
|
|
||||||
import it.cavallium.strangedb.functionalinterfaces.RunnableWithIO;
|
import it.cavallium.strangedb.functionalinterfaces.RunnableWithIO;
|
||||||
import it.cavallium.strangedb.lists.EnhancedObjectStrandeDbList;
|
import it.cavallium.strangedb.java.annotations.*;
|
||||||
import it.cavallium.strangedb.lists.ObjectStrandeDbList;
|
import it.cavallium.strangedb.java.database.DatabaseJava;
|
||||||
|
import it.cavallium.strangedb.java.objects.lists.EnhancedObjectStrandeDbList;
|
||||||
|
import it.cavallium.strangedb.java.objects.lists.ObjectStrandeDbList;
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
import it.cavallium.strangedb.database.Database;
|
import it.cavallium.strangedb.database.DatabaseCore;
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
import it.cavallium.strangedb.database.IDatabaseTools;
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||||
import it.cavallium.strangedb.VariableWrapper;
|
import it.cavallium.strangedb.VariableWrapper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -23,7 +24,7 @@ public class Performance {
|
|||||||
private static Path dbDataFile;
|
private static Path dbDataFile;
|
||||||
private static Path dbBlocksFile;
|
private static Path dbBlocksFile;
|
||||||
private static Path dbReferencesFile;
|
private static Path dbReferencesFile;
|
||||||
private static Database db;
|
private static DatabaseJava db;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -48,8 +49,8 @@ public class Performance {
|
|||||||
System.out.println("-------------------------------------------------------+-----------------------------------------------------------------");
|
System.out.println("-------------------------------------------------------+-----------------------------------------------------------------");
|
||||||
System.out.println("Test name Total Time | Time at 1 Time at 10 Time at 100 Time at 1K Time at 10K");
|
System.out.println("Test name Total Time | Time at 1 Time at 10 Time at 100 Time at 1K Time at 10K");
|
||||||
System.out.println("-------------------------------------------------------+-----------------------------------------------------------------");
|
System.out.println("-------------------------------------------------------+-----------------------------------------------------------------");
|
||||||
testS("Database creation", 3000, Performance::deleteDb, Performance::generateDb, () -> {});
|
testS("DatabaseCore creation", 3000, Performance::deleteDb, Performance::generateDb, () -> {});
|
||||||
testS("Database root creation", 3000, Performance::regenDb, () -> db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new), () -> {});
|
testS("DatabaseCore root creation", 3000, Performance::regenDb, () -> db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new), () -> {});
|
||||||
final VariableWrapper<PreloadedListContainer> preloadedListContainer = new VariableWrapper<>(null);
|
final VariableWrapper<PreloadedListContainer> preloadedListContainer = new VariableWrapper<>(null);
|
||||||
final VariableWrapper<SimpleEnhancedObject> simpleEnhancedObjectContainer = new VariableWrapper<>(null);
|
final VariableWrapper<SimpleEnhancedObject> simpleEnhancedObjectContainer = new VariableWrapper<>(null);
|
||||||
testS("ObjectStrandeDbList<Int> creation", 3000, () -> {
|
testS("ObjectStrandeDbList<Int> creation", 3000, () -> {
|
||||||
@ -267,7 +268,7 @@ public class Performance {
|
|||||||
dbDataFile = Files.createFile(rootDirectory.resolve("db_data.dat"));
|
dbDataFile = Files.createFile(rootDirectory.resolve("db_data.dat"));
|
||||||
dbBlocksFile = Files.createFile(rootDirectory.resolve("db_blocks.dat"));
|
dbBlocksFile = Files.createFile(rootDirectory.resolve("db_blocks.dat"));
|
||||||
dbReferencesFile = Files.createFile(rootDirectory.resolve("db_references.dat"));
|
dbReferencesFile = Files.createFile(rootDirectory.resolve("db_references.dat"));
|
||||||
db = new Database(dbDataFile, dbBlocksFile, dbReferencesFile);
|
db = new DatabaseJava(dbDataFile, dbBlocksFile, dbReferencesFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteDb() throws IOException {
|
public static void deleteDb() throws IOException {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package it.cavallium.strangedb.tests;
|
package it.cavallium.strangedb.tests;
|
||||||
|
|
||||||
import it.cavallium.strangedb.EnhancedObjectUpgrader;
|
import it.cavallium.strangedb.java.objects.EnhancedObjectUpgrader;
|
||||||
import it.cavallium.strangedb.annotations.DbDataType;
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||||
import it.cavallium.strangedb.annotations.DbField;
|
import it.cavallium.strangedb.java.annotations.DbField;
|
||||||
import it.cavallium.strangedb.annotations.DbPrimitiveField;
|
import it.cavallium.strangedb.java.annotations.DbPrimitiveField;
|
||||||
import it.cavallium.strangedb.annotations.DbPrimitiveType;
|
import it.cavallium.strangedb.java.annotations.DbPrimitiveType;
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
import it.cavallium.strangedb.database.IDatabaseTools;
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||||
import it.cavallium.strangedb.annotations.DbClass;
|
import it.cavallium.strangedb.java.annotations.DbClass;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package it.cavallium.strangedb.utils;
|
package it.cavallium.strangedb.utils;
|
||||||
|
|
||||||
import it.cavallium.strangedb.annotations.DbPrimitiveField;
|
import it.cavallium.strangedb.java.annotations.DbPrimitiveField;
|
||||||
import it.cavallium.strangedb.annotations.DbPrimitiveType;
|
import it.cavallium.strangedb.java.annotations.DbPrimitiveType;
|
||||||
import it.cavallium.strangedb.database.Database;
|
import it.cavallium.strangedb.database.DatabaseCore;
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.database.DatabaseJava;
|
||||||
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ public class NSimplestClass extends EnhancedObject {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NSimplestClass(Database database) throws IOException {
|
public NSimplestClass(DatabaseJava database) throws IOException {
|
||||||
super(database);
|
super(database);
|
||||||
field1 = true;
|
field1 = true;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package it.cavallium.strangedb.utils;
|
package it.cavallium.strangedb.utils;
|
||||||
|
|
||||||
import it.cavallium.strangedb.annotations.*;
|
import it.cavallium.strangedb.database.DatabaseCore;
|
||||||
import it.cavallium.strangedb.functionalinterfaces.RunnableWithIO;
|
import it.cavallium.strangedb.functionalinterfaces.RunnableWithIO;
|
||||||
|
import it.cavallium.strangedb.java.annotations.*;
|
||||||
|
import it.cavallium.strangedb.java.database.DatabaseJava;
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
import it.cavallium.strangedb.database.Database;
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||||
import it.cavallium.strangedb.EnhancedObject;
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||||
import it.cavallium.strangedb.database.IDatabaseTools;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -23,7 +24,7 @@ public class NTestUtils {
|
|||||||
|
|
||||||
public static class WrappedDb {
|
public static class WrappedDb {
|
||||||
|
|
||||||
private Database db;
|
private DatabaseJava db;
|
||||||
private Path tempDir;
|
private Path tempDir;
|
||||||
private RunnableWithIO r;
|
private RunnableWithIO r;
|
||||||
|
|
||||||
@ -46,8 +47,8 @@ public class NTestUtils {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Database openDatabase() throws IOException {
|
private DatabaseJava openDatabase() throws IOException {
|
||||||
return new Database(tempDir.resolve(Paths.get("data.db")), tempDir.resolve(Paths.get("blocks.dat")), tempDir.resolve(Paths.get("references.dat")));
|
return new DatabaseJava(tempDir.resolve(Paths.get("data.db")), tempDir.resolve(Paths.get("blocks.dat")), tempDir.resolve(Paths.get("references.dat")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() throws IOException {
|
public void delete() throws IOException {
|
||||||
@ -55,7 +56,7 @@ public class NTestUtils {
|
|||||||
deleteDir(tempDir);
|
deleteDir(tempDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Database get() {
|
public DatabaseJava get() {
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user