From 468e58994c33be81f014c58419949eeab0d27661 Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Fri, 7 Dec 2018 00:26:38 +0100 Subject: [PATCH] Made value in EntryReference private --- .../java/org/warp/jcwdb/EntryReference.java | 25 +++++++++- .../java/org/warp/jcwdb/FileIndexManager.java | 46 +++++++++++++++++-- .../java/org/warp/jcwdb/exampleimpl/App.java | 2 +- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/warp/jcwdb/EntryReference.java b/src/main/java/org/warp/jcwdb/EntryReference.java index 70e932d..5ff818b 100644 --- a/src/main/java/org/warp/jcwdb/EntryReference.java +++ b/src/main/java/org/warp/jcwdb/EntryReference.java @@ -1,6 +1,7 @@ package org.warp.jcwdb; import java.io.IOException; +import java.util.function.Function; /** * You must have only a maximum of 1 reference for each index @@ -10,7 +11,7 @@ public class EntryReference implements Castable { private final JCWDatabase.EntryReferenceTools db; private final long entryIndex; private final DBTypeParser parser; - public T value; + private T value; private volatile boolean closed; private final Object closeLock = new Object(); @@ -50,6 +51,28 @@ public class EntryReference implements Castable { } } + public void editValue(Function editFunction) throws IOException { + this.value = editFunction.apply(this.value); + this.save(); + } + + /** + * Use editValue instead + * @return + */ + @Deprecated() + public T getValue() { + return this.value; + } + + /** + * DO NOT ATTEMPT TO MODIFY THE VALUE RETURNED + * @return + */ + public T getValueUnsafe() { + return this.value; + } + @Override public T cast() { return (T) this; diff --git a/src/main/java/org/warp/jcwdb/FileIndexManager.java b/src/main/java/org/warp/jcwdb/FileIndexManager.java index 4a5776e..4e98222 100644 --- a/src/main/java/org/warp/jcwdb/FileIndexManager.java +++ b/src/main/java/org/warp/jcwdb/FileIndexManager.java @@ -71,14 +71,20 @@ public class FileIndexManager implements IndexManager { @Override public void set(long index, DBDataOutput data) throws IOException { checkClosed(); + final int dataSize = data.getSize(); final IndexDetails indexDetails = getIndexMetadataUnsafe(index); - if (indexDetails == null || indexDetails.getSize() != data.getSize()) { // TODO: should be indexDetails.getSize() < data.getSize(). Need to create a method to mark memory free if the size is bigger than the needed, instead of allocating a new space. + if (indexDetails == null || indexDetails.getSize() < dataSize) { + // Allocate new space allocateAndWrite(index, data); } else { - if (indexDetails.getSize() > data.getSize()) { - editIndex(index, indexDetails.getOffset(), data.getSize(), indexDetails.getType(), data.calculateHash()); - fileAllocator.markFree(indexDetails.getOffset() + data.getSize(), data.getSize()); + // Check if size changed + if (indexDetails.getSize() > dataSize) { + // Mark free the unused bytes + fileAllocator.markFree(indexDetails.getOffset() + dataSize, dataSize); } + // Update index details + editIndex(index, indexDetails, indexDetails.getOffset(), dataSize, indexDetails.getType(), data.calculateHash()); + // Write data writeExact(indexDetails, data); } } @@ -178,12 +184,44 @@ public class FileIndexManager implements IndexManager { } } + /** + * Edit index data if a change is detected + * @param index + * @param oldData Old index data to check + * @param offset offset + * @param size size + * @param type type + * @param hash hash + * @return + */ + private IndexDetails editIndex(long index, IndexDetails oldData, long offset, int size, int type, long hash) { + if (oldData.getOffset() != offset || oldData.getSize() != size || oldData.getType() != type || oldData.getHash() != hash) { + editIndex(index, offset, size, type, hash); + } else { + return oldData; + } + } + + /** + * Edit index data + * @param index + * @param offset + * @param size + * @param type + * @param hash + * @return + */ private IndexDetails editIndex(long index, long offset, int size, int type, long hash) { IndexDetails indexDetails = new IndexDetails(offset, size, type, hash); editIndex(index, indexDetails); return indexDetails; } + /** + * Edit index data + * @param index + * @param details + */ private void editIndex(long index, IndexDetails details) { synchronized (indicesMapsAccessLock) { loadedIndices.put(index, details); diff --git a/src/main/java/org/warp/jcwdb/exampleimpl/App.java b/src/main/java/org/warp/jcwdb/exampleimpl/App.java index 42e10a2..c71eed4 100644 --- a/src/main/java/org/warp/jcwdb/exampleimpl/App.java +++ b/src/main/java/org/warp/jcwdb/exampleimpl/App.java @@ -26,7 +26,7 @@ public class App { System.out.println("Time elapsed: " + (time01 - time0)); System.out.println("Loading root..."); EntryReference> rootRef = db.getRoot(Animal.class); - LightList root = rootRef.value; + LightList root = rootRef.getValue(); long time1 = System.currentTimeMillis(); System.out.println("Time elapsed: " + (time1 - time01)); System.out.println("Root size: " + root.size());