From: Antti Villberg Date: Mon, 6 Jul 2020 16:33:19 +0000 (+0300) Subject: DB query swapping to file system X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=e460fd6f0af60314e2ca28391ef7ff2043016d97;p=simantics%2Fplatform.git DB query swapping to file system gitlab #572 Change-Id: I3609ab9207fd01710aeb7c00debae259d1dc08c3 (cherry picked from commit 51cf547b475df8309ca0207c35f97fda0d26abd0) --- diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ArraySet.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ArraySet.java deleted file mode 100644 index 1360cef74..000000000 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ArraySet.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management - * in Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.db.impl.graph; - -import java.util.Collection; -import java.util.Iterator; -import java.util.Set; - -import org.simantics.db.Resource; -import org.simantics.db.impl.query.IntSet; -import org.simantics.db.impl.query.QuerySupport; - -public class ArraySet implements Set { - - final Resource[] set; - - ArraySet(IntSet intSet, QuerySupport support) { - - if(intSet.data == null) { - if(intSet.sizeOrData != IntSet.NO_DATA) { - set = new Resource[] { support.getResource(intSet.sizeOrData) }; - } else { - set = Resource.NONE; - } - } else { - set = new Resource[intSet.sizeOrData]; - for(int i=0;i c) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean contains(Object o) { - for(int i=0;i c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isEmpty() { - return set.length == 0; - } - - @Override - public Iterator iterator() { - - class ArraySetIterator implements Iterator { - - int next = 0; - - @Override - public boolean hasNext() { - return next < set.length; - } - - @Override - public Resource next() { - return set[next++]; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - } - - return new ArraySetIterator(); - - } - - @Override - public boolean remove(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean retainAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public int size() { - return set.length; - } - - @Override - public Object[] toArray() { - throw new UnsupportedOperationException(); - } - - @Override - public T[] toArray(T[] a) { - throw new UnsupportedOperationException(); - } - -} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java index b4104e965..23fbe95ec 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java @@ -241,5 +241,11 @@ final public class AssertedPredicates extends UnaryQuery { }); } - + + @Override + public void serializeValue(QuerySerializer serializer) { + IntArray is = getResult(); + is.serialize(serializer); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicatesFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicatesFactory.java new file mode 100644 index 000000000..c76bc51ee --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicatesFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class AssertedPredicatesFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + AssertedPredicates result = reference(deserializer); + IntArray ia = IntArray.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readAssertedPredicates(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatementsFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatementsFactory.java new file mode 100644 index 000000000..708ce6686 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatementsFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class AssertedStatementsFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + AssertedStatements result = reference(deserializer); + IntArray ia = IntArray.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readAssertedStatements(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncMultiReadEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncMultiReadEntry.java index ea88d1791..788044807 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncMultiReadEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncMultiReadEntry.java @@ -190,4 +190,9 @@ final public class AsyncMultiReadEntry extends CacheEntryBase extends CacheEntryBase> i } } + @Override + public String classId() { + return null; + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQuery.java index d699ea825..04df0d00c 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQuery.java @@ -66,4 +66,15 @@ public abstract class BinaryQuery extends CacheEntryBase i abstract public void removeEntry(QueryProcessor provider); + @Override + public long cluster(QueryProcessor processor) { + return processor.cluster(r1()); + } + + @Override + public void serializeKey(QuerySerializer serializer) { + serializer.addResource(r1()); + serializer.addResource(r2()); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntry.java index 1cdcbde9d..edb087025 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntry.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.simantics.db.impl.query; +import java.util.Collection; + import org.simantics.db.exception.DatabaseException; import org.simantics.db.impl.graph.ReadGraphImpl; @@ -43,7 +45,7 @@ public abstract class CacheEntry { abstract void removeParent(CacheEntry entry); abstract void addParent(CacheEntry entry); abstract boolean hasParents(); - abstract Iterable> getParents(QueryProcessor processor); + abstract Collection> getParents(QueryProcessor processor); abstract CacheEntry getFirstParent(QueryProcessor processor); abstract boolean moreThanOneParent(QueryProcessor processor); abstract int parentCount(QueryProcessor processor); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntryBase.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntryBase.java index e79f99dea..56da11ace 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntryBase.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntryBase.java @@ -12,6 +12,7 @@ package org.simantics.db.impl.query; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import org.simantics.databoard.Bindings; @@ -339,7 +340,7 @@ public abstract class CacheEntryBase extends CacheEntry { } @Override - final public Iterable> getParents(QueryProcessor processor) { + final public Collection> getParents(QueryProcessor processor) { ArrayList> result = new ArrayList>(); if(p1 != null) result.add(p1); @@ -471,5 +472,44 @@ public abstract class CacheEntryBase extends CacheEntry { public CacheEntryBase() { } + + public String classId() { + return getClass().getName(); + } + + public void serializeKey(QuerySerializer serializer) { + throw new IllegalStateException("Cannot serialize query key for " + this); + } + + public void serializeValue(QuerySerializer serializer) { + throw new IllegalStateException("Cannot serialize query value for " + this); + } + + public void serializeParents(QuerySerializer serializer) { + Collection> ps = getParents(serializer.getQueryProcessor()); + int sizePos = serializer.writeUnknownSize(); + int actual = 0; + for(CacheEntry entry : ps) { + CacheEntryBase b = (CacheEntryBase)entry; + String cid = b.classId(); + if(cid == null) + continue; + serializer.serializeId(b.classId()); + b.serializeKey(serializer); + actual++; + } + serializer.setUnknownSize(sizePos, actual); + } + + public long cluster(QueryProcessor processor) { + throw new IllegalStateException("Cannot compute query cluster for " + this); + } + + public void serialize(QuerySerializer serializer) { + serializer.serializeId(classId()); + serializeKey(serializer); + serializeValue(serializer); + serializeParents(serializer); + } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java index 8effbb1d5..79d3106a8 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java @@ -142,6 +142,16 @@ public final class ChildMap extends UnaryQueryP> { } + @Override + public void serializeValue(QuerySerializer serializer) { + ObjectResourceIdMap is = getResult(); + serializer.writeLE(is.size()); + for(String s : is.keySet()) { + serializer.addString(s); + serializer.addResource(is.getId(s)); + } + } + @Override public String toString() { return "ChildMap[" + id + "]"; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMapFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMapFactory.java new file mode 100644 index 000000000..bf179b523 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMapFactory.java @@ -0,0 +1,28 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.ObjectResourceIdMap; +import org.simantics.db.exception.DatabaseException; + +public class ChildMapFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + ChildMap result = reference(deserializer); + ObjectResourceIdMap map = deserializer.createChildMap(); + int size = deserializer.readLE4(); + for(int i=0;i T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readChildMap(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionBinaryQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionBinaryQuery.java index cd139655c..6e1692ba4 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionBinaryQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionBinaryQuery.java @@ -11,9 +11,6 @@ *******************************************************************************/ package org.simantics.db.impl.query; - - - abstract public class CollectionBinaryQuery extends BinaryQuery { public CollectionBinaryQuery(final int r1, final int r2) { @@ -33,5 +30,11 @@ abstract public class CollectionBinaryQuery extends BinaryQuery { if(size == 0) setResult(IntArray.EMPTY); else v.trim(); } - + + @Override + public void serializeValue(QuerySerializer serializer) { + IntArray is = getResult(); + is.serialize(serializer); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionUnaryQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionUnaryQuery.java index 90bb03554..2eaeca472 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionUnaryQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionUnaryQuery.java @@ -96,4 +96,10 @@ public abstract class CollectionUnaryQuery extends UnaryQuery impl except(throwable); } + @Override + public void serializeValue(QuerySerializer serializer) { + IntArray is = getResult(); + is.serialize(serializer); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjectsFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjectsFactory.java new file mode 100644 index 000000000..323ec2134 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjectsFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class DirectObjectsFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + DirectObjects result = reference(deserializer); + IntArray ia = IntArray.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readDirectObjects(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java index 1a006369a..ee0faa1cf 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java @@ -16,7 +16,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.impl.graph.ReadGraphImpl; import org.simantics.db.impl.procedure.InternalProcedure; -public final class DirectPredicates extends UnaryQueryP { +public final class DirectPredicates extends UnaryQueryPIntSet { DirectPredicates(final int resource) { super(resource); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicatesFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicatesFactory.java new file mode 100644 index 000000000..e707e62e7 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicatesFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class DirectPredicatesFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + DirectPredicates result = reference(deserializer); + IntSet is = IntSet.deserialize(deserializer); + result.setResult(is); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readDirectPredicates(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java index d04404339..6253744bb 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java @@ -231,5 +231,10 @@ final public class ExternalReadEntry extends CacheEntryBase public boolean isDisposed() { return registered && (isDiscarded() || !graph.processor.isBound(this)); } - + + @Override + public String classId() { + return null; + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntArray.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntArray.java index 6ee30ad70..53b447f08 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntArray.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntArray.java @@ -13,6 +13,8 @@ package org.simantics.db.impl.query; import java.util.Arrays; +import org.simantics.db.exception.DatabaseException; + final public class IntArray { @@ -111,7 +113,27 @@ final public class IntArray { } return result; } - + + public void serialize(QuerySerializer serializer) { + int size = size(); + serializer.writeLE(size); + if(size == 1) { + serializer.addResource(sizeOrData); + } else { + for(int i=0;i implement except(throwable); } + @Override + public void serializeValue(QuerySerializer serializer) { + IntArray is = getResult(); + is.serialize(serializer); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ObjectsFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ObjectsFactory.java new file mode 100644 index 000000000..f6758e618 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ObjectsFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class ObjectsFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + Objects result = reference(deserializer); + IntArray ia = IntArray.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readObjects(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSetFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSetFactory.java new file mode 100644 index 000000000..9b5f581ba --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSetFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class OrderedSetFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + OrderedSet result = reference(deserializer); + IntArray ia = IntArray.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readOrderedSet(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java index 9445db03b..982d8019c 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java @@ -19,7 +19,7 @@ import org.simantics.db.request.RequestFlags; import gnu.trove.procedure.TIntProcedure; -final public class Predicates extends UnaryQueryP { +final public class Predicates extends UnaryQueryPIntSet { Predicates(final int r) { super(r); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PredicatesFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PredicatesFactory.java new file mode 100644 index 000000000..c86e43ce6 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PredicatesFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class PredicatesFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + Predicates result = reference(deserializer); + IntSet ia = IntSet.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readPredicates(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypesFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypesFactory.java new file mode 100644 index 000000000..ccd4ddc47 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypesFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class PrincipalTypesFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + PrincipalTypes result = reference(deserializer); + IntArray ia = IntArray.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readPrincipalTypes(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java index f80fb5098..b0bca1350 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java @@ -4,13 +4,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.Semaphore; -import org.simantics.databoard.Bindings; import org.simantics.db.AsyncReadGraph; -import org.simantics.db.DevelopmentKeys; import org.simantics.db.ObjectResourceIdMap; import org.simantics.db.ReadGraph; import org.simantics.db.RelationInfo; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.impl.graph.ReadGraphImpl; import org.simantics.db.impl.procedure.InternalProcedure; @@ -24,7 +21,6 @@ import org.simantics.db.request.AsyncRead; import org.simantics.db.request.ExternalRead; import org.simantics.db.request.MultiRead; import org.simantics.db.request.Read; -import org.simantics.utils.Development; import gnu.trove.map.hash.THashMap; import gnu.trove.map.hash.TObjectIntHashMap; @@ -980,5 +976,158 @@ public class QueryCacheBase { static boolean shouldCache(QueryProcessor processor, Object o) { return false; } + + AssertedPredicates getOrCreateAssertedPredicates(int r) { + AssertedPredicates entry = (AssertedPredicates)assertedPredicatesMap.get(r); + if(entry == null) { + entry = new AssertedPredicates(r); + assertedPredicatesMap.put(keyR(r), entry); + } + return entry; + } + AssertedStatements getOrCreateAssertedStatements(int r1, int r2) { + AssertedStatements entry = (AssertedStatements)assertedStatementsMap.get(r1, r2); + if(entry == null) { + entry = new AssertedStatements(r1, r2); + assertedStatementsMap.put(keyR2(r1, r2), entry); + } + return entry; + } + + ChildMap getOrCreateChildMap(int r) { + ChildMap entry = (ChildMap)childMapMap.get(r); + if(entry == null) { + entry = new ChildMap(r); + childMapMap.put(keyR(r), entry); + } + return entry; + } + + DirectObjects getOrCreateDirectObjects(int r1, int r2) { + DirectObjects entry = (DirectObjects)directObjectsMap.get(r1, r2); + if(entry == null) { + entry = new DirectObjects(r1, r2); + directObjectsMap.put(keyR2(r1, r2), entry); + } + return entry; + } + + DirectPredicates getOrCreateDirectPredicates(int r) { + DirectPredicates entry = (DirectPredicates)directPredicatesMap.get(r); + if(entry == null) { + entry = new DirectPredicates(r); + directPredicatesMap.put(keyR(r), entry); + } + return entry; + } + + Objects getOrCreateObjects(int r1, int r2) { + Objects entry = (Objects)objectsMap.get(r1, r2); + if(entry == null) { + entry = new Objects(r1, r2); + objectsMap.put(keyR2(r1, r2), entry); + } + return entry; + } + + OrderedSet getOrCreateOrderedSet(int r) { + OrderedSet entry = (OrderedSet)orderedSetMap.get(r); + if(entry == null) { + entry = new OrderedSet(r); + orderedSetMap.put(keyR(r), entry); + } + return entry; + } + + Predicates getOrCreatePredicates(int r) { + Predicates entry = (Predicates)predicatesMap.get(r); + if(entry == null) { + entry = new Predicates(r); + predicatesMap.put(keyR(r), entry); + } + return entry; + } + + PrincipalTypes getOrCreatePrincipalTypes(int r) { + PrincipalTypes entry = (PrincipalTypes)principalTypesMap.get(r); + if(entry == null) { + entry = new PrincipalTypes(r); + principalTypesMap.put(keyR(r), entry); + } + return entry; + } + + RelationInfoQuery getOrCreateRelationInfoQuery(int r) { + RelationInfoQuery entry = (RelationInfoQuery)relationInfoQueryMap.get(r); + if(entry == null) { + entry = new RelationInfoQuery(r); + relationInfoQueryMap.put(keyR(r), entry); + } + return entry; + } + + Statements getOrCreateStatements(int r1, int r2) { + Statements entry = (Statements)statementsMap.get(r1, r2); + if(entry == null) { + entry = new Statements(r1, r2); + statementsMap.put(keyR2(r1, r2), entry); + } + return entry; + } + + SuperRelations getOrCreateSuperRelations(int r) { + SuperRelations entry = (SuperRelations)superRelationsMap.get(r); + if(entry == null) { + entry = new SuperRelations(r); + superRelationsMap.put(keyR(r), entry); + } + return entry; + } + + SuperTypes getOrCreateSuperTypes(int r) { + SuperTypes entry = (SuperTypes)superTypesMap.get(r); + if(entry == null) { + entry = new SuperTypes(r); + superTypesMap.put(keyR(r), entry); + } + return entry; + } + + TypeHierarchy getOrCreateTypeHierarchy(int r) { + TypeHierarchy entry = (TypeHierarchy)typeHierarchyMap.get(r); + if(entry == null) { + entry = new TypeHierarchy(r); + typeHierarchyMap.put(keyR(r), entry); + } + return entry; + } + + Types getOrCreateTypes(int r) { + Types entry = (Types)typesMap.get(r); + if(entry == null) { + entry = new Types(r); + typesMap.put(keyR(r), entry); + } + return entry; + } + + URIToResource getOrCreateURIToResource(String s) { + URIToResource entry = (URIToResource)uRIToResourceMap.get(s); + if(entry == null) { + entry = new URIToResource(s); + uRIToResourceMap.put(keyID(s), entry); + } + return entry; + } + + ValueQuery getOrCreateValueQuery(int r) { + ValueQuery entry = (ValueQuery)valueQueryMap.get(r); + if(entry == null) { + entry = new ValueQuery(r); + valueQueryMap.put(keyR(r), entry); + } + return entry; + } + } \ No newline at end of file diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryDeserializer.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryDeserializer.java new file mode 100644 index 000000000..0fe9b9c1e --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryDeserializer.java @@ -0,0 +1,227 @@ +package org.simantics.db.impl.query; + +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.simantics.db.ObjectResourceIdMap; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.impl.ClusterBase; +import org.simantics.db.impl.ClusterSupport; +import org.simantics.db.impl.ClusterTraitsBase; +import org.simantics.db.service.Bytes; +import org.slf4j.LoggerFactory; + +import gnu.trove.map.hash.TIntLongHashMap; + +public class QueryDeserializer { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(QueryDeserializer.class); + + QueryCache qc; + QuerySupport qs; + ClusterSupport cs; + + private byte[] bytes; + private int byteIndex; + + private TIntLongHashMap clusterKeys = new TIntLongHashMap(); + private Map ids = new HashMap(); + + public QueryDeserializer(QueryProcessor qp, byte[] bytes) { + this.qc = qp.cache; + this.qs = qp.querySupport; + this.cs = qs.getClusterSupport();; + this.bytes = bytes; + } + + public byte readByte() { + return bytes[byteIndex++]; + } + + public int readLE4() { + int result = Bytes.readLE4(bytes, byteIndex); + byteIndex += 4; + return result; + } + + public long readLE8() { + long result = Bytes.readLE8(bytes, byteIndex); + byteIndex += 8; + return result; + } + + public byte[] readBytes(int len) { + byte[] result = Arrays.copyOfRange(bytes, byteIndex, byteIndex+len); + byteIndex += len; + return result; + } + + public void readHeaders() { + int idsSize = readLE4(); + for(int i=0;i clazz = (Class)getClass().getClassLoader().loadClass(id + "Factory"); + QueryFactory qf = clazz.getDeclaredConstructor().newInstance(); + ids.put(key, qf); + } catch (ClassNotFoundException e) { + LOGGER.error("Error while resolving QueryFactory", e); + } catch (InstantiationException e) { + LOGGER.error("Error while resolving QueryFactory", e); + } catch (IllegalAccessException e) { + LOGGER.error("Error while resolving QueryFactory", e); + } catch (IllegalArgumentException e) { + LOGGER.error("Error while resolving QueryFactory", e); + } catch (InvocationTargetException e) { + LOGGER.error("Error while resolving QueryFactory", e); + } catch (NoSuchMethodException e) { + LOGGER.error("Error while resolving QueryFactory", e); + } catch (SecurityException e) { + LOGGER.error("Error while resolving QueryFactory", e); + } + } + int clusterKeysSize = readLE4(); + for(int i=0;i createChildMap() { + return qs.createChildMap(); + } + + AssertedPredicates readAssertedPredicates() throws DatabaseException { + int r = readResource(); + return qc.getOrCreateAssertedPredicates(r); + } + + AssertedStatements readAssertedStatements() throws DatabaseException { + int r1 = readResource(); + int r2 = readResource(); + return qc.getOrCreateAssertedStatements(r1, r2); + } + + ChildMap readChildMap() throws DatabaseException { + int r = readResource(); + return qc.getOrCreateChildMap(r); + } + + DirectObjects readDirectObjects() throws DatabaseException { + int r1 = readResource(); + int r2 = readResource(); + return qc.getOrCreateDirectObjects(r1, r2); + } + + DirectPredicates readDirectPredicates() throws DatabaseException { + int r = readResource(); + return qc.getOrCreateDirectPredicates(r); + } + + Objects readObjects() throws DatabaseException { + int r1 = readResource(); + int r2 = readResource(); + return qc.getOrCreateObjects(r1, r2); + } + + OrderedSet readOrderedSet() throws DatabaseException { + int r = readResource(); + return qc.getOrCreateOrderedSet(r); + } + + Predicates readPredicates() throws DatabaseException { + int r = readResource(); + return qc.getOrCreatePredicates(r); + } + + PrincipalTypes readPrincipalTypes() throws DatabaseException { + int r = readResource(); + return qc.getOrCreatePrincipalTypes(r); + } + + RelationInfoQuery readRelationInfoQuery() throws DatabaseException { + int r = readResource(); + return qc.getOrCreateRelationInfoQuery(r); + } + + Statements readStatements() throws DatabaseException { + int r1 = readResource(); + int r2 = readResource(); + return qc.getOrCreateStatements(r1, r2); + } + + SuperRelations readSuperRelations() throws DatabaseException { + int r = readResource(); + return qc.getOrCreateSuperRelations(r); + } + + SuperTypes readSuperTypes() throws DatabaseException { + int r = readResource(); + return qc.getOrCreateSuperTypes(r); + } + + TypeHierarchy readTypeHierarchy() throws DatabaseException { + int r = readResource(); + return qc.getOrCreateTypeHierarchy(r); + } + + Types readTypes() throws DatabaseException { + int r = readResource(); + return qc.getOrCreateTypes(r); + } + + URIToResource readURIToResource() throws DatabaseException { + String s = readString(); + return qc.getOrCreateURIToResource(s); + } + + ValueQuery readValueQuery() throws DatabaseException { + int r = readResource(); + return qc.getOrCreateValueQuery(r); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryFactory.java new file mode 100644 index 000000000..c4b3f9f9a --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryFactory.java @@ -0,0 +1,8 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public interface QueryFactory { + public CacheEntryBase read(QueryDeserializer deserializer) throws DatabaseException; + public T reference(QueryDeserializer deserializer) throws DatabaseException; +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryFactoryBase.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryFactoryBase.java new file mode 100644 index 000000000..a193ccec3 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryFactoryBase.java @@ -0,0 +1,25 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +abstract public class QueryFactoryBase implements QueryFactory { + + abstract protected CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException; + + public void readParents(QueryDeserializer deserializer, CacheEntryBase entry) throws DatabaseException { + int ps = deserializer.readLE4(); + for(int i=0;i getParents(QueryProcessor processor) { + public Collection getParents(QueryProcessor processor) { // TODO Auto-generated method stub return null; } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java index 6d9560940..f61c661d1 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java @@ -32,6 +32,7 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.core.runtime.Platform; import org.simantics.databoard.Bindings; import org.simantics.db.AsyncReadGraph; import org.simantics.db.DevelopmentKeys; @@ -42,6 +43,7 @@ import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.Statement; import org.simantics.db.VirtualGraph; +import org.simantics.db.common.ByteFileReader; import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter; import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; @@ -68,9 +70,11 @@ import org.simantics.db.request.AsyncMultiRead; import org.simantics.db.request.ExternalRead; import org.simantics.db.request.MultiRead; import org.simantics.db.request.RequestFlags; +import org.simantics.db.service.Bytes; import org.simantics.layer0.Layer0; import org.simantics.utils.DataContainer; import org.simantics.utils.Development; +import org.simantics.utils.FileUtils; import org.simantics.utils.datastructures.Pair; import org.simantics.utils.datastructures.collections.CollectionUtils; import org.simantics.utils.datastructures.disposable.AbstractDisposable; @@ -1069,6 +1073,82 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap } + public synchronized void save() throws IOException { + + long start = System.nanoTime(); + + Collection caches = allCaches(new CacheCollectionResult()).toCollection(); + Map> cachesByCluster = new HashMap<>(); + for(CacheEntryBase entry : caches) { + String clazz = entry.classId(); + if(clazz == null) + continue; + long cluster = entry.cluster(this); + List queries = cachesByCluster.get(cluster); + if(queries == null) { + queries = new ArrayList<>(); + cachesByCluster.put(cluster, queries); + } + queries.add(entry); + } + + File workspace = Platform.getLocation().toFile(); + File dir = new File(workspace, "queryData"); + FileUtils.deleteAll(dir); + + dir.mkdir(); + + for(Long cluster : cachesByCluster.keySet()) { + + List queries = cachesByCluster.get(cluster); + QuerySerializer serializer = new QuerySerializer(this); + int count = 0; + int pos = serializer.writeUnknownSize(); + for(CacheEntryBase entry : queries) { + String clazz = entry.classId(); + if(clazz == null) + continue; + try { + entry.serialize(serializer); + count++; + } catch (IllegalStateException e) { + System.err.println(e.getMessage()); + } + } + serializer.setUnknownSize(pos, count); + + System.err.println(serializer.bytes().length + " bytes for cluster " + cluster); + FileUtils.writeFile(new File(dir, "" + cluster + ".queryData"), serializer.bytes()); + + } + + long end = System.nanoTime(); + + System.err.println("saved queries in " + 1e-6*(end-start) + "ms."); + + } + + public void restore() throws IOException { + + long start = System.nanoTime(); + + File workspace = Platform.getLocation().toFile(); + File dir = new File(workspace, "queryData"); + dir.mkdir(); + + for(File f : FileUtils.listFilesByExtension(dir, "queryData")) { + byte[] bytes = FileUtils.readFile(f); + QueryDeserializer qd = new QueryDeserializer(this, bytes); + qd.readHeaders(); + qd.readQueries(); + } + + long end = System.nanoTime(); + + System.err.println("restored queries in " + 1e-6*(end-start) + "ms."); + + } + boolean removeQuery(CacheEntry entry) { // This entry has been removed before. No need to do anything here. @@ -1760,6 +1840,12 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap } return result; } + + public long cluster(int resource) { + if(resource <= 0) + return 0; + return querySupport.getClusterId(resource); + } public void assertDone() { } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySerializer.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySerializer.java new file mode 100644 index 000000000..06b01407c --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySerializer.java @@ -0,0 +1,136 @@ +package org.simantics.db.impl.query; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.simantics.db.impl.ClusterTraitsBase; + +import gnu.trove.list.array.TByteArrayList; +import gnu.trove.map.hash.TLongIntHashMap; +import gnu.trove.procedure.TLongIntProcedure; + +public class QuerySerializer { + + private QueryProcessor processor; + private QuerySupport querySupport; + private TByteArrayList bytes = new TByteArrayList(); + private TLongIntHashMap clusterKeys = new TLongIntHashMap(); + private Map ids = new HashMap(); + + public QuerySerializer(QueryProcessor processor) { + this.processor = processor; + this.querySupport = processor.querySupport; + } + + public int writeUnknownSize() { + int pos = bytes.size(); + bytes.add((byte)0); + bytes.add((byte)0); + bytes.add((byte)0); + bytes.add((byte)0); + return pos; + } + + public void setUnknownSize(int pos, int value) { + bytes.set(pos, (byte) (value & 0xFF)); + bytes.set(pos+1, (byte) ((value >>> 8) & 0xFF)); + bytes.set(pos+2, (byte) ((value >>> 16) & 0xFF)); + bytes.set(pos+3, (byte) ((value >>> 24) & 0xFF)); + } + + public void serializeId(String classId) { + Integer id = ids.get(classId); + if(id == null) { + id = ids.size() + 1; + ids.put(classId, id); + } + writeLE(id); + } + + public void addResource(int r) { + if(r < 0) { + writeLE(r); + } else { + long clusterId = querySupport.getClusterId(r); + int clusterKey = clusterKeys.get(clusterId); + if(clusterKey == 0) { + clusterKey = clusterKeys.size() + 1; + clusterKeys.put(clusterId, clusterKey); + } + int i = ClusterTraitsBase.createResourceKeyNoThrow(clusterKey, ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(r)); + writeLE(i); + } + } + + public void addString(String s) { + byte[] b = s.getBytes(); + writeLE(b.length); + bytes.add(b); + } + + public void add(byte b) { + bytes.add(b); + } + + public void add(byte[] bs) { + bytes.add(bs); + } + + public byte[] bytes() { + TByteArrayList header = new TByteArrayList(); + writeLE(header, ids.size()); + for(Entry entry : ids.entrySet()) { + String id = entry.getKey(); + writeLE(header, id.length()); + header.add(id.getBytes()); + writeLE(header, entry.getValue()); + } + + writeLE(header, clusterKeys.size()); + clusterKeys.forEachEntry(new TLongIntProcedure() { + + @Override + public boolean execute(long a, int b) { + writeLE(header, a); + writeLE(header, b); + return true; + } + + }); + + header.add(bytes.toArray()); + return header.toArray(); + } + + public void writeLE(int value) { + writeLE(bytes, value); + } + + public static void writeLE(TByteArrayList bytes, int value) { + bytes.add((byte) (value & 0xFF)); + bytes.add((byte) ((value >>> 8) & 0xFF)); + bytes.add((byte) ((value >>> 16) & 0xFF)); + bytes.add((byte) ((value >>> 24) & 0xFF)); + } + + public void writeLE(long value) { + writeLE(bytes, value); + } + + public static void writeLE(TByteArrayList bytes, long value) { + bytes.add((byte) (value & 0xFF)); + bytes.add((byte) ((value >>> 8) & 0xFF)); + bytes.add((byte) ((value >>> 16) & 0xFF)); + bytes.add((byte) ((value >>> 24) & 0xFF)); + bytes.add((byte) ((value >>> 32) & 0xFF)); + bytes.add((byte) ((value >>> 40) & 0xFF)); + bytes.add((byte) ((value >>> 48) & 0xFF)); + bytes.add((byte) ((value >>> 56) & 0xFF)); + } + + public QueryProcessor getQueryProcessor() { + return processor; + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySupport.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySupport.java index 3071c30c0..0a0a207fd 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySupport.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySupport.java @@ -13,17 +13,23 @@ package org.simantics.db.impl.query; import java.io.InputStream; +import org.simantics.db.ObjectResourceIdMap; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.VirtualGraph; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.impl.ClusterSupport; import org.simantics.db.impl.graph.ReadGraphImpl; public interface QuerySupport extends ResourceTranslator { Session getSession(); - + + ClusterSupport getClusterSupport(); + + ObjectResourceIdMap createChildMap(); + boolean isImmutable(int id); long getClusterId(int id); int getId(Resource resource); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ReadEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ReadEntry.java index 8f547d22b..4fb5ed996 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ReadEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ReadEntry.java @@ -214,4 +214,9 @@ public final class ReadEntry extends CacheEntryBase> implem except(throwable); } + @Override + public String classId() { + return null; + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java index cffd2984a..367e75f63 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java @@ -100,4 +100,13 @@ public final class RelationInfoQuery extends UnaryQueryP { return RequestFlags.IMMEDIATE_UPDATE; } + @Override + public void serializeValue(QuerySerializer serializer) { + RelationInfo ri = getResult(); + serializer.addResource(ri.predicate); + serializer.add(ri.isFunctional ? (byte)1 : 0); + serializer.add(ri.isFinal ? (byte)1 : 0); + serializer.add(ri.isAsserted ? (byte)1 : 0); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQueryFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQueryFactory.java new file mode 100644 index 000000000..05adb56a7 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQueryFactory.java @@ -0,0 +1,26 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.RelationInfo; +import org.simantics.db.exception.DatabaseException; + +public class RelationInfoQueryFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + RelationInfoQuery result = reference(deserializer); + int r = deserializer.readResource(); + int isFunctional = deserializer.readByte(); + int isFinal = deserializer.readByte(); + int isAsserted = deserializer.readByte(); + RelationInfo ri = new RelationInfo(r, isFunctional == 1, isFinal == 1, isAsserted == 1); + result.setResult(ri); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readRelationInfoQuery(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/StatementsFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/StatementsFactory.java new file mode 100644 index 000000000..7639235d6 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/StatementsFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class StatementsFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + Statements result = reference(deserializer); + IntArray ia = IntArray.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readStatements(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java index 1f540062e..5c6e8e439 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java @@ -21,7 +21,7 @@ import org.simantics.db.impl.procedure.InternalProcedure; import gnu.trove.procedure.TIntProcedure; import gnu.trove.set.hash.TIntHashSet; -public final class SuperRelations extends UnaryQueryP { +public final class SuperRelations extends UnaryQueryPIntSet { SuperRelations(final int resource) { super(resource); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelationsFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelationsFactory.java new file mode 100644 index 000000000..9011b4606 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelationsFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class SuperRelationsFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + SuperRelations result = reference(deserializer); + IntSet ia = IntSet.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readSuperRelations(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java index a02fda462..f3dc03e14 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java @@ -17,7 +17,7 @@ import org.simantics.db.impl.procedure.InternalProcedure; import gnu.trove.procedure.TIntProcedure; -public final class SuperTypes extends UnaryQueryP { +public final class SuperTypes extends UnaryQueryPIntSet { SuperTypes(int resource) { super(resource); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypesFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypesFactory.java new file mode 100644 index 000000000..edb82ef83 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypesFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class SuperTypesFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + SuperTypes result = reference(deserializer); + IntSet ia = IntSet.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readSuperTypes(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java index 5c2be0c64..323bbd42d 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java @@ -18,7 +18,7 @@ import org.simantics.db.procedure.ListenerBase; import gnu.trove.procedure.TIntProcedure; -public final class TypeHierarchy extends UnaryQueryP { +public final class TypeHierarchy extends UnaryQueryPIntSet { TypeHierarchy(int resource) { super(resource); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchyFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchyFactory.java new file mode 100644 index 000000000..d8120b7f2 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchyFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class TypeHierarchyFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + TypeHierarchy result = reference(deserializer); + IntSet ia = IntSet.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readTypeHierarchy(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java index a9fe36bc6..bb0d11a24 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java @@ -19,7 +19,7 @@ import org.simantics.db.impl.procedure.InternalProcedure; import gnu.trove.procedure.TIntProcedure; -public final class Types extends UnaryQueryP { +public final class Types extends UnaryQueryPIntSet { Types(int resource) { super(resource); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypesFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypesFactory.java new file mode 100644 index 000000000..014b0eecd --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypesFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class TypesFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + Types result = reference(deserializer); + IntSet ia = IntSet.deserialize(deserializer); + result.setResult(ia); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readTypes(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java index ec7ebeed7..9dae343e3 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java @@ -144,4 +144,20 @@ public class URIToResource extends StringQuery> imple except(throwable); } + @Override + public long cluster(QueryProcessor processor) { + return 0; + } + + @Override + public void serializeKey(QuerySerializer serializer) { + serializer.addString(id); + } + + @Override + public void serializeValue(QuerySerializer serializer) { + Integer value = getResult(); + serializer.addResource(value); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResourceFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResourceFactory.java new file mode 100644 index 000000000..ca82ff647 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResourceFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class URIToResourceFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + URIToResource result = reference(deserializer); + int value = deserializer.readResource(); + result.setResult(value); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readURIToResource(); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQuery.java index fd6cd7d87..fe24846aa 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQuery.java @@ -15,6 +15,8 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.impl.graph.ReadGraphImpl; import org.simantics.db.request.RequestFlags; +import gnu.trove.list.array.TByteArrayList; + public abstract class UnaryQuery extends CacheEntryBase implements Query { final public int id; @@ -68,4 +70,14 @@ public abstract class UnaryQuery extends CacheEntryBase im return graph.processor.isImmutable(id); } + @Override + public long cluster(QueryProcessor processor) { + return processor.cluster(id); + } + + @Override + public void serializeKey(QuerySerializer serializer) { + serializer.addResource(id); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryPIntSet.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryPIntSet.java new file mode 100644 index 000000000..cf824790a --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryPIntSet.java @@ -0,0 +1,15 @@ +package org.simantics.db.impl.query; + +abstract public class UnaryQueryPIntSet extends UnaryQueryP { + + public UnaryQueryPIntSet(int r) { + super(r); + } + + @Override + public void serializeValue(QuerySerializer serializer) { + IntSet is = getResult(); + is.serialize(serializer); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java index ad4017f9c..f04df9f68 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java @@ -45,6 +45,17 @@ public final class ValueQuery extends UnaryQueryP { return value; } + + @Override + public void serializeValue(QuerySerializer serializer) { + byte[] result = getResult(); + if(result == null) { + serializer.writeLE(-1); + } else { + serializer.writeLE(result.length); + serializer.add(result); + } + } @Override public String toString() { diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQueryFactory.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQueryFactory.java new file mode 100644 index 000000000..4a746fda1 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQueryFactory.java @@ -0,0 +1,21 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.exception.DatabaseException; + +public class ValueQueryFactory extends QueryFactoryBase { + + @Override + public CacheEntryBase readKeyAndValue(QueryDeserializer deserializer) throws DatabaseException { + ValueQuery result = reference(deserializer); + byte[] bytes = deserializer.readByteArray(); + result.setResult(bytes); + result.setReady(); + return result; + } + + @Override + public T reference(QueryDeserializer deserializer) throws DatabaseException { + return (T)deserializer.readValueQuery(); + } + +} diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DebugSupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DebugSupportImpl.java index 3b05bcba6..ca5eb0825 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DebugSupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DebugSupportImpl.java @@ -45,6 +45,7 @@ import org.simantics.scl.runtime.function.FunctionImpl2; import org.simantics.scl.runtime.function.FunctionImpl3; import org.simantics.utils.Development; import org.simantics.utils.FileUtils; +import org.slf4j.LoggerFactory; import gnu.trove.map.hash.TIntIntHashMap; import gnu.trove.procedure.TIntIntProcedure; @@ -53,6 +54,8 @@ import gnu.trove.set.hash.TIntHashSet; public class DebugSupportImpl implements DebugSupport { + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DebugSupportImpl.class); + final private Map> getCommands = new HashMap>(); final private Map> listCommands = new HashMap>(); final private Map> execCommands = new HashMap>(); @@ -106,6 +109,21 @@ public class DebugSupportImpl implements DebugSupport { }); + listCommands.put("queryData", new FunctionImpl3() { + + @Override + public String apply(WriteGraph graph, File file, String args) { + try { + getSession(graph).queryProvider2.save(); + return "Saved queries"; + } catch (IOException e) { + LOGGER.error("Error while saving queries", e); + return e.getMessage(); + } + } + + }); + listCommands.put("queryActivity", new FunctionImpl3() { @Override diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ObjectResourceMap.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ObjectResourceMap.java index 8b26442d8..02daf860e 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ObjectResourceMap.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ObjectResourceMap.java @@ -214,5 +214,5 @@ final class ObjectResourceMap implements Map, ObjectResourceIdMa public int getId(T t) { return backend.get(t); } - + } \ No newline at end of file diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java index eea97e2e0..0febcea1b 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java @@ -5,6 +5,7 @@ import java.io.InputStream; import java.util.Collection; import java.util.function.Consumer; +import org.simantics.db.ObjectResourceIdMap; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.Statement; @@ -83,7 +84,17 @@ public class QuerySupportImpl implements QuerySupport { public ResourceSupport getSupport() { return resourceSupport; } - + + @Override + public ClusterSupport getClusterSupport() { + return clusterSupport; + } + + @Override + public ObjectResourceIdMap createChildMap() { + return new ObjectResourceMap(session); + } + @Override public Statement getStatement(int s, int p, int o) { return getStatement(null, s, p, o); diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java index 0178e805f..2b7f2da33 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java @@ -93,6 +93,9 @@ final public class SessionImplDb extends SessionImplSocket { serviceLocator.registerService(QuerySupport.class, querySupport); queryProvider2 = new QueryProcessor(getAmountOfQueryThreads(), querySupport, sessionThreads); + + if("true".equals(System.getProperty("org.simantics.db.persistQueries"))) + queryProvider2.restore(); writeSupport = new WriteSupportImpl(this); serviceLocator.registerService(WriteSupport.class, writeSupport); diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/XSupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/XSupportImpl.java index 058706686..7a9be0480 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/XSupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/XSupportImpl.java @@ -1,5 +1,7 @@ package fi.vtt.simantics.procore.internal; +import java.io.IOException; + import org.simantics.db.Database; import org.simantics.db.Resource; import org.simantics.db.Session; @@ -175,5 +177,14 @@ public class XSupportImpl implements XSupport { ClusterImpl clusterImpl = session.clusterTable.getClusterByClusterUIDOrMakeProxy(clusterUID); return clusterImpl.isLoaded(); } - + + @Override + public void saveQueries() throws DatabaseException { + try { + session.queryProvider2.save(); + } catch (IOException e) { + throw new DatabaseException(e); + } + } + } diff --git a/bundles/org.simantics.db/src/org/simantics/db/RelationInfo.java b/bundles/org.simantics.db/src/org/simantics/db/RelationInfo.java index fb4c4820a..168816ed9 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/RelationInfo.java +++ b/bundles/org.simantics.db/src/org/simantics/db/RelationInfo.java @@ -11,8 +11,6 @@ *******************************************************************************/ package org.simantics.db; - - final public class RelationInfo { public static final RelationInfo[] NONE = new RelationInfo[0]; @@ -27,7 +25,7 @@ final public class RelationInfo { this.isFinal = isFinal; this.isAsserted = isAsserted; } - + @Override public String toString() { return "RelationInfo[predicate=" + predicate + ", isFunctional=" + isFunctional + ", isFinal=" + isFinal + ", isAsserted=" + isAsserted + "]"; diff --git a/bundles/org.simantics.db/src/org/simantics/db/service/XSupport.java b/bundles/org.simantics.db/src/org/simantics/db/service/XSupport.java index cf9e96e78..bab69074e 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/service/XSupport.java +++ b/bundles/org.simantics.db/src/org/simantics/db/service/XSupport.java @@ -162,5 +162,7 @@ public interface XSupport { public boolean rolledback(); public boolean isClusterLoaded(ClusterUID clusterUID) throws DatabaseException; - + + public void saveQueries() throws DatabaseException; + } diff --git a/bundles/org.simantics/src/org/simantics/Simantics.java b/bundles/org.simantics/src/org/simantics/Simantics.java index cbe17e940..35808bd92 100644 --- a/bundles/org.simantics/src/org/simantics/Simantics.java +++ b/bundles/org.simantics/src/org/simantics/Simantics.java @@ -44,6 +44,7 @@ import org.simantics.db.management.SessionContextProvider; import org.simantics.db.management.SingleSessionContextProviderSource; import org.simantics.db.request.ReadInterface; import org.simantics.db.request.WriteInterface; +import org.simantics.db.service.XSupport; import org.simantics.internal.FileServiceImpl; import org.simantics.layer0.Layer0; import org.simantics.project.IProject; @@ -467,6 +468,14 @@ public class Simantics { } } + public static void saveQueries(Session session) { + try { + XSupport xs = session.getService(XSupport.class); + xs.saveQueries(); + } catch (Exception e) { + LOGGER.error("Saving database queries failed.", e); + } + } @SuppressWarnings({ "unchecked", "rawtypes" }) public static T applySCL(String module, String function, Object ... args) throws DatabaseException { diff --git a/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java b/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java index c5ed8fd1e..aa0b503da 100644 --- a/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java +++ b/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java @@ -1012,6 +1012,11 @@ public class SimanticsPlatform implements LifecycleListener { } catch (Throwable t) { LOGGER.error("Failed to flush index caches.", t); } + + if("true".equals(System.getProperty("org.simantics.db.persistQueries"))) { + progress.subTask("Saving Queries"); + Simantics.saveQueries(s); + } } progress.subTask("Close Database Session");