DB query swapping to file system 60/4360/1
authorAntti Villberg <antti.villberg@semantum.fi>
Mon, 6 Jul 2020 16:33:19 +0000 (19:33 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Wed, 29 Jul 2020 11:37:26 +0000 (11:37 +0000)
gitlab #572

Change-Id: I3609ab9207fd01710aeb7c00debae259d1dc08c3
(cherry picked from commit 51cf547b475df8309ca0207c35f97fda0d26abd0)

60 files changed:
bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ArraySet.java [deleted file]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicatesFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatementsFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncMultiReadEntry.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncReadEntry.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQuery.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntry.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntryBase.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMapFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionBinaryQuery.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionUnaryQuery.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjectsFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicatesFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntArray.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntSet.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ObjectsFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSetFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PredicatesFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypesFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryDeserializer.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryFactoryBase.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryIdentityHash.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySerializer.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySupport.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ReadEntry.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQueryFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/StatementsFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelationsFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypesFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchyFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypesFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResourceFactory.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQuery.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryPIntSet.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQueryFactory.java [new file with mode: 0644]
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DebugSupportImpl.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ObjectResourceMap.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/XSupportImpl.java
bundles/org.simantics.db/src/org/simantics/db/RelationInfo.java
bundles/org.simantics.db/src/org/simantics/db/service/XSupport.java
bundles/org.simantics/src/org/simantics/Simantics.java
bundles/org.simantics/src/org/simantics/SimanticsPlatform.java

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 (file)
index 1360cef..0000000
+++ /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<Resource> {
-    
-    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<intSet.sizeOrData;i++) set[i] = support.getResource(intSet.data[i]);
-        }
-        
-    }
-    
-    @Override
-    public boolean add(Resource e) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean addAll(Collection<? extends Resource> c) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void clear() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean contains(Object o) {
-        for(int i=0;i<set.length;i++) if(o.equals(set[i])) return true;
-        return false;
-    }
-
-    @Override
-    public boolean containsAll(Collection<?> c) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return set.length == 0;
-    }
-
-    @Override
-    public Iterator<Resource> iterator() {
-        
-        class ArraySetIterator implements Iterator<Resource> {
-            
-            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> T[] toArray(T[] a) {
-        throw new UnsupportedOperationException();
-    }
-
-}
index b4104e965fbc0b56be90fc40a8f0cd07eef5ab3a..23fbe95ecd6627453202e85e94a6711e6ae0d947 100644 (file)
@@ -241,5 +241,11 @@ final public class AssertedPredicates extends UnaryQuery<IntProcedure> {
         });
         
     }
-    
+
+    @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 (file)
index 0000000..c76bc51
--- /dev/null
@@ -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 extends CacheEntryBase> 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 (file)
index 0000000..708ce66
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readAssertedStatements();
+    }
+
+}
index ea88d179107c920f9f10193f727907a56d39356e..7880448078dc0f7edb48701c4de7d9bac52e9fec 100644 (file)
@@ -190,4 +190,9 @@ final public class AsyncMultiReadEntry<T> extends CacheEntryBase<AsyncMultiProce
                return graph.processor.cache.performQuery(graph, id, this, procedure);
        }
 
+    @Override
+    public String classId() {
+        return null;
+    }
+
 }
index 5017151b10b9f8478bf1df7319326d020b0fb583..2fdb43d113332e4f33b6b131685fd8c80c112b22 100644 (file)
@@ -213,4 +213,9 @@ final public class AsyncReadEntry<T> extends CacheEntryBase<AsyncProcedure<T>> i
         }
     }
 
+    @Override
+    public String classId() {
+        return null;
+    }
+
 }
index d699ea825d9823cfb8c1f3454f13115ff4518455..04df0d00c5c8f1ea1222eee6000788e8e2a43bde 100644 (file)
@@ -66,4 +66,15 @@ public abstract class BinaryQuery<Procedure> extends CacheEntryBase<Procedure> 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());
+    }
+
 }
index 1cdcbde9dd0b11733b224877c4a5a0c7cf41cbe7..edb0870254f327ebba56d297c2a166a40003efd2 100644 (file)
@@ -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<Procedure> {
     abstract void removeParent(CacheEntry entry);
     abstract void addParent(CacheEntry entry);
     abstract boolean hasParents();
-    abstract Iterable<CacheEntry<?>> getParents(QueryProcessor processor);
+    abstract Collection<CacheEntry<?>> getParents(QueryProcessor processor);
     abstract CacheEntry getFirstParent(QueryProcessor processor);
     abstract boolean moreThanOneParent(QueryProcessor processor);
     abstract int parentCount(QueryProcessor processor);
index e79f99deae1d06ab4469e1496accd8fbcacb3e97..56da11ace36b718d75ce3fa48ac9012c6f3eedf0 100644 (file)
@@ -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<Procedure> extends CacheEntry<Procedure> {
     }
     
     @Override
-       final public Iterable<CacheEntry<?>> getParents(QueryProcessor processor) {
+       final public Collection<CacheEntry<?>> getParents(QueryProcessor processor) {
 
                ArrayList<CacheEntry<?>> result = new ArrayList<CacheEntry<?>>();
                if(p1 != null) result.add(p1);
@@ -471,5 +472,44 @@ public abstract class CacheEntryBase<Procedure> extends CacheEntry<Procedure> {
 
     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<CacheEntry<?>> 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);
+    }
 
 }
index 8effbb1d549152bd21f0ecdae723bc0c7c81993d..79d3106a8c0074b9ce763e2c4188b819656eb48d 100644 (file)
@@ -142,6 +142,16 @@ public final class ChildMap extends UnaryQueryP<ObjectResourceIdMap<String>> {
 
     }
 
+    @Override
+    public void serializeValue(QuerySerializer serializer) {
+        ObjectResourceIdMap<String> 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 (file)
index 0000000..bf179b5
--- /dev/null
@@ -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<String> map = deserializer.createChildMap();
+        int size = deserializer.readLE4();
+        for(int i=0;i<size;i++) {
+            String key = deserializer.readString();
+            int r2 = deserializer.readResource();
+            map.putId(key, r2);
+        }
+        result.setResult(map);
+        result.setReady();
+        return result;
+    }
+    
+    @Override
+    public <T extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readChildMap();
+    }
+
+}
index cd139655cfa647080f74d825ddbafdbf02dd433b..6e1692ba462f1af084d502959f25d41513c15e89 100644 (file)
@@ -11,9 +11,6 @@
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-
-
-
 abstract public class CollectionBinaryQuery<T> extends BinaryQuery<T> {
        
     public CollectionBinaryQuery(final int r1, final int r2) {
@@ -33,5 +30,11 @@ abstract public class CollectionBinaryQuery<T> extends BinaryQuery<T> {
         if(size == 0) setResult(IntArray.EMPTY);
         else v.trim();
     }
-    
+
+    @Override
+    public void serializeValue(QuerySerializer serializer) {
+        IntArray is = getResult();
+        is.serialize(serializer);
+    }
+
 }
index 90bb0355447acfeac8089b3f080d435f062a23e8..2eaeca472c2088d7d10156cc678506004dfdacbc 100644 (file)
@@ -96,4 +96,10 @@ public abstract class CollectionUnaryQuery extends UnaryQuery<IntProcedure> 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 (file)
index 0000000..323ec21
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readDirectObjects();
+    }
+
+}
index 1a006369a1d6867c0c788449f61900eae12d55ee..ee0faa1cfdd8b607ab59a8261e7e2c38af6d9e4b 100644 (file)
@@ -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<IntSet> {
+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 (file)
index 0000000..e707e62
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readDirectPredicates();
+    }
+
+}
index d044043394ef771f7e7e0cfab3e5257f77883db6..6253744bb05e26d012ff3b86906e465fc9911e95 100644 (file)
@@ -231,5 +231,10 @@ final public class ExternalReadEntry<T> extends CacheEntryBase<AsyncProcedure<T>
        public boolean isDisposed() {
                return registered && (isDiscarded() || !graph.processor.isBound(this));
        }
-    
+
+    @Override
+    public String classId() {
+        return null;
+    }
+
 }
index 6ee30ad70fd1d341930f11c35eabe2ecdf69af87..53b447f08b3da6e081bfff9d1a0452c4bd552bde 100644 (file)
@@ -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<size;i++)
+                serializer.addResource(data[i]);
+        }
+    }
+    public static IntArray deserialize(QueryDeserializer deserializer) throws DatabaseException {
+        int size = deserializer.readLE4();
+        IntArray result = new IntArray();
+        for(int i=0;i<size;i++) {
+            result.add(deserializer.readResource());
+        }
+        return result;
+    }
+
     @Override
     public boolean equals(Object object) {
         if (this == object)
index 3ef19b8f335ec9dbf60aeaf1df6bf818251d67a2..3f2e0140bda6f0a2da13dea02e7e24b7a77e8230 100644 (file)
@@ -32,8 +32,7 @@ final public class IntSet implements ResourceSet {
 
     public int[] data;
 
-    /** the index after the last entry in the list */
-    public int sizeOrData;
+    private int sizeOrData;
 
     /** the default capacity for new lists */
     protected static final int DEFAULT_CAPACITY = 3;
@@ -46,6 +45,8 @@ final public class IntSet implements ResourceSet {
 
     private IntSet() {
         support = null;
+        data = null;
+        sizeOrData = NO_DATA;
     }
 
     public IntSet(QuerySupport support) {
@@ -299,5 +300,26 @@ final public class IntSet implements ResourceSet {
         }
         procedure.finished(graph);
     }
+    
+    public void serialize(QuerySerializer serializer) {
+        serializer.writeLE(size());
+        forEach(new TIntProcedure() {
+            
+            @Override
+            public boolean execute(int value) {
+                serializer.addResource(value);
+                return true;
+            }
+        });
+    }
+    
+    public static IntSet deserialize(QueryDeserializer deserializer) throws DatabaseException {
+        int size = deserializer.readLE4();
+        IntSet result = new IntSet();
+        for(int i=0;i<size;i++) {
+            result.add(deserializer.readResource());
+        }
+        return result;
+    }
 
 }
\ No newline at end of file
index 8bac422636ff9a13d8064f5ab0ef64cee6a4d476..c84b63dc61a5d6304cf52c3478c8c91a7ca9f7e3 100644 (file)
@@ -680,4 +680,10 @@ public final class Objects extends CollectionBinaryQuery<IntProcedure> 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 (file)
index 0000000..f6758e6
--- /dev/null
@@ -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 extends CacheEntryBase> 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 (file)
index 0000000..9b5f581
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readOrderedSet();
+    }
+
+}
index 9445db03b4e048ca1488cb22f45eeaa56da9bdd1..982d8019c0c7cdd6328b791fa2071baf98ece9f9 100644 (file)
@@ -19,7 +19,7 @@ import org.simantics.db.request.RequestFlags;
 
 import gnu.trove.procedure.TIntProcedure;
 
-final public class Predicates extends UnaryQueryP<IntSet> {
+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 (file)
index 0000000..c86e43c
--- /dev/null
@@ -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 extends CacheEntryBase> 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 (file)
index 0000000..ccd4ddc
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readPrincipalTypes();
+    }
+
+}
index f80fb5098b847d9264768be6c833c39d38a7ac24..b0bca135042fbe99a5f07ffc3f4cab28628a164b 100644 (file)
@@ -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 (file)
index 0000000..0fe9b9c
--- /dev/null
@@ -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<Integer,QueryFactory> ids = new HashMap<Integer,QueryFactory>();
+
+    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<idsSize;i++) {
+            int size = readLE4();
+            byte[] data = readBytes(size);
+            String id = new String(data);
+            int key = readLE4();
+            try {
+                Class<QueryFactory> clazz = (Class<QueryFactory>)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<clusterKeysSize;i++) {
+            long cluster = readLE8();
+            int key = readLE4();
+            clusterKeys.put(key, cluster);
+        }
+    }
+    
+    public QueryFactory readFactory() {
+        int key = readLE4();
+        return ids.get(key);
+    }
+
+    public void readQueries() {
+        int count = readLE4();
+        for(int i=0;i<count;i++) {
+            QueryFactory qf = readFactory();
+            try {
+                qf.read(this);
+            } catch (DatabaseException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public int readResource() throws DatabaseException {
+        int key = readLE4();
+        if(key < 0)
+            return key;
+        int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKey(key);
+        long cluster = clusterKeys.get(clusterKey);
+        ClusterBase cb = cs.getClusterByClusterId(cluster);
+        return ClusterTraitsBase.createResourceKey(cb.getClusterKey(), ClusterTraitsBase.getResourceIndexFromResourceKey(key));
+    }
+    
+    public byte[] readByteArray() {
+        int len = readLE4();
+        if(len == -1)
+            return null;
+        return readBytes(len);
+    }
+    
+    public String readString() {
+        return new String(readByteArray());
+    }
+    
+    public ObjectResourceIdMap<String> 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 (file)
index 0000000..c4b3f9f
--- /dev/null
@@ -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 extends CacheEntryBase> 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 (file)
index 0000000..a193cce
--- /dev/null
@@ -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<ps;i++) {
+            QueryFactory qf = deserializer.readFactory();
+            CacheEntryBase ceb = qf.reference(deserializer);
+            entry.addParent(ceb);
+        }
+    }
+    
+    @Override
+    final public CacheEntryBase read(QueryDeserializer deserializer) throws DatabaseException {
+        CacheEntryBase entry = readKeyAndValue(deserializer);
+        readParents(deserializer, entry);
+        return entry;
+    }
+
+}
index c2b21444fd17157753d2cfc303bd8b4932a488fa..ffbf4b2a9a34f2f20814b2e17df54a6ee66f349b 100644 (file)
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import gnu.trove.impl.hash.THash;
+import java.util.Collection;
 
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 
+import gnu.trove.impl.hash.THash;
+
 
 /**
  * An open addressed hashing implementation for Object types.
@@ -59,7 +61,7 @@ abstract public class QueryIdentityHash extends THash {
         }
 
         @Override
-        public Iterable<CacheEntry> getParents(QueryProcessor processor) {
+        public Collection<CacheEntry> getParents(QueryProcessor processor) {
             // TODO Auto-generated method stub
             return null;
         }
index 6d9560940be2b1c19b73616c85a2996ee2b65d25..f61c661d19cbd7eb47fbf15de27ef4bb9035627c 100644 (file)
@@ -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<CacheEntryBase> caches = allCaches(new CacheCollectionResult()).toCollection();
+        Map<Long,List<CacheEntryBase>> cachesByCluster = new HashMap<>();
+        for(CacheEntryBase entry : caches) {
+            String clazz = entry.classId();
+            if(clazz == null)
+                continue;
+            long cluster = entry.cluster(this);
+            List<CacheEntryBase> 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<CacheEntryBase> 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 (file)
index 0000000..06b0140
--- /dev/null
@@ -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<String,Integer> ids = new HashMap<String,Integer>();
+
+    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<String,Integer> 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;
+    }
+
+}
index 3071c30c042d8730799004eec9d10b7168b70fd4..0a0a207fdc4d8d90b51ac93e594bc417489984f8 100644 (file)
@@ -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<String> createChildMap();
+
        boolean isImmutable(int id);
        long getClusterId(int id);
        int getId(Resource resource);
index 8f547d22b3e950a9c3b87e035fd9a0e07a4aef08..4fb5ed996011a047659a22158477103d216c6f41 100644 (file)
@@ -214,4 +214,9 @@ public final class ReadEntry<T> extends CacheEntryBase<AsyncProcedure<T>> implem
         except(throwable);
     }
 
+    @Override
+    public String classId() {
+        return null;
+    }
+
 }
index cffd2984a0c31219acfcb740aa7cf921df0e709e..367e75f632c3cdd10e592286fb06cacdb13548b6 100644 (file)
@@ -100,4 +100,13 @@ public final class RelationInfoQuery extends UnaryQueryP<RelationInfo> {
                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 (file)
index 0000000..05adb56
--- /dev/null
@@ -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 extends CacheEntryBase> 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 (file)
index 0000000..7639235
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readStatements();
+    }
+
+}
index 1f540062e9440d2db81164ee820c05566f4a55c0..5c6e8e43947917da321343525984fdb8a362d47a 100644 (file)
@@ -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<IntSet> {
+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 (file)
index 0000000..9011b46
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readSuperRelations();
+    }
+
+}
index a02fda4623342fc7d80889f8c543f6d5aec70316..f3dc03e14ffb2c85f7f7885516a45c130ab67709 100644 (file)
@@ -17,7 +17,7 @@ import org.simantics.db.impl.procedure.InternalProcedure;
 
 import gnu.trove.procedure.TIntProcedure;
 
-public final class SuperTypes extends UnaryQueryP<IntSet> {
+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 (file)
index 0000000..edb82ef
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readSuperTypes();
+    }
+
+}
index 5c2be0c64e6dca1908b182ee340073de9405bfa3..323bbd42dc66d811e1b2db14d8eb39c724585bd1 100644 (file)
@@ -18,7 +18,7 @@ import org.simantics.db.procedure.ListenerBase;
 
 import gnu.trove.procedure.TIntProcedure;
 
-public final class TypeHierarchy extends UnaryQueryP<IntSet> {
+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 (file)
index 0000000..d8120b7
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readTypeHierarchy();
+    }
+
+}
index a9fe36bc6bfcb60608e2758f3a28721c165e09dc..bb0d11a243193da746bb88804696317503dc941f 100644 (file)
@@ -19,7 +19,7 @@ import org.simantics.db.impl.procedure.InternalProcedure;
 
 import gnu.trove.procedure.TIntProcedure;
 
-public final class Types extends UnaryQueryP<IntSet> {
+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 (file)
index 0000000..014b0ee
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readTypes();
+    }
+
+}
index ec7ebeed7fad0324035280af18dc69225307c1ac..9dae343e39b3e7028e2e46d0f14def1d6dfbcc1e 100644 (file)
@@ -144,4 +144,20 @@ public class URIToResource extends StringQuery<InternalProcedure<Integer>> 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 (file)
index 0000000..ca82ff6
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readURIToResource();
+    }
+
+}
index fd6cd7d879374bb8af81c18a40058137b46aed2e..fe24846aa318539da2524f19a0c50b4a2e382d5c 100644 (file)
@@ -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<Procedure> extends CacheEntryBase<Procedure> implements Query {
 
     final public int id;
@@ -68,4 +70,14 @@ public abstract class UnaryQuery<Procedure> extends CacheEntryBase<Procedure> 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 (file)
index 0000000..cf82479
--- /dev/null
@@ -0,0 +1,15 @@
+package org.simantics.db.impl.query;
+
+abstract public class UnaryQueryPIntSet extends UnaryQueryP<IntSet> {
+
+    public UnaryQueryPIntSet(int r) {
+        super(r);
+    }
+    
+    @Override
+    public void serializeValue(QuerySerializer serializer) {
+        IntSet is = getResult();
+        is.serialize(serializer);
+    }
+
+}
index ad4017f9cff863c0a2bbe42a4fb9458a655e57f2..f04df9f6846097d6b03c1f1b0bc5411ca71af248 100644 (file)
@@ -45,6 +45,17 @@ public final class ValueQuery extends UnaryQueryP<byte[]> {
         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 (file)
index 0000000..4a746fd
--- /dev/null
@@ -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 extends CacheEntryBase> T reference(QueryDeserializer deserializer) throws DatabaseException {
+        return (T)deserializer.readValueQuery();
+    }
+
+}
index 3b05bcba6d67baabc0ee5afcf48557f522f3b384..ca5eb0825a3c6462676dcee91124d4b2384b2021 100644 (file)
@@ -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<String, Function2<WriteGraph, String, Object>> getCommands = new HashMap<String, Function2<WriteGraph, String, Object>>();
        final private Map<String, Function3<WriteGraph, File, String, String>> listCommands = new HashMap<String, Function3<WriteGraph, File, String, String>>();
        final private Map<String, Function2<WriteGraph, String, String>> execCommands = new HashMap<String, Function2<WriteGraph, String, String>>();
@@ -106,6 +109,21 @@ public class DebugSupportImpl implements DebugSupport {
 
                });
 
+        listCommands.put("queryData", new FunctionImpl3<WriteGraph, File, String, String>() {
+
+            @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<WriteGraph, File, String, String>() {
 
                        @Override
index 8b26442d87ff6c70a6e37e4a8dfa980d9f342e2b..02daf860e7945fcb27345d264a4a36026373642a 100644 (file)
@@ -214,5 +214,5 @@ final class ObjectResourceMap<T> implements Map<T, Resource>, ObjectResourceIdMa
        public int getId(T t) {
                return backend.get(t);
        }
-
+       
 }
\ No newline at end of file
index eea97e2e0a673c0050cf0f14f6aa1d2c99494719..0febcea1b87b2781c3c5461a2adb051d929e42a9 100644 (file)
@@ -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<String> createChildMap() {
+        return new ObjectResourceMap<String>(session);
+    }
+
     @Override
     public Statement getStatement(int s, int p, int o) {
         return getStatement(null, s, p, o);
index 0178e805fd29d09b99cce3ecc5ff7d8a4b3e8fec..2b7f2da3358778d90495a7a20b59b12f69ed9ed3 100644 (file)
@@ -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);
index 05870668616b258e648634e5ac4383a88f8277f1..7a9be048055fdcff23e9831a2882917d2d5ede6d 100644 (file)
@@ -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);
+        }
+    }
+
 }
index fb4c4820a43442dd97c8d7d545e109abfb74e78c..168816ed992852c5f5e561f84f7790e5b461b649 100644 (file)
@@ -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 + "]";
index cf9e96e7833421fb7617cc9ebeaef422a9dd3947..bab69074e6ca1cd30dc5fdb613dad21cfb67cf0c 100644 (file)
@@ -162,5 +162,7 @@ public interface XSupport {
     public boolean rolledback();
     
     public boolean isClusterLoaded(ClusterUID clusterUID) throws DatabaseException;
-    
+
+    public void saveQueries() throws DatabaseException;
+
 }
index cbe17e940d9436223aa6c2b62127872963a7b769..35808bd929fa74d63f18f860bdc51680abeababf 100644 (file)
@@ -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> T applySCL(String module, String function, Object ... args) throws DatabaseException {
index c5ed8fd1e6374b70294bf65ecd5a4034b40b2efa..aa0b503dace880ca7c18d86dd1584f944a18260e 100644 (file)
@@ -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");