Merge branch 'master' into origin/better
This commit is contained in:
commit
20dbb31ac4
@ -1,2 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="JAVA_MODULE" version="4" />
|
|
@ -1,5 +0,0 @@
|
|||||||
package org.warp.jcwdb;
|
|
||||||
|
|
||||||
public interface AdvancedSaveable extends Saveable {
|
|
||||||
public void save(boolean isEditFinished);
|
|
||||||
}
|
|
60
src/main/java/org/warp/jcwdb/Editable.java
Normal file
60
src/main/java/org/warp/jcwdb/Editable.java
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package org.warp.jcwdb;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public interface Editable<T> {
|
||||||
|
/**
|
||||||
|
* Reccomended way to edit the value
|
||||||
|
*
|
||||||
|
* @param editFunction
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
void editValue(BiFunction<T, Saveable, T> editFunction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reccomended way to edit the value
|
||||||
|
* @param editFunction
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
void editValue(Function<T, T> editFunction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reccomended way to edit the value
|
||||||
|
* @param editFunction
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
void editValue(BiConsumer<T, Saveable> editFunction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reccomended way to edit the value
|
||||||
|
* @param editFunction
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
void editValue(Consumer<T> editFunction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reccomended way to view the value
|
||||||
|
* @param viewFunction
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
void viewValue(Consumer<T> viewFunction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Substitute the old value with a new one
|
||||||
|
* @param val
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
void setValue(T val);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DO NOT ATTEMPT TO MODIFY THE VALUE RETURNED
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
T getValueReadOnlyUnsafe();
|
||||||
|
|
||||||
|
}
|
@ -10,7 +10,7 @@ import java.util.function.Function;
|
|||||||
* You must have only a maximum of 1 reference for each index
|
* You must have only a maximum of 1 reference for each index
|
||||||
* @param <T>
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
public class EntryReference<T> implements Castable, AdvancedSaveable {
|
public class EntryReference<T> implements Editable<T>, Saveable, Castable {
|
||||||
private final JCWDatabase.EntryReferenceTools db;
|
private final JCWDatabase.EntryReferenceTools db;
|
||||||
private final long entryIndex;
|
private final long entryIndex;
|
||||||
private final DBTypeParser<T> parser;
|
private final DBTypeParser<T> parser;
|
||||||
@ -63,6 +63,10 @@ public class EntryReference<T> implements Castable, AdvancedSaveable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isClosed() {
|
||||||
|
return closed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note that this method won't be called when closing without saving
|
* Note that this method won't be called when closing without saving
|
||||||
*/
|
*/
|
||||||
@ -70,21 +74,27 @@ public class EntryReference<T> implements Castable, AdvancedSaveable {
|
|||||||
this.save(false);
|
this.save(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(boolean isEditFinished) {
|
public void saveAndFlush() {
|
||||||
|
this.save(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void save(boolean flush) {
|
||||||
synchronized(accessLock) {
|
synchronized(accessLock) {
|
||||||
if (loaded && !closed) {
|
if (loaded && !closed) {
|
||||||
try {
|
try {
|
||||||
if (value instanceof AdvancedSaveable) {
|
if (value instanceof Saveable) {
|
||||||
((AdvancedSaveable)value).save(isEditFinished);
|
if (flush) {
|
||||||
} else if (value instanceof Saveable) {
|
((Saveable)value).saveAndFlush();
|
||||||
((Saveable)value).save();
|
} else {
|
||||||
|
((Saveable)value).save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IndexDetails returnedDetails = this.db.write(entryIndex, parser.getWriter(value));
|
IndexDetails returnedDetails = this.db.write(entryIndex, parser.getWriter(value));
|
||||||
synchronized(hashCacheLock) {
|
synchronized(hashCacheLock) {
|
||||||
this.cachedHash = returnedDetails.getHash();
|
this.cachedHash = returnedDetails.getHash();
|
||||||
this.isHashCached = true;
|
this.isHashCached = true;
|
||||||
}
|
}
|
||||||
if (isEditFinished) {
|
if (flush) {
|
||||||
if (!isFlushingAllowed) {
|
if (!isFlushingAllowed) {
|
||||||
this.db.setFlushingAllowed(entryIndex, true);
|
this.db.setFlushingAllowed(entryIndex, true);
|
||||||
this.isFlushingAllowed = true;
|
this.isFlushingAllowed = true;
|
||||||
@ -149,6 +159,19 @@ public class EntryReference<T> implements Castable, AdvancedSaveable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reccomended way to edit the value
|
||||||
|
* DO NOT EDIT THE VALUE
|
||||||
|
* @param viewFunction
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void viewValue(Consumer<T> viewFunction) {
|
||||||
|
synchronized(accessLock) {
|
||||||
|
load();
|
||||||
|
viewFunction.accept(this.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Substitute the old value with a new one
|
* Substitute the old value with a new one
|
||||||
* @param val
|
* @param val
|
||||||
@ -171,14 +194,14 @@ public class EntryReference<T> implements Castable, AdvancedSaveable {
|
|||||||
*/
|
*/
|
||||||
@Deprecated()
|
@Deprecated()
|
||||||
public T getValue() {
|
public T getValue() {
|
||||||
return getValueReadOnly();
|
return getValueReadOnlyUnsafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DO NOT ATTEMPT TO MODIFY THE VALUE RETURNED
|
* DO NOT ATTEMPT TO MODIFY THE VALUE RETURNED
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public T getValueReadOnly() {
|
public T getValueReadOnlyUnsafe() {
|
||||||
synchronized(accessLock) {
|
synchronized(accessLock) {
|
||||||
load();
|
load();
|
||||||
return this.value;
|
return this.value;
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package org.warp.jcwdb;
|
package org.warp.jcwdb;
|
||||||
|
|
||||||
|
import java.io.IOError;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class JCWDatabase implements AutoCloseable, Cleanable {
|
public class JCWDatabase implements AutoCloseable, Cleanable {
|
||||||
public final static long MAX_LOADED_INDICES = 1000;
|
public final static long MAX_LOADED_INDICES = 1000;
|
||||||
@ -13,6 +17,7 @@ public class JCWDatabase implements AutoCloseable, Cleanable {
|
|||||||
private volatile boolean closed;
|
private volatile boolean closed;
|
||||||
private final Object closeLock = new Object();
|
private final Object closeLock = new Object();
|
||||||
private final Object indicesAccessLock = new Object();
|
private final Object indicesAccessLock = new Object();
|
||||||
|
private final LinkedList<EntryReference<?>> usedReferences = new LinkedList<>();
|
||||||
|
|
||||||
public JCWDatabase(Path dataFile, Path metadataFile) throws IOException {
|
public JCWDatabase(Path dataFile, Path metadataFile) throws IOException {
|
||||||
this.typesManager = new TypesManager(this);
|
this.typesManager = new TypesManager(this);
|
||||||
@ -29,17 +34,31 @@ public class JCWDatabase implements AutoCloseable, Cleanable {
|
|||||||
this.databaseCleaner.start();
|
this.databaseCleaner.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> EntryReference<LightList<T>> getRoot() throws IOException {
|
public <T> EntryReference<LightList<T>> getRoot() {
|
||||||
checkClosed();
|
try {
|
||||||
if (exists(0)) {
|
checkClosed();
|
||||||
return get(0);
|
if (exists(0)) {
|
||||||
} else {
|
return get(0);
|
||||||
LightList<T> newRoot = new LightBigList<>(this);
|
} else {
|
||||||
return set(0, newRoot);
|
LightList<T> newRoot = new LightBigList<>(this);
|
||||||
|
return set(0, newRoot);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IOError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> EntryReference<LightList<T>> getRoot(Class<T> clazz) throws IOException {
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> EntryReference<T> getRootItem(int index) {
|
||||||
|
return ((LightList<T>) getRoot().getValueReadOnlyUnsafe()).getReference(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> EntryReference<T> getRootItem(int index, Supplier<T> defaultValue) {
|
||||||
|
return ((LightList<T>) getRoot().getValueReadOnlyUnsafe()).getReferenceOrInitialize(index, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> EntryReference<LightList<T>> getRoot(Class<T> clazz) {
|
||||||
return getRoot().cast();
|
return getRoot().cast();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +156,14 @@ public class JCWDatabase implements AutoCloseable, Cleanable {
|
|||||||
@Override
|
@Override
|
||||||
public long clean() {
|
public long clean() {
|
||||||
long removedItems = indices.clean();
|
long removedItems = indices.clean();
|
||||||
|
Iterator<EntryReference<?>> usedReferencesIterator = usedReferences.iterator();
|
||||||
|
while(usedReferencesIterator.hasNext()) {
|
||||||
|
EntryReference<?> entryReference = usedReferencesIterator.next();
|
||||||
|
if (entryReference.isClosed()) {
|
||||||
|
usedReferencesIterator.remove();
|
||||||
|
removedItems += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
return removedItems;
|
return removedItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +183,10 @@ public class JCWDatabase implements AutoCloseable, Cleanable {
|
|||||||
public void setFlushingAllowed(long index, boolean isFlushingAllowed) {
|
public void setFlushingAllowed(long index, boolean isFlushingAllowed) {
|
||||||
indices.setFlushingAllowed(index, isFlushingAllowed);
|
indices.setFlushingAllowed(index, isFlushingAllowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> void setUsed(EntryReference<T> ref) {
|
||||||
|
usedReferences.add(ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -48,7 +48,7 @@ public class LightArrayList<T> implements LightList<T> {
|
|||||||
EntryReference<T> ref = null;
|
EntryReference<T> ref = null;
|
||||||
try {
|
try {
|
||||||
ref = db.get(element);
|
ref = db.get(element);
|
||||||
if (o.equals(ref.getValueReadOnly())) {
|
if (o.equals(ref.getValueReadOnlyUnsafe())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -70,7 +70,7 @@ public class LightArrayList<T> implements LightList<T> {
|
|||||||
final ArrayList<T> elements = new ArrayList<>();
|
final ArrayList<T> elements = new ArrayList<>();
|
||||||
for (long element : internalList) {
|
for (long element : internalList) {
|
||||||
try {
|
try {
|
||||||
elements.add((T) db.get(element).getValueReadOnly());
|
elements.add((T) db.get(element).getValueReadOnlyUnsafe());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ public class LightArrayList<T> implements LightList<T> {
|
|||||||
final T[] elements = (T[]) new Object[internalList.size()];
|
final T[] elements = (T[]) new Object[internalList.size()];
|
||||||
for (int i = 0; i < elements.length; i++) {
|
for (int i = 0; i < elements.length; i++) {
|
||||||
try {
|
try {
|
||||||
T element = (T) db.get(internalList.getLong(i)).getValueReadOnly();
|
T element = (T) db.get(internalList.getLong(i)).getValueReadOnlyUnsafe();
|
||||||
elements[i] = element;
|
elements[i] = element;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -140,7 +140,7 @@ public class LightArrayList<T> implements LightList<T> {
|
|||||||
final T1[] elements = (T1[]) new Objects[internalList.size()];
|
final T1[] elements = (T1[]) new Objects[internalList.size()];
|
||||||
for (int i = 0; i < elements.length; i++) {
|
for (int i = 0; i < elements.length; i++) {
|
||||||
try {
|
try {
|
||||||
elements[i] = (T1) db.get(internalList.getLong(i)).getValueReadOnly();
|
elements[i] = (T1) db.get(internalList.getLong(i)).getValueReadOnlyUnsafe();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -265,7 +265,7 @@ public class LightArrayList<T> implements LightList<T> {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public T getReadOnlyValue(int index) {
|
public T getReadOnlyValue(int index) {
|
||||||
try {
|
try {
|
||||||
return (T) db.get(internalList.getLong(index)).getValueReadOnly();
|
return (T) db.get(internalList.getLong(index)).getValueReadOnlyUnsafe();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
@ -289,7 +289,7 @@ public class LightArrayList<T> implements LightList<T> {
|
|||||||
long oldIndex = internalList.set(index, ref.getIndex());
|
long oldIndex = internalList.set(index, ref.getIndex());
|
||||||
try {
|
try {
|
||||||
ref.close();
|
ref.close();
|
||||||
return ((EntryReference<T>) (db.get(oldIndex))).getValueReadOnly();
|
return ((EntryReference<T>) (db.get(oldIndex))).getValueReadOnlyUnsafe();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw (NullPointerException) new NullPointerException().initCause(e);
|
throw (NullPointerException) new NullPointerException().initCause(e);
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ public class LightArrayList<T> implements LightList<T> {
|
|||||||
public T remove(int index) {
|
public T remove(int index) {
|
||||||
long oldIndex = internalList.removeLong(index);
|
long oldIndex = internalList.removeLong(index);
|
||||||
try {
|
try {
|
||||||
return ((EntryReference<T>) (db.get(oldIndex))).getValueReadOnly();
|
return ((EntryReference<T>) (db.get(oldIndex))).getValueReadOnlyUnsafe();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw (NullPointerException) new NullPointerException().initCause(e);
|
throw (NullPointerException) new NullPointerException().initCause(e);
|
||||||
}
|
}
|
||||||
@ -340,7 +340,7 @@ public class LightArrayList<T> implements LightList<T> {
|
|||||||
long index = internalList.getLong(i);
|
long index = internalList.getLong(i);
|
||||||
try {
|
try {
|
||||||
EntryReference<?> ref2 = db.get(index);
|
EntryReference<?> ref2 = db.get(index);
|
||||||
if (ref.getValueReadOnly().equals(ref2.getValueReadOnly())) {
|
if (ref.getValueReadOnlyUnsafe().equals(ref2.getValueReadOnlyUnsafe())) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -372,7 +372,7 @@ public class LightArrayList<T> implements LightList<T> {
|
|||||||
try {
|
try {
|
||||||
EntryReference<?> ref2 = db.get(index2);
|
EntryReference<?> ref2 = db.get(index2);
|
||||||
if (objToRemoveHash == ref2.calculateHash()) {
|
if (objToRemoveHash == ref2.calculateHash()) {
|
||||||
if (ref.getValueReadOnly().equals(ref2.getValueReadOnly())) {
|
if (ref.getValueReadOnlyUnsafe().equals(ref2.getValueReadOnlyUnsafe())) {
|
||||||
lastValue = i;
|
lastValue = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,7 +431,7 @@ public class LightArrayList<T> implements LightList<T> {
|
|||||||
for (int i = 0; i < internalList.size(); ) {
|
for (int i = 0; i < internalList.size(); ) {
|
||||||
T obj;
|
T obj;
|
||||||
try {
|
try {
|
||||||
obj = ((EntryReference<T>) (db.get(internalList.getLong(i)).cast())).getValueReadOnly();
|
obj = ((EntryReference<T>) (db.get(internalList.getLong(i)).cast())).getValueReadOnlyUnsafe();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw (NullPointerException) new NullPointerException().initCause(e);
|
throw (NullPointerException) new NullPointerException().initCause(e);
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@ import it.unimi.dsi.fastutil.ints.IntArrayList;
|
|||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
|
||||||
import java.io.IOError;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class LightBigList<T> implements LightList<T>, Saveable {
|
public class LightBigList<T> implements LightList<T>, Saveable {
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ public class LightBigList<T> implements LightList<T>, Saveable {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw (NullPointerException) new NullPointerException().initCause(ex);
|
throw (NullPointerException) new NullPointerException().initCause(ex);
|
||||||
}
|
}
|
||||||
this.cachedChunk = this.cachedChunkRef.getValueReadOnly();
|
this.cachedChunk = this.cachedChunkRef.getValueReadOnlyUnsafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -134,7 +134,7 @@ public class LightBigList<T> implements LightList<T>, Saveable {
|
|||||||
for (long chunkIndex : chunks) {
|
for (long chunkIndex : chunks) {
|
||||||
try {
|
try {
|
||||||
EntryReference<LightArrayList<T>> chunkRef = db.get(chunkIndex);
|
EntryReference<LightArrayList<T>> chunkRef = db.get(chunkIndex);
|
||||||
LightArrayList<T> chunk = chunkRef.getValueReadOnly();
|
LightArrayList<T> chunk = chunkRef.getValueReadOnlyUnsafe();
|
||||||
if (chunk.contains(o)) {
|
if (chunk.contains(o)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -211,7 +211,7 @@ public class LightBigList<T> implements LightList<T>, Saveable {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
EntryReference<LightArrayList<T>> chunkRef = db.get(chunkIndex);
|
EntryReference<LightArrayList<T>> chunkRef = db.get(chunkIndex);
|
||||||
LightArrayList<T> chunk = chunkRef.getValueReadOnly();
|
LightArrayList<T> chunk = chunkRef.getValueReadOnlyUnsafe();
|
||||||
for (int i1 = 0; i1 < chunk.size(); i1++) {
|
for (int i1 = 0; i1 < chunk.size(); i1++) {
|
||||||
result[(int)(chunkStartOffset + i1)] = chunk.get(i);
|
result[(int)(chunkStartOffset + i1)] = chunk.get(i);
|
||||||
}
|
}
|
||||||
@ -378,7 +378,7 @@ public class LightBigList<T> implements LightList<T>, Saveable {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public T getReadOnlyValue(int index) {
|
public T getReadOnlyValue(int index) {
|
||||||
try {
|
try {
|
||||||
return (T) db.get(chunks.getLong(index)).getValueReadOnly();
|
return (T) db.get(chunks.getLong(index)).getValueReadOnlyUnsafe();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
@ -387,10 +387,26 @@ public class LightBigList<T> implements LightList<T>, Saveable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntryReference<T> getReference(int index) {
|
public EntryReference<T> getReference(int index) {
|
||||||
|
return getReferenceUnsafe(index, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntryReference<T> getReferenceOrInitialize(int index, Supplier<T> initializer) {
|
||||||
|
EntryReference<T> value = getReferenceUnsafe(index, false);
|
||||||
|
if (value != null) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
T initializedData = initializer.get();
|
||||||
|
EntryReference<T> initializedDataRef = addToDatabase(initializedData);
|
||||||
|
return set(index, initializedDataRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntryReference<T> getReferenceUnsafe(int index, boolean throwError) {
|
||||||
try {
|
try {
|
||||||
return db.get(chunks.getLong(index)).cast();
|
return db.get(chunks.getLong(index)).cast();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
if (throwError) e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,8 +414,14 @@ public class LightBigList<T> implements LightList<T>, Saveable {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public T set(int setOffset, final T element) {
|
public T set(int setOffset, final T element) {
|
||||||
|
return set(setOffset, addToDatabase(element)).getValueReadOnlyUnsafe();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public EntryReference<T> set(int setOffset, final EntryReference<T> element) {
|
||||||
long nextChunkOffset = 0;
|
long nextChunkOffset = 0;
|
||||||
VariableWrapper<T> wrapper = new VariableWrapper<>(null);
|
VariableWrapper<EntryReference<T>> wrapper = new VariableWrapper<>(null);
|
||||||
if (setOffset >= 0) {
|
if (setOffset >= 0) {
|
||||||
// Iterate through all chunks
|
// Iterate through all chunks
|
||||||
for (int i = 0; i < chunks.size(); i++) {
|
for (int i = 0; i < chunks.size(); i++) {
|
||||||
@ -420,8 +442,7 @@ public class LightBigList<T> implements LightList<T>, Saveable {
|
|||||||
try {
|
try {
|
||||||
EntryReference<LightArrayList<T>> chunkRef = db.get(chunkIndex);
|
EntryReference<LightArrayList<T>> chunkRef = db.get(chunkIndex);
|
||||||
chunkRef.editValue((chunk) -> {
|
chunkRef.editValue((chunk) -> {
|
||||||
chunk.set(relativeOffset, element);
|
wrapper.var = chunk.set(relativeOffset, element);
|
||||||
wrapper.var = element;
|
|
||||||
});
|
});
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw (NullPointerException) new NullPointerException().initCause(ex);
|
throw (NullPointerException) new NullPointerException().initCause(ex);
|
||||||
@ -463,7 +484,7 @@ public class LightBigList<T> implements LightList<T>, Saveable {
|
|||||||
// Get chunk index
|
// Get chunk index
|
||||||
final long chunkIndex = chunks.getLong(i);
|
final long chunkIndex = chunks.getLong(i);
|
||||||
EntryReference<LightArrayList<T>> chunkRef = db.get(chunkIndex);
|
EntryReference<LightArrayList<T>> chunkRef = db.get(chunkIndex);
|
||||||
final int foundIndex = chunkRef.getValueReadOnly().indexOfEntry(ref);
|
final int foundIndex = chunkRef.getValueReadOnlyUnsafe().indexOfEntry(ref);
|
||||||
if (foundIndex >= 0) {
|
if (foundIndex >= 0) {
|
||||||
return currentOffset + foundIndex;
|
return currentOffset + foundIndex;
|
||||||
}
|
}
|
||||||
@ -492,7 +513,7 @@ public class LightBigList<T> implements LightList<T>, Saveable {
|
|||||||
// Get chunk index
|
// Get chunk index
|
||||||
final long chunkIndex = chunks.getLong(i);
|
final long chunkIndex = chunks.getLong(i);
|
||||||
EntryReference<LightArrayList<T>> chunkRef = db.get(chunkIndex);
|
EntryReference<LightArrayList<T>> chunkRef = db.get(chunkIndex);
|
||||||
final int foundIndex = chunkRef.getValueReadOnly().lastIndexOfEntry(ref);
|
final int foundIndex = chunkRef.getValueReadOnlyUnsafe().lastIndexOfEntry(ref);
|
||||||
if (foundIndex >= 0) {
|
if (foundIndex >= 0) {
|
||||||
return currentOffset + foundIndex;
|
return currentOffset + foundIndex;
|
||||||
}
|
}
|
||||||
@ -578,4 +599,9 @@ public class LightBigList<T> implements LightList<T>, Saveable {
|
|||||||
this.cachedChunkRef.save();
|
this.cachedChunkRef.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveAndFlush() {
|
||||||
|
save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package org.warp.jcwdb;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public interface LightList<T> extends List<T> {
|
public interface LightList<T> extends List<T> {
|
||||||
|
|
||||||
@ -12,10 +13,14 @@ public interface LightList<T> extends List<T> {
|
|||||||
|
|
||||||
EntryReference<T> addEntry(T o);
|
EntryReference<T> addEntry(T o);
|
||||||
|
|
||||||
|
EntryReference<T> set(int setOffset, final EntryReference<T> element);
|
||||||
|
|
||||||
boolean remove(EntryReference<T> ref);
|
boolean remove(EntryReference<T> ref);
|
||||||
|
|
||||||
EntryReference<T> getReference(int index);
|
EntryReference<T> getReference(int index);
|
||||||
|
|
||||||
|
EntryReference<T> getReferenceOrInitialize(int index, Supplier<T> initializer);
|
||||||
|
|
||||||
int indexOfEntry(EntryReference<T> ref);
|
int indexOfEntry(EntryReference<T> ref);
|
||||||
|
|
||||||
int lastIndexOfEntry(EntryReference<T> ref);
|
int lastIndexOfEntry(EntryReference<T> ref);
|
||||||
|
@ -3,5 +3,6 @@ package org.warp.jcwdb;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public interface Saveable {
|
public interface Saveable {
|
||||||
public void save();
|
void save();
|
||||||
|
void saveAndFlush();
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ public class App {
|
|||||||
|
|
||||||
System.out.println("Retrieving items...");
|
System.out.println("Retrieving items...");
|
||||||
root.forEachReference((valueReference) -> {
|
root.forEachReference((valueReference) -> {
|
||||||
Animal value = valueReference.getValueReadOnly();
|
Animal value = valueReference.getValueReadOnlyUnsafe();
|
||||||
if (Animal.hasFourLegs(value)) {
|
if (Animal.hasFourLegs(value)) {
|
||||||
results.add(value);
|
results.add(value);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user