190 lines
6.9 KiB
Java
190 lines
6.9 KiB
Java
package it.cavallium.strangedb.java.objects.lists;
|
|
|
|
import it.cavallium.strangedb.java.database.IObjectsIO;
|
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
|
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
|
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
|
import it.cavallium.strangedb.java.annotations.DbDataType;
|
|
import it.cavallium.strangedb.java.annotations.DbField;
|
|
|
|
import java.io.IOException;
|
|
|
|
public class EnhancedObjectStrangeDbList<T extends EnhancedObject> extends StrangeDbList<T> {
|
|
|
|
@DbField(id = 0, type = DbDataType.REFERENCES_LIST)
|
|
private LongArrayList indices;
|
|
|
|
@DbField(id = 1, type = DbDataType.OBJECT)
|
|
private Class<T> type;
|
|
|
|
@Override
|
|
protected LongArrayList getIndices() {
|
|
return indices;
|
|
}
|
|
|
|
public EnhancedObjectStrangeDbList() {
|
|
super();
|
|
}
|
|
|
|
public EnhancedObjectStrangeDbList(IDatabaseTools databaseTools, Class<T> type) throws IOException {
|
|
super(databaseTools);
|
|
this.type = type;
|
|
indices = new LongArrayList();
|
|
}
|
|
|
|
@Override
|
|
protected T loadItem(long uid) throws IOException {
|
|
return databaseTools.getObjectsIO().loadEnhancedObject(uid);
|
|
}
|
|
|
|
@Override
|
|
protected void writeItemToDisk(long uid, T item) throws IOException {
|
|
databaseTools.getObjectsIO().setEnhancedObject(uid, item);
|
|
}
|
|
|
|
public ElementsArrayList<EnhancedObjectIndices> queryUids(ListQuery query) throws IOException {
|
|
ElementsArrayList<EnhancedObjectIndices> uids = executeQuery(query, this, databaseTools.getObjectsIO());
|
|
return uids;
|
|
}
|
|
|
|
public ElementsArrayList<T> query(ListQuery query) throws IOException {
|
|
ElementsArrayList<EnhancedObjectIndices> uids = queryUids(query);
|
|
ElementsArrayList<T> elements = new ElementsArrayList<>(uids.size());
|
|
for (int i = 0; i < uids.size(); i++) {
|
|
T element = databaseTools.getObjectsIO().loadEnhancedObject(uids.get(i).objectUid);
|
|
elements.add(element);
|
|
}
|
|
return elements;
|
|
}
|
|
|
|
private ElementsArrayList<EnhancedObjectIndices> executeQuery(ListQuery query, ElementsList<?> inputList, IObjectsIO dbio) throws IOException {
|
|
if (query instanceof ListQuery.ListQueryElement) {
|
|
return executeQueryElement((ListQuery.ListQueryElement) query, inputList, dbio);
|
|
} else if (query instanceof ListQuery.ListQueryAnd) {
|
|
ListQuery[] children = ((ListQuery.ListQueryAnd) query).getQueryChildren();
|
|
ElementsArrayList<EnhancedObjectIndices> results = null;
|
|
for (ListQuery childQuery : children) {
|
|
results = executeQuery(childQuery, results == null ? inputList : results, dbio);
|
|
if (results.size() == 0) break;
|
|
}
|
|
return results;
|
|
} else if (query instanceof ListQuery.ListQueryOr) {
|
|
ListQuery[] children = ((ListQuery.ListQueryOr) query).getQueryChildren();
|
|
ElementsArrayList<EnhancedObjectIndices> results = new ElementsArrayList<>();
|
|
for (ListQuery childQuery : children) {
|
|
ElementsArrayList<EnhancedObjectIndices> childResults = executeQuery(childQuery, inputList, dbio);
|
|
int childResultsSize = childResults.size();
|
|
if (childResultsSize == inputList.size()) {
|
|
return childResults;
|
|
}
|
|
addMissingElements(results, childResults);
|
|
}
|
|
return results;
|
|
} else {
|
|
throw new RuntimeException("Not implemented!");
|
|
}
|
|
}
|
|
|
|
static void addMissingElements(ElementsArrayList<EnhancedObjectIndices> main, ElementsList<EnhancedObjectIndices> elementsToAdd) throws IOException {
|
|
int elementsSize = elementsToAdd.size();
|
|
for (int i = 0; i < elementsSize; i++) {
|
|
EnhancedObjectIndices childResultElement = elementsToAdd.get(i);
|
|
if (!main.contains(childResultElement)) {
|
|
main.add(childResultElement);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
static ElementsArrayList<Long> toElementsArrayList(ElementsList<?> elementsList) {
|
|
if (elementsList instanceof EnhancedObjectStrangeDbList<?>) {
|
|
return new ElementsArrayList<>(((EnhancedObjectStrangeDbList) elementsList).getIndices());
|
|
} else if (elementsList instanceof ElementsArrayList<?>) {
|
|
return (ElementsArrayList<Long>) elementsList;
|
|
} else {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
private static ElementsArrayList<EnhancedObjectIndices> executeQueryElement(ListQuery.ListQueryElement query, ElementsList<?> inputList, IObjectsIO dbio) throws IOException {
|
|
ElementsArrayList<EnhancedObjectIndices> results = new ElementsArrayList<>();
|
|
if (inputList instanceof EnhancedObjectStrangeDbList<?>) {
|
|
EnhancedObjectStrangeDbList<?> dbList = ((EnhancedObjectStrangeDbList<?>) inputList);
|
|
final int listSize = inputList.size();
|
|
final LongArrayList indices = dbList.getIndices();
|
|
for (int i = 0; i < listSize; i++) {
|
|
Long elementUid = indices.get(i);
|
|
EnhancedObjectIndices elementUids = dbio.loadEnhancedObjectUids(elementUid);
|
|
Object result = resolveItemFromDb(query.valuePointer, dbio, elementUids);
|
|
if (query.valueOperation.evaluate(result)) {
|
|
results.add(elementUids);
|
|
}
|
|
}
|
|
} else if (inputList instanceof ElementsArrayList<?>) {
|
|
final int listSize = inputList.size();
|
|
ElementsArrayList<EnhancedObjectIndices> elementsUids = ((ElementsArrayList<EnhancedObjectIndices>) inputList);
|
|
for (int i = 0; i < listSize; i++) {
|
|
EnhancedObjectIndices elementUid = elementsUids.get(i);
|
|
Object result = resolveItemFromDb(query.valuePointer, dbio, elementUid);
|
|
if (query.valueOperation.evaluate(result)) {
|
|
results.add(elementUid);
|
|
}
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
static Object resolveItemFromDb(ValuePointer pointer, IObjectsIO objectsIO, EnhancedObjectIndices element) throws IOException {
|
|
EnhancedObjectIndices currentElement = element;
|
|
boolean isLastElement;
|
|
for (int i = 0; i < pointer.size(); i++) {
|
|
isLastElement = i >= pointer.size() - 1;
|
|
ValuePointer currentPointer = pointer.at(i);
|
|
|
|
int pathNumber = currentPointer.getPathNumber();
|
|
ValueType valueType = currentPointer.getPathType();
|
|
|
|
Object value;
|
|
switch (valueType) {
|
|
case FIELD: {
|
|
if (isLastElement) {
|
|
//TODO: get field data type. it can be an enhancedObject or an object
|
|
value = objectsIO.loadObject(currentElement.fieldUids[pathNumber]);
|
|
} else {
|
|
value = objectsIO.loadEnhancedObjectUids(currentElement.fieldUids[pathNumber]);
|
|
}
|
|
break;
|
|
}
|
|
case PRIMITIVE_FIELD: {
|
|
if (isLastElement) {
|
|
//TODO: get primitive type
|
|
value = objectsIO.loadPrimitiveData(currentElement.nativeDataUid).getLong(pathNumber);
|
|
} else {
|
|
throw new IllegalArgumentException("You can access to a type field only in the last pointer");
|
|
}
|
|
break;
|
|
}
|
|
case PROPERTY: {
|
|
if (isLastElement) {
|
|
//TODO: get field data type. it can be an enhancedObject or an object
|
|
value = objectsIO.loadObject(currentElement.fieldUids[pathNumber]);
|
|
} else {
|
|
value = objectsIO.loadEnhancedObjectUids(currentElement.propertyUids[pathNumber]);
|
|
}
|
|
}
|
|
default: {
|
|
throw new IllegalArgumentException("Not implemented");
|
|
}
|
|
}
|
|
if (isLastElement) {
|
|
return value;
|
|
} else {
|
|
currentElement = (EnhancedObjectIndices) value;
|
|
}
|
|
}
|
|
throw new IOException("The pointer is empty");
|
|
}
|
|
|
|
}
|