]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Multiple reader thread support for db client 69/1969/7
authorAntti Villberg <antti.villberg@semantum.fi>
Fri, 27 Jul 2018 20:33:59 +0000 (23:33 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Fri, 3 Aug 2018 05:00:34 +0000 (08:00 +0300)
gitlab #5

Change-Id: Ia5c189525f2f8277bfc10234c41a1ae47082bb15

180 files changed:
bundles/org.simantics.acorn/src/org/simantics/acorn/cluster/ClusterBig.java
bundles/org.simantics.acorn/src/org/simantics/acorn/cluster/ClusterSmall.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyGraphLabeler.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyParametrizedViewpoint.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyResourceQueryContainer.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyViewpoint.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/CallbackViewpointContributionImpl.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalCheckedStateContributionImpl.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalImageDecoratorContributionImpl.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalImagerContributionImpl.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalLabelDecoratorContributionImpl.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalLabelerContributionImpl.java
bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalViewpointContributionImpl.java
bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/ForEachAssertedObject.java
bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/IsInstanceOf.java
bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/PossibleAdapter.java
bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/RelationInfoRequest.java
bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/single/SingleSetSyncListenerDelegate.java
bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/wrapper/NoneToSyncMultiListener.java [new file with mode: 0644]
bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/wrapper/NoneToSyncMultiProcedure.java [new file with mode: 0644]
bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java
bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java
bundles/org.simantics.db.common/src/org/simantics/db/common/request/PossibleTypedParent.java
bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceAsyncMultiRead.java
bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceAsyncRead2.java
bundles/org.simantics.db.common/src/org/simantics/db/common/uri/UnescapedChildMapOfResource.java
bundles/org.simantics.db.common/src/org/simantics/db/common/utils/CommonDBUtils.java
bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java
bundles/org.simantics.db.common/src/org/simantics/db/common/utils/Transaction.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncMultiProcedure.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/ClusterI.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectContextProcedure.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectProcedure.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForPossibleRelatedValueContextProcedure.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForPossibleRelatedValueProcedure.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/TransientGraph.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/MultiIntProcedure.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphSupport.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/InternalProcedure.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/ResultCallWrappedSyncQueryProcedure.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/TripleIntProcedureAdapter.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatements.java
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/BinaryQueryHash.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 [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CollectionUnaryQuery.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjects.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectSuperRelations.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DoubleKeyQueryHashMap.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntProcedure.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/MultiReadEntry.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/NamespaceIndex.java [deleted file]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSet.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PossibleSuperRelation.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypes.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Query.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCollectorImpl2.java
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/QuerySupport.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.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/Statements.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/StringQuery.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SyncIntProcedure.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ThreadRunnable.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TripleIntProcedure.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQuery.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryHash.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryP.java [new file with mode: 0644]
bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/TGRemover.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/ExternalRequest.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/NamespaceRequirements.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/OntologiesForModel.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/combinations/Combinators.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSourceRequest.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterWriteOnly.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DirectQuerySupportImpl.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ObjectResourceMap.java [new file with mode: 0644]
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QueryControlImpl.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QueryDebugImpl.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/SessionImplSocket.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterBig.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterSmall.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/IntHash.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ObjectTable.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTable.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTableSmall.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntSet.java
bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java
bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/reflection/AbstractReflectionAdapter.java
bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/reflection/ReflectionAdapter2.java
bundles/org.simantics.db.testing/src/org/simantics/db/testing/common/TestBase.java
bundles/org.simantics.db/src/org/simantics/db/AsyncReadGraph.java
bundles/org.simantics.db/src/org/simantics/db/AsyncRequestProcessor.java
bundles/org.simantics.db/src/org/simantics/db/AsyncRequestProcessorSpecific.java
bundles/org.simantics.db/src/org/simantics/db/ObjectResourceIdMap.java [new file with mode: 0644]
bundles/org.simantics.db/src/org/simantics/db/ReadGraph.java
bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java
bundles/org.simantics.db/src/org/simantics/db/RequestProcessorSpecific.java
bundles/org.simantics.db/src/org/simantics/db/Session.java
bundles/org.simantics.db/src/org/simantics/db/procedure/SyncContextMultiProcedure.java [new file with mode: 0644]
bundles/org.simantics.db/src/org/simantics/db/procedure/SyncContextProcedure.java [new file with mode: 0644]
bundles/org.simantics.db/src/org/simantics/db/request/AsyncMultiRead.java
bundles/org.simantics.db/src/org/simantics/db/request/AsyncRead.java
bundles/org.simantics.db/src/org/simantics/db/request/MultiRead.java
bundles/org.simantics.db/src/org/simantics/db/request/Request.java [deleted file]
bundles/org.simantics.db/src/org/simantics/db/service/DirectQuerySupport.java
bundles/org.simantics.db/src/org/simantics/db/service/QueryControl.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/ConstantStyle.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/MappedTypeGroup.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/DiagramElementGroup.java
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java
bundles/org.simantics.diagram/src/org/simantics/diagram/runtime/RuntimeDiagramManager.java
bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java
bundles/org.simantics.issues.common/src/org/simantics/issues/common/IssueUtils.java
bundles/org.simantics.layer0.utils/src/org/simantics/layer0/utils/queries/QueryExecutor2.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorClassFactory2.java
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/issue/SCLExpressionIssueProvider.java
bundles/org.simantics.modeling/src/org/simantics/modeling/subscription/ModelHistoryCollector.java
bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/Group.java
bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/Style.java
bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java
bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/GraphUI.java
bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SheetFactory.java
bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorInput2.java
bundles/org.simantics.ui/src/org/simantics/ui/workbench/editor/input/InputValidationCombinators.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/readGraph/forObjectSet/ForObjectSetTest1.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/AsyncTransactionTest.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest3.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest4.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest5.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest6.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestProcessorTest1.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestQueuingTest.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest2.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest5.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest6.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest9.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/performance/read/HierarchicalNames.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/performance/read/ReadHierarchicalNames.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test1.java
tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test2.java

index 1de4006a72e630482a22dd5390c39b2e411fb15b..063bcf548fa27f687318a1e021fcae511f8bf668 100644 (file)
@@ -40,8 +40,8 @@ import org.simantics.db.impl.Table;
 import org.simantics.db.impl.TableHeader;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.query.QueryProcessor;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.procore.cluster.ClusterMap;
 import org.simantics.db.procore.cluster.ClusterPrintDebugInfo;
 import org.simantics.db.procore.cluster.ClusterTraits;
@@ -54,6 +54,8 @@ import org.simantics.db.procore.cluster.ResourceTable;
 import org.simantics.db.procore.cluster.ValueTable;
 import org.simantics.db.service.ClusterUID;
 
+import fi.vtt.simantics.procore.internal.SessionImplSocket;
+
 final public class ClusterBig extends ClusterImpl {
     private static final int TABLE_HEADER_SIZE = TableHeader.HEADER_SIZE + TableHeader.EXTRA_SIZE;
     private static final int RESOURCE_TABLE_OFFSET = 0;
@@ -263,7 +265,7 @@ final public class ClusterBig extends ClusterImpl {
         return objectTable.getSingleObject(objectIndex, support, this);
     }
 
-    public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure,
+    public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, SyncMultiProcedure<Resource> procedure,
             ClusterSupport support) throws DatabaseException {
         if (DEBUG)
             System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
@@ -276,7 +278,7 @@ final public class ClusterBig extends ClusterImpl {
         }
         objectTable.foreachObject(graph, objectIndex, procedure, this);
     }
-    public <C> void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, AsyncContextMultiProcedure<C, Resource> procedure,
+    public <C> void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, SyncContextMultiProcedure<C, Resource> procedure,
             ClusterSupport support) throws DatabaseException {
         if (DEBUG)
             System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
@@ -355,57 +357,53 @@ final public class ClusterBig extends ClusterImpl {
     
     @Override
     public void forObjects(ReadGraphImpl graph, int resourceKey,
-            int predicateKey, AsyncMultiProcedure<Resource> procedure)
+            int predicateKey, SyncMultiProcedure<Resource> procedure)
             throws DatabaseException {
         
-       throw new UnsupportedOperationException();
-       
-//        SessionImplSocket session = (SessionImplSocket)graph.getSession();
-//        ClusterSupport support = session.clusterTranslator;
-//        
-//        if (DEBUG)
-//            System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
-//        final int resourceIndex = getLocalReference(resourceKey);
-//        final int pRef = getInternalReferenceOrZero(predicateKey, support);
-//        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
-//        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
-//            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
-//            return;
-//        }
-//        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
-//        if (0 == predicateIndex) {
-//            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
-//            return;
-//        }
-//        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
-//        forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);
+        SessionImplSocket session = (SessionImplSocket)graph.getSession();
+        ClusterSupport support = session.clusterTranslator;
+        
+        if (DEBUG)
+            System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
+        final int resourceIndex = getLocalReference(resourceKey);
+        final int pRef = getInternalReferenceOrZero(predicateKey, support);
+        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
+        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
+            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
+        if (0 == predicateIndex) {
+            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
+        forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);
         
     }
     
     @Override
     public void forObjects(ReadGraphImpl graph, int resourceKey, ForEachObjectProcedure procedure) throws DatabaseException {
        
-       throw new UnsupportedOperationException();
-       
-//        SessionImplSocket session = (SessionImplSocket)graph.getSession();
-//        ClusterSupport support = session.clusterTranslator;
-//        final int predicateKey = procedure.predicateKey;
-//        if (DEBUG)
-//            System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
-//        final int resourceIndex = getLocalReference(resourceKey);
-//        final int pRef = getInternalReferenceOrZero(predicateKey, support);
-//        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
-//        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
-//            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
-//            return;
-//        }
-//        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
-//        if (0 == predicateIndex) {
-//            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
-//            return;
-//        }
-//        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
-//        forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);
+        SessionImplSocket session = (SessionImplSocket)graph.getSession();
+        ClusterSupport support = session.clusterTranslator;
+        final int predicateKey = procedure.predicateKey;
+        if (DEBUG)
+            System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
+        final int resourceIndex = getLocalReference(resourceKey);
+        final int pRef = getInternalReferenceOrZero(predicateKey, support);
+        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
+        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
+            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
+        if (0 == predicateIndex) {
+            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
+        forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);
         
     }
     @Override
index 117ab75a3fc723b66660cd48c6db6231b496a3d1..a964c90c98fbbb5bb64842d43563df7d54f76053 100644 (file)
@@ -38,8 +38,8 @@ import org.simantics.db.impl.IClusterTable;
 import org.simantics.db.impl.Table;
 import org.simantics.db.impl.TableHeader;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.procore.cluster.ClusterMapSmall;
 import org.simantics.db.procore.cluster.ClusterTraits;
 import org.simantics.db.procore.cluster.ClusterTraitsSmall;
@@ -54,6 +54,7 @@ import org.simantics.db.service.Bytes;
 import org.simantics.db.service.ClusterUID;
 import org.simantics.db.service.ResourceUID;
 
+import fi.vtt.simantics.procore.internal.SessionImplSocket;
 import gnu.trove.map.hash.TIntShortHashMap;
 import gnu.trove.procedure.TIntProcedure;
 import gnu.trove.set.hash.TIntHashSet;
@@ -300,7 +301,7 @@ final public class ClusterSmall extends ClusterImpl {
         return objectTable.getSingleObject(objectIndex, support, this);
     }
 
-    public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, AsyncMultiProcedure<Resource> procedure,
+    public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, SyncMultiProcedure<Resource> procedure,
             ClusterSupport support) throws DatabaseException {
         if (DEBUG)
             System.out.println("ClusterSmall.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
@@ -314,7 +315,7 @@ final public class ClusterSmall extends ClusterImpl {
         objectTable.foreachObject(graph, objectIndex, procedure, this);
     }
 
-    public <C> void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, C context, AsyncContextMultiProcedure<C, Resource> procedure,
+    public <C> void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, C context, SyncContextMultiProcedure<C, Resource> procedure,
             ClusterSupport support) throws DatabaseException {
         if (DEBUG)
             System.out.println("ClusterSmall.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
@@ -408,29 +409,28 @@ final public class ClusterSmall extends ClusterImpl {
 
     @Override
     public void forObjects(ReadGraphImpl graph, int resourceKey,
-            int predicateKey, AsyncMultiProcedure<Resource> procedure) throws DatabaseException {
+            int predicateKey, SyncMultiProcedure<Resource> procedure) throws DatabaseException {
        
-       throw new UnsupportedOperationException();
-       
-//        SessionImplSocket session = (SessionImplSocket)graph.getSession();
-//        ClusterSupport support = session.clusterTranslator;
-//        if (DEBUG)
-//            System.out.println("ClusterSmall.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
-//        final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
-//        final int pRef = getInternalReferenceOrZero2(predicateKey, support);
-//        final int completeType = ClusterTraitsBase.getCompleteTypeIntFromResourceKey(predicateKey);
-//        final ClusterI.CompleteTypeEnum pCompleteType = CompleteTypeEnum.make(completeType);
-//        if (completeType > 0) {
-//            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
-//            return;
-//        }
-//        final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF;
-//        if (0 == predicateIndex) {
-//            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
-//            return;
-//        }
-//        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF);
-//        forObjects(graph, resourceKey, predicateKey, objectIndex, procedure, support);
+        SessionImplSocket session = (SessionImplSocket)graph.getSession();
+        ClusterSupport support = session.clusterTranslator;
+        if (DEBUG)
+            System.out.println("ClusterSmall.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
+        final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey);
+        final int pRef = getInternalReferenceOrZero2(predicateKey, support);
+        final int completeType = ClusterTraitsBase.getCompleteTypeIntFromResourceKey(predicateKey);
+        final ClusterI.CompleteTypeEnum pCompleteType = CompleteTypeEnum.make(completeType);
+        if (completeType > 0) {
+            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF;
+        if (0 == predicateIndex) {
+            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF);
+        forObjects(graph, resourceKey, predicateKey, objectIndex, procedure, support);
+        
     }
 
     public void forObjects(ReadGraphImpl graph, int resourceKey, ForEachObjectProcedure procedure) throws DatabaseException {
index a7635bedfbb676c337870027bcb85550494766e5..639c90391f8c73351cb9c2e86211e7755d5953d0 100644 (file)
@@ -21,6 +21,7 @@ import org.simantics.browsing.ui.PrimitiveQueryUpdater;
 import org.simantics.browsing.ui.common.labelers.LabelerContent;
 import org.simantics.browsing.ui.common.labelers.LabelerStub;
 import org.simantics.browsing.ui.graph.impl.request.ResourceQuery;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.Listener;
@@ -92,7 +93,7 @@ public abstract class LazyGraphLabeler extends LabelerStub {
 
         if (content == LabelerContent.NO_CONTENT) {
 
-            final DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+            final DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
             assert(source != null);
             source.schedule(graph -> graph.asyncRequest(labelQuery, procedure));
 
index 91aeb9c5d4539b5e2e4e189fc703b5f2bdd6cb03..c5d96a90a81fac91b86f556acc421e61130eb153 100644 (file)
@@ -11,8 +11,6 @@
  *******************************************************************************/
 package org.simantics.browsing.ui.graph.impl;
 
-import java.util.function.Consumer;
-
 import org.simantics.browsing.ui.BuiltinKeys;
 import org.simantics.browsing.ui.DataSource;
 import org.simantics.browsing.ui.NodeContext;
@@ -20,6 +18,7 @@ import org.simantics.browsing.ui.PrimitiveQueryUpdater;
 import org.simantics.browsing.ui.common.viewpoints.ViewpointStub;
 import org.simantics.browsing.ui.content.Viewpoint;
 import org.simantics.browsing.ui.graph.impl.request.ParametrizedResourceQuery;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.Listener;
@@ -135,7 +134,7 @@ public abstract class LazyParametrizedViewpoint extends ViewpointStub {
        @Override
        public NodeContext[] getChildren() {
                if (children == Viewpoint.PENDING_CHILDREN) {
-                       DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+                       DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
                        if (source != null) {
                                source.schedule(graph -> graph.asyncRequest(childQuery, childQueryProcedure));
                        }
@@ -147,17 +146,11 @@ public abstract class LazyParametrizedViewpoint extends ViewpointStub {
        @Override
        public Boolean getHasChildren() {
                if (hasChildren == Viewpoint.PENDING_HAS_CHILDREN) {
-                       DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+                       DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
                        if (source != null) {
-                               source.schedule(new Consumer<ReadGraph>() {
-                                       @Override
-                                       public void accept(ReadGraph source) {
-                                               source.asyncRequest(hasChildQuery, hasChildQueryProcedure);
-                                       }
-                               });
+                               source.schedule(graph -> graph.asyncRequest(hasChildQuery, hasChildQueryProcedure));
                        }
                }
-
                return hasChildren;
        }
 
index c694ba2e88291a52661a178438e60afc2ddc17be..808193a18982d11d672a26d7984dc34f20146e06 100644 (file)
  *******************************************************************************/
 package org.simantics.browsing.ui.graph.impl;
 
-import java.util.function.Consumer;
-
 import org.simantics.browsing.ui.DataSource;
 import org.simantics.browsing.ui.NodeContext;
 import org.simantics.browsing.ui.NodeContext.PrimitiveQueryKey;
 import org.simantics.browsing.ui.PrimitiveQueryProcessor;
 import org.simantics.browsing.ui.PrimitiveQueryUpdater;
 import org.simantics.browsing.ui.graph.impl.request.ResourceQuery;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.Listener;
@@ -113,19 +112,10 @@ public abstract class LazyResourceQueryContainer<Result> implements Container<Re
 
         if (!computed) {
 
-            final DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+            final DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
             assert(source != null);
 
-            source.schedule(new Consumer<ReadGraph>() {
-
-                @Override
-                public void accept(ReadGraph source) {
-
-                    source.asyncRequest(query, procedure);
-
-                }
-
-            });
+            source.schedule(graph -> graph.asyncRequest(query, procedure));
 
         }
 
index a760c848a793d0d87fed012a684087e33930d5cb..a86a172d8911b5f530755ab900941b20e9c8e150 100644 (file)
@@ -11,8 +11,6 @@
  *******************************************************************************/
 package org.simantics.browsing.ui.graph.impl;
 
-import java.util.function.Consumer;
-
 import org.simantics.browsing.ui.BuiltinKeys;
 import org.simantics.browsing.ui.DataSource;
 import org.simantics.browsing.ui.NodeContext;
@@ -20,6 +18,7 @@ import org.simantics.browsing.ui.PrimitiveQueryUpdater;
 import org.simantics.browsing.ui.common.viewpoints.ViewpointStub;
 import org.simantics.browsing.ui.content.Viewpoint;
 import org.simantics.browsing.ui.graph.impl.request.ResourceQuery;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.Listener;
@@ -149,14 +148,9 @@ public abstract class LazyViewpoint extends ViewpointStub {
     public NodeContext[] getChildren() {
 
         if (children == Viewpoint.PENDING_CHILDREN) {
-            DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+            DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
             final Listener<NodeContext[]> childProcedure = createListener();
-            source.schedule(new Consumer<ReadGraph>() {
-                @Override
-                public void accept(ReadGraph source) {
-                    source.asyncRequest(childQuery, childProcedure);
-                }
-            });
+            source.schedule(graph -> graph.asyncRequest(childQuery, childProcedure));
         }
 
         return children;
index 68bf689138841314bf6cf043ddfabc7ab63c7ea8..d6813edbbcabb6ee91878378bfa13794713ff07e 100644 (file)
@@ -69,7 +69,7 @@ abstract public class CallbackViewpointContributionImpl extends ContributionStub
         //System.out.println("LazyViewpoint2@" + System.identityHashCode(this) + " getChildren() = " + children.length);
 
         if (children == org.simantics.browsing.ui.content.ViewpointContribution.PENDING_CONTRIBUTION) {
-            DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+            DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
             if (source != null) {
                 source.schedule(graph -> {
                     ReadRequest childQuery = new ReadRequest() {
index 4c28fae2bb460f3b1a9aca3bd36c7be09ea2c8eb..9754fc8065ac7e4a0b547cf2ef829f74d3440d7f 100644 (file)
@@ -18,6 +18,7 @@ import org.simantics.browsing.ui.DataSource;
 import org.simantics.browsing.ui.NodeContext;
 import org.simantics.browsing.ui.PrimitiveQueryUpdater;
 import org.simantics.browsing.ui.graph.impl.request.ResourceQuery;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.Listener;
@@ -43,7 +44,7 @@ public abstract class FinalCheckedStateContributionImpl {
        
        if (state == null) {
 
-            final DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+            final DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
             assert(source != null);
 
             source.schedule(graph -> {
index 6acaffa43963f941dedb5d0d187e36807dc30a66..833db059c8fc79056ada3cd495ac266a5c486a2d 100644 (file)
@@ -17,6 +17,7 @@ import org.simantics.browsing.ui.NodeContext;
 import org.simantics.browsing.ui.PrimitiveQueryUpdater;
 import org.simantics.browsing.ui.content.ImageDecorator;
 import org.simantics.browsing.ui.graph.impl.request.ResourceQuery;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.exception.PendingVariableException;
@@ -49,7 +50,7 @@ public abstract class FinalImageDecoratorContributionImpl implements ImageDecora
 
     private void request() {
 
-        final DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+        final DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
         assert(source != null);
 
         final Procedure<ImageDecorator> procedure = createProcedure();
index b4d233e0882289b59862157d11f872871376e52f..833e6ef19a76dede68f037d557d4792a4820f5aa 100644 (file)
@@ -22,6 +22,7 @@ import org.simantics.browsing.ui.NodeContext;
 import org.simantics.browsing.ui.PrimitiveQueryUpdater;
 import org.simantics.browsing.ui.content.Imager;
 import org.simantics.browsing.ui.graph.impl.request.ResourceQuery;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.exception.PendingVariableException;
@@ -107,7 +108,7 @@ public abstract class FinalImagerContributionImpl implements Imager {
 
             content = PENDING;
 
-            final DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+            final DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
             assert(source != null);
 
             final Procedure<Map<String, ImageDescriptor>> procedure = createProcedure();
index 3459990009ede231ba7259c4d8535638dd363a5c..fa1945dfff2b41e235922f667bcce31225465058 100644 (file)
@@ -17,6 +17,7 @@ import org.simantics.browsing.ui.NodeContext;
 import org.simantics.browsing.ui.PrimitiveQueryUpdater;
 import org.simantics.browsing.ui.content.LabelDecorator;
 import org.simantics.browsing.ui.graph.impl.request.ResourceQuery;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.Listener;
@@ -48,7 +49,7 @@ public abstract class FinalLabelDecoratorContributionImpl extends LabelDecorator
 
     private void request() {
 
-        final DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+        final DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
         assert(source != null);
         
         final Procedure<LabelDecorator> procedure = createProcedure();
index b283d662e76f92b3b50148ecf6e264585a9adf4b..ed56886944644b453c3d6f07d6c4a7cfc9a3337c 100644 (file)
@@ -25,6 +25,7 @@ import org.simantics.browsing.ui.common.labelers.LabelerContent;
 import org.simantics.browsing.ui.common.labelers.LabelerStub;
 import org.simantics.browsing.ui.common.node.IModifiableNode;
 import org.simantics.browsing.ui.graph.impl.request.ResourceQuery;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.UndoContext;
 import org.simantics.db.common.utils.Logger;
@@ -115,7 +116,7 @@ public abstract class FinalLabelerContributionImpl extends LabelerStub {
 
         if (content == LabelerContent.NO_CONTENT) {
 
-            final DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+            final DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
             assert(source != null);
 
             final Procedure<LabelerContent> procedure = createProcedure();
index f514fa48c9aeee4daeda1684e2c1e158f47a35cd..e1dbd4f5234b21a8e12415b86b1591ee9b58cdcf 100644 (file)
@@ -130,7 +130,7 @@ abstract public class FinalViewpointContributionImpl extends ContributionStub im
         //System.out.println("LazyViewpoint2@" + System.identityHashCode(this) + " getChildren() = " + children.length);
 
         if (children == org.simantics.browsing.ui.content.ViewpointContribution.PENDING_CONTRIBUTION) {
-            DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
+            DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
             if (source != null) {
                 source.schedule(graph -> {
                     if(childProcedure instanceof Listener<?>)
index a71fd1ba6f91552ef78794dc84faac7a21f183da..6e0a3c0b5a6f126d8bde01fb739290adf844265f 100644 (file)
@@ -24,7 +24,7 @@ final public class ForEachAssertedObject extends ResourceAsyncMultiRead2<Resourc
 
        @Override
        public void perform(AsyncReadGraph graph, AsyncMultiProcedure<Resource> procedure) {
-       graph.forEachAssertedObject(resource, resource2, procedure);
+               graph.forEachAssertedObject(resource, resource2, procedure);
        }
 
 }
index 63a5ddcb3293f2fa34f72e118d123dce341e4cc0..84e6fdc34ea10402c68b27f4ac06f31f8c61c1b0 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.common.primitiverequest;
 
-import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
-import org.simantics.db.common.request.ResourceAsyncRead2;
-import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.common.request.ResourceRead2;
+import org.simantics.db.exception.DatabaseException;
 
-final public class IsInstanceOf extends ResourceAsyncRead2<Boolean> {
+public final class IsInstanceOf extends ResourceRead2<Boolean> {
 
     public IsInstanceOf(Resource resource, Resource resource2) {
         super(resource, resource2);
     }
 
     @Override
-    public void perform(AsyncReadGraph graph, AsyncProcedure<Boolean> procedure) {
-        graph.forIsInstanceOf(resource, resource2, procedure);
+    public Boolean perform(ReadGraph graph) throws DatabaseException {
+        return graph.isInstanceOf(resource, resource2);
     }
 
 }
index 61a47ecb12a96443620f5c546b29bc2fda50813d..81d0f38958e9217bfbbe4cd7efd6c367f75b8618 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.common.primitiverequest;
 
-import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
-import org.simantics.db.procedure.AsyncProcedure;
-import org.simantics.db.request.AsyncRead;
+import org.simantics.db.adaption.AdaptionService;
+import org.simantics.db.common.request.BinaryRead;
+import org.simantics.db.exception.DatabaseException;
 
-final public class PossibleAdapter<T> implements AsyncRead<T> {
+public final class PossibleAdapter<T> extends BinaryRead<Resource,Class<T>, T> {
 
-       final private Resource resource;
-    final private Class<T> clazz;
-    
-    @Override
-    public int hashCode() {
-        return resource.hashCode() + 31 * clazz.hashCode();
-    }
-    
-    @Override
-    public boolean equals(Object object) {
-        if (this == object)
-            return true;
-        else if (object == null)
-            return false;
-        else if (getClass() != object.getClass())
-            return false;
-        PossibleAdapter<?> r = (PossibleAdapter<?>)object;
-        return resource.equals(r.resource) && clazz.equals(r.clazz);
-    }
-
-    @Override
-    public int threadHash() {
-       return hashCode();
-    }
-
-    @Override
-    public int getFlags() {
-        return 0;
-    }
-    
     public PossibleAdapter(Resource resource, Class<T> clazz) {
-        this.resource = resource;
-        this.clazz = clazz;
+        super(resource, clazz);
     }
 
     @Override
-    public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
-        
-        graph.forPossibleAdapted(resource, clazz, procedure);
-        
+    public T perform(ReadGraph graph) throws DatabaseException {
+        final AdaptionService service = graph.peekService(AdaptionService.class);
+        return service.adapt(graph, parameter, parameter, Resource.class, parameter2, true);
     }
 
 }
index 59a66aeaa7fb8ba7f61e50663c2835c68cb3d4db..5fbe501137a108910f5b375534766644e6ab0079 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -15,20 +15,24 @@ import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.RelationInfo;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.ResourceAsyncRead;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.service.DirectQuerySupport;
 
-final public class RelationInfoRequest extends ResourceAsyncRead<RelationInfo> {
+public final class RelationInfoRequest extends ResourceAsyncRead<RelationInfo> {
 
     public RelationInfoRequest(Resource resource) {
         super(resource);
     }
 
-       @Override
-       public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
-               DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
-               dqs.forRelationInfo(graph, resource, procedure);
-       }
-       
-}
-       
\ No newline at end of file
+    @Override
+    public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
+        DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
+        try {
+            procedure.execute(graph, dqs.getRelationInfo(graph, resource));
+        } catch (DatabaseException e) {
+            procedure.exception(graph, e);
+        }
+    }
+
+}      
\ No newline at end of file
index 0628507d9e6fe7789b9b8cc5dc6cf12c36fad223..19f1ec42bf5597c2c654f786adb900cc47cd43d7 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
 package org.simantics.db.common.procedure.single;
 
 import org.simantics.db.ReadGraph;
-import org.simantics.db.common.procedure.adapter.AsyncListenerSupport;
+import org.simantics.db.common.procedure.adapter.SyncListenerSupport;
 
-abstract public class SingleSetSyncListenerDelegate<T> extends SingleSetSyncListener<T> {
+public abstract class SingleSetSyncListenerDelegate<T> extends SingleSetSyncListener<T> {
     
-    final private AsyncListenerSupport support;
+    private final SyncListenerSupport support;
     
-    public SingleSetSyncListenerDelegate(AsyncListenerSupport support) {
+    public SingleSetSyncListenerDelegate(SyncListenerSupport support) {
         this.support = support;
     }
 
diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/wrapper/NoneToSyncMultiListener.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/wrapper/NoneToSyncMultiListener.java
new file mode 100644 (file)
index 0000000..9e3178e
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2018 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.common.procedure.wrapper;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.procedure.MultiListener;
+import org.simantics.db.procedure.SyncMultiListener;
+
+public class NoneToSyncMultiListener<T> implements SyncMultiListener<T> {
+
+    private final MultiListener<T> procedure;
+
+    public NoneToSyncMultiListener(MultiListener<T> procedure) {
+        this.procedure = procedure;
+    }
+
+    @Override
+    public void execute(ReadGraph graph, final T result) {
+        procedure.execute(result);
+    }
+
+    @Override
+    public void finished(ReadGraph graph) {
+        procedure.finished();
+    }
+
+    @Override
+    public void exception(ReadGraph graph, Throwable t) {
+        procedure.exception(t);
+    }
+
+    @Override
+    public boolean isDisposed() {
+        return procedure.isDisposed();
+    }
+
+    @Override
+    public String toString() {
+        return "NoneToAsyncMultiListener -> " + procedure;
+    }
+
+}
diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/wrapper/NoneToSyncMultiProcedure.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/wrapper/NoneToSyncMultiProcedure.java
new file mode 100644 (file)
index 0000000..7531f97
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2018 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.common.procedure.wrapper;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.procedure.MultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
+
+public class NoneToSyncMultiProcedure<T> implements SyncMultiProcedure<T> {
+
+    private final MultiProcedure<T> procedure;
+
+    public NoneToSyncMultiProcedure(MultiProcedure<T> procedure) {
+        this.procedure = procedure;
+    }
+
+    @Override
+    public void execute(ReadGraph graph, final T result) {
+        procedure.execute(result);
+    }
+
+    @Override
+    public void finished(ReadGraph graph) {
+        procedure.finished();
+    }
+
+    @Override
+    public void exception(ReadGraph graph, Throwable t) {
+         procedure.exception(t);
+    }
+
+    @Override
+    public String toString() {
+        return "NoneToAsyncMultiProcedure -> " + procedure;
+    }
+
+}
index bf72e041648e4d11c4e0e4b1de8506b8e8397cf2..e9523c0c899628ee03fb29a4130067131044708a 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -24,12 +24,12 @@ import java.util.function.Consumer;
 import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.AsyncRequestProcessor;
 import org.simantics.db.ReadGraph;
-import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
+import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter;
 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
 import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.common.request.WriteRequest;
@@ -64,7 +64,7 @@ import org.simantics.db.request.WriteResult;
 import org.simantics.utils.DataContainer;
 import org.simantics.utils.datastructures.Pair;
 
-public class MergingGraphRequestProcessor implements RequestProcessor {
+public class MergingGraphRequestProcessor implements AsyncRequestProcessor {
 
     private static class SyncWriteRequestAdapter implements Write {
 
@@ -264,11 +264,11 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
 
                                Logger.defaultLogError(t);
 
-                        if(currentRequest.second instanceof AsyncProcedure<?>) {
-                            ((AsyncProcedure<?>)currentRequest.second).exception(graph, t);
-                        } else {
-                            ((AsyncMultiProcedure<?>)currentRequest.second).exception(graph, t);
-                        }
+//                        if(currentRequest.second instanceof AsyncProcedure<?>) {
+//                            ((AsyncProcedure<?>)currentRequest.second).exception(graph, t);
+//                        } else {
+//                            ((AsyncMultiProcedure<?>)currentRequest.second).exception(graph, t);
+//                        }
 
                     }
 
@@ -286,25 +286,25 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
                         if(currentRequest.second instanceof AsyncProcedure<?>) {
                             if(currentRequest.first instanceof AsyncRead) {
                                 AsyncRead req = (AsyncRead)currentRequest.first;
-                                graph.asyncRequest(req, (AsyncProcedure<?>)currentRequest.second);
+                                graph.syncRequest(req, (AsyncProcedure<?>)currentRequest.second);
                             } else {
                                 Read req = (Read)currentRequest.first;
-                                graph.asyncRequest(req, (AsyncProcedure<?>)currentRequest.second);
+                                graph.syncRequest(req, (AsyncProcedure<?>)currentRequest.second);
                             }
                         } else {
                             AsyncMultiRead req = (AsyncMultiRead)currentRequest.first;
-                            graph.asyncRequest(req, (AsyncMultiProcedure<?>)currentRequest.second);
+                            graph.syncRequest(req, (AsyncMultiProcedure<?>)currentRequest.second);
                         }
 
                     } catch(Throwable t) {
 
                                Logger.defaultLogError(t);
 
-                        if(currentRequest.second instanceof AsyncProcedure<?>) {
-                            ((AsyncProcedure<?>)currentRequest.second).exception(graph, t);
-                        } else {
-                            ((AsyncMultiProcedure<?>)currentRequest.second).exception(graph, t);
-                        }
+//                        if(currentRequest.second instanceof AsyncProcedure<?>) {
+//                            ((AsyncProcedure<?>)currentRequest.second).exception(graph, t);
+//                        } else {
+//                            ((AsyncMultiProcedure<?>)currentRequest.second).exception(graph, t);
+//                        }
 
                     }
                 }
@@ -443,10 +443,10 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
 
 //        System.out.println(this + " asyncRequest(ReadGraphRequest<QueryProcedure4<T>> request, QueryProcedure4<T> procedure)");
 
-        if (requestSet.contains(request))
+        Pair<Object, Object> pair = Pair.make(request, procedure);
+        if (requestSet.contains(pair))
             return;
 
-        Pair<Object, Object> pair = new Pair<Object, Object>(request, procedure);
         requestQueue.add(pair);
         requestSet.add(pair);
 
@@ -464,10 +464,10 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
 
 //        System.out.println(this + " asyncRequest(ReadGraphRequest<SingleQueryProcedure4<T>> request, SingleQueryProcedure4<T> procedure) " + this);
 
-        if (requestSet.contains(request))
+        Pair<Object, Object> pair = Pair.make(request, procedure);
+        if (requestSet.contains(pair))
             return;
 
-        Pair<Object, Object> pair = new Pair<Object, Object>(request, procedure);
         requestQueue.add(pair);
         requestSet.add(pair);
 
@@ -486,10 +486,10 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
 
 //        System.out.println(this + " asyncRequest(WriteGraphRequest request)");
 
-        if (requestSet.contains(request))
+        Pair<Object, Object> pair = Pair.make(request, callback);
+        if (requestSet.contains(pair))
             return;
 
-        Pair<Object, Object> pair = new Pair<Object, Object>(request, callback);
         requestQueue.add(pair);
         requestSet.add(pair);
 
@@ -509,10 +509,10 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
 
 //        System.out.println(this + " asyncRequest(WriteGraphRequest request)");
 
-        if (requestSet.contains(request))
+        Pair<Object, Object> pair = Pair.make(request, callback);
+        if (requestSet.contains(pair))
             return;
 
-        Pair<Object, Object> pair = new Pair<Object, Object>(request, callback);
         requestQueue.add(pair);
         requestSet.add(pair);
 
@@ -532,10 +532,10 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
 
 //        System.out.println(this + " asyncRequest(WriteGraphRequest request)");
 
-        if (requestSet.contains(request))
+        Pair<Object, Object> pair = Pair.make(request, callback);
+        if (requestSet.contains(pair))
             return;
 
-        Pair<Object, Object> pair = new Pair<Object, Object>(request, callback);
         requestQueue.add(pair);
         requestSet.add(pair);
 
@@ -889,10 +889,10 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
     public synchronized <T> void asyncRequest(Read<T> request,
             AsyncProcedure<T> procedure) {
 
-        if (requestSet.contains(request))
+        Pair<Object, Object> pair = Pair.make(request, procedure);
+        if (requestSet.contains(pair))
             return;
 
-        Pair<Object, Object> pair = new Pair<Object, Object>(request, procedure);
         requestQueue.add(pair);
         requestSet.add(pair);
 
@@ -917,17 +917,17 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
         final ArrayList<T> result = new ArrayList<T>();
         final DataContainer<Throwable> exception = new DataContainer<Throwable>();
 
-        syncRequest(request, new AsyncMultiProcedureAdapter<T>() {
+        syncRequest(request, new SyncMultiProcedureAdapter<T>() {
 
             @Override
-            public void execute(AsyncReadGraph graph, T t) {
+            public void execute(ReadGraph graph, T t) {
                 synchronized(result) {
                     result.add(t);
                 }
             }
 
             @Override
-            public void exception(AsyncReadGraph graph, Throwable t) {
+            public void exception(ReadGraph graph, Throwable t) {
                 exception.set(t);
             }
 
@@ -947,11 +947,6 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
         return result;
     }
 
-    @Override
-    public <T> Collection<T> syncRequest(MultiRead<T> request, AsyncMultiProcedure<T> procedure)  {
-        throw new UnsupportedOperationException("Not implemented");
-    }
-
     @Override
     public <T> Collection<T> syncRequest(MultiRead<T> request, MultiProcedure<T> procedure) {
         throw new UnsupportedOperationException("Not implemented");
@@ -967,11 +962,6 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
         throw new UnsupportedOperationException("Not implemented");
     }
 
-    @Override
-    public <T> void asyncRequest(MultiRead<T> request, AsyncMultiProcedure<T> procedure) {
-        throw new UnsupportedOperationException("Not implemented");
-    }
-
     @Override
     public <T> void asyncRequest(MultiRead<T> request, MultiProcedure<T> procedure) {
         throw new UnsupportedOperationException("Not implemented");
@@ -1103,12 +1093,6 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
 
     }
 
-    @Override
-    public <T> Collection<T> syncRequest(MultiRead<T> arg0, AsyncMultiListener<T> arg1) {
-        throw new UnsupportedOperationException("Not implemented.");
-
-    }
-
     @Override
     public <T> Collection<T> syncRequest(MultiRead<T> arg0, SyncMultiListener<T> arg1) {
         throw new UnsupportedOperationException("Not implemented.");
@@ -1153,12 +1137,6 @@ public class MergingGraphRequestProcessor implements RequestProcessor {
 
     }
 
-    @Override
-    public <T> void asyncRequest(MultiRead<T> arg0, AsyncMultiListener<T> arg1) {
-        throw new UnsupportedOperationException("Not implemented.");
-
-    }
-
     @Override
     public <T> void asyncRequest(MultiRead<T> arg0, SyncMultiListener<T> arg1) {
         throw new UnsupportedOperationException("Not implemented.");
index 6e1aeabaae4d3b47a8a3624e73c2e64a366c8854..1f00ff008674e73ada990c71e297e9f01afe2f19 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -14,7 +14,7 @@ package org.simantics.db.common.processor;
 import java.util.Collection;
 import java.util.function.Consumer;
 
-import org.simantics.db.RequestProcessor;
+import org.simantics.db.AsyncRequestProcessor;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.exception.DatabaseException;
@@ -44,7 +44,7 @@ import org.simantics.db.request.WriteOnly;
 import org.simantics.db.request.WriteOnlyResult;
 import org.simantics.db.request.WriteResult;
 
-public class ProcessorBase implements RequestProcessor {
+public class ProcessorBase implements AsyncRequestProcessor {
 
     @Override
     public <T> void asyncRequest(AsyncMultiRead<T> request, AsyncMultiProcedure<T> procedure) {
@@ -173,11 +173,6 @@ public class ProcessorBase implements RequestProcessor {
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public <T> Collection<T> syncRequest(MultiRead<T> request, AsyncMultiProcedure<T> procedure)  {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public <T> Collection<T> syncRequest(MultiRead<T> request, MultiProcedure<T> procedure) {
         throw new UnsupportedOperationException();
@@ -193,11 +188,6 @@ public class ProcessorBase implements RequestProcessor {
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public <T> void asyncRequest(MultiRead<T> request, AsyncMultiProcedure<T> procedure) {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public <T> void asyncRequest(MultiRead<T> request, MultiProcedure<T> procedure) {
         throw new UnsupportedOperationException();
@@ -313,11 +303,6 @@ public class ProcessorBase implements RequestProcessor {
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public <T> Collection<T> syncRequest(MultiRead<T> arg0, AsyncMultiListener<T> arg1) {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public <T> Collection<T> syncRequest(MultiRead<T> arg0, SyncMultiListener<T> arg1) {
         throw new UnsupportedOperationException();
@@ -355,11 +340,6 @@ public class ProcessorBase implements RequestProcessor {
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public <T> void asyncRequest(MultiRead<T> arg0, AsyncMultiListener<T> arg1) {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public <T> void asyncRequest(MultiRead<T> arg0, SyncMultiListener<T> arg1) {
         throw new UnsupportedOperationException();
index 668791821c7320927fb50c3e785537bf70422783..4a6d0b19169e86f8e384fd2e430a843acbd20f95 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.common.request;
 
-import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
-import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.layer0.Layer0;
 
-public class PossibleTypedParent extends ResourceAsyncRead2<Resource> {
+public class PossibleTypedParent extends ResourceRead2<Resource> {
 
        public PossibleTypedParent(Resource resource, Resource type) {
                super(resource, type);
        }
 
        @Override
-       public void perform(AsyncReadGraph graph, final AsyncProcedure<Resource> procedure) {
-
-           final Layer0 l0 = graph.getService(Layer0.class);
-
-               graph.forIsInstanceOf(resource, resource2, new AsyncProcedure<Boolean>() {
-
-                       @Override
-                       public void execute(AsyncReadGraph graph, Boolean isInstance) {
-                               if(isInstance) {
-                                       procedure.execute(graph, resource);
-                               } else {
-                                       
-                                       graph.forPossibleObject(resource, l0.PartOf, new AsyncProcedure<Resource>() {
-
-                                               @Override
-                                               public void execute(AsyncReadGraph graph, final Resource parent) {
-
-                                                       if(parent == null) {
-                                                               procedure.execute(graph, null);
-                                                       } else {
-                                                               graph.asyncRequest(new PossibleTypedParent(parent, resource2), procedure);
-                                                       }
-                                                       
-                                               }
-
-                                               @Override
-                                               public void exception(AsyncReadGraph graph, Throwable throwable) {
-                                                       procedure.exception(graph, throwable);
-                                               }
-                                               
-                                       });
-                                       
-                               }
-                       }
-
-                       @Override
-                       public void exception(AsyncReadGraph graph, Throwable throwable) {
-                               procedure.exception(graph, throwable);
+       public Resource perform(ReadGraph graph) throws DatabaseException {
+               if (graph.isInstanceOf(resource, resource2)) {
+                       return resource;
+               } else {
+                       Layer0 L0 = Layer0.getInstance(graph);
+                       Resource possibleParent = graph.getPossibleObject(resource, L0.PartOf);
+                       if (possibleParent != null) {
+                               return graph.syncRequest(new PossibleTypedParent(possibleParent, resource2));
+                       } else {
+                               return null;
                        }
-               });
-               
-               
+               }
        }
 
 }
index 4e51a09973c47a946e14ebc127fbb912c480bd30..4d15bd5f3398cbda58f2c82537c39ef9dae8081f 100644 (file)
@@ -22,11 +22,6 @@ public abstract class ResourceAsyncMultiRead<T> implements AsyncMultiRead<T> {
     public int hashCode() {
         return resource.hashCode();
     }
-    
-    @Override
-    final public int threadHash() {
-       return resource.getThreadHash();
-    }
 
     @Override
     public boolean equals(Object object) {
index ae40ad4acc90db9e8f6240ab5edc09d675a92f77..1b13285d86ef6fd3b7872ab7bdf1cec8cea2231d 100644 (file)
@@ -23,9 +23,8 @@ import org.simantics.db.procedure.SyncListener;
 import org.simantics.db.procedure.SyncProcedure;
 import org.simantics.db.request.AsyncRead;
 import org.simantics.db.request.ReadInterface;
-import org.simantics.db.request.Request;
 
-public abstract class ResourceAsyncRead2<T> implements AsyncRead<T>, Request, ReadInterface<T> {
+public abstract class ResourceAsyncRead2<T> implements AsyncRead<T>, ReadInterface<T> {
 
     final protected Resource resource;
     final protected Resource resource2;
index f9517f7bbe0c495ba6e6ab9b32b5c2b1d6b3e8fe..7713535b50ddcf5b4366070ed644ddc5185875c6 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.common.uri;
 
-import java.util.Collection;
 import java.util.Map;
 
-import org.simantics.databoard.Bindings;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.ResourceRead;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.service.CollectionSupport;
-import org.simantics.layer0.Layer0;
-import org.simantics.utils.Development;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class UnescapedChildMapOfResource extends ResourceRead<Map<String, Resource>> {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(UnescapedChildMapOfResource.class);
-
        public UnescapedChildMapOfResource(Resource resource) {
-           super(resource);
+               super(resource);
        }
-       
+
        @Override
        public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
-           Layer0 L0 = Layer0.getInstance(graph);
-           Collection<Resource> objects = graph.getObjects(resource, L0.ConsistsOf);
-           CollectionSupport cs = graph.getService(CollectionSupport.class);
-           Map<String,Resource> result = cs.createObjectResourceMap(String.class, objects.size());
-           for(Resource r : objects) {
-               String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
-               if(name != null) {
-                   Resource old = result.put(name, r);
-                   if (old != null)
-                       LOGGER.error("The database contains siblings with the same name " + name + " (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ", previous child=$" + old.getResourceId() + ").");
-               } else {
-                       if(Development.DEVELOPMENT)
-                           LOGGER.error("The database contains a child with no unique name (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ").");
-               }
-           }
-           return result;
-       }       
-       
+               return graph.getChildren(resource);
+       }
+
 }
index 2e16b284903997a204f1c229f3a1adc83df10a96..77eacf2055e9002c86aa99da5fed5c96a3f15906 100644 (file)
@@ -234,12 +234,10 @@ public class CommonDBUtils {
                DirectStatementProcedure proc = new DirectStatementProcedure();
 
                if (ignoreVirtual) {
-                       dqs.forEachDirectPersistentStatement(graph, resource, proc);
+                       return dqs.getDirectPersistentStatements(graph, resource);
                } else {
-                       dqs.forEachDirectStatement(graph, resource, proc);
+                       return dqs.getDirectStatements(graph, resource);
                }
-               
-               return proc.getOrThrow();
 
        }
        
index eb0ca24b6a5fa32e318936dfbfe54ce5a8a42f79..143d3e443099f31c703503dfea77b1da7ea115f1 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -25,7 +25,6 @@ import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.WriteOnlyGraph;
-import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.RuntimeDatabaseException;
 import org.simantics.db.exception.ValidationException;
@@ -235,21 +234,6 @@ public class OrderedSetUtils {
         }
     }
 
-    /**
-     * Converts ordered set into a list.
-     */
-    public static void forEach(AsyncReadGraph g, final Resource l, final AsyncMultiProcedure<Resource> procedure) {
-        g.asyncRequest(new ReadRequest() {
-
-            @Override
-            public void run(ReadGraph graph) throws DatabaseException {
-                for(Resource r : toList(graph, l))
-                    procedure.execute(graph, r);
-            }
-
-        });
-    }
-
     /**
      * Creates an empty ordered set.
      */
index 9e5d563a51205fd2855400458fac64bf69111ff5..96d915482e53b91efb9f5e536d7d0e0d480a3868 100644 (file)
@@ -18,6 +18,7 @@ import java.util.function.Consumer;
 import org.simantics.databoard.accessor.Accessor;
 import org.simantics.databoard.binding.Binding;
 import org.simantics.databoard.type.Datatype;
+import org.simantics.db.AsyncRequestProcessor;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
@@ -150,11 +151,11 @@ public class Transaction {
                }
        }
        
-       public static void startTransaction(RequestProcessor processor, boolean write) throws DatabaseException {
+       public static void startTransaction(AsyncRequestProcessor processor, boolean write) throws DatabaseException {
                startTransaction(processor, write ? Type.WRITE : Type.READ);
        }
        
-       public static void startTransaction(RequestProcessor processor, Type type) throws DatabaseException {
+       public static void startTransaction(AsyncRequestProcessor processor, Type type) throws DatabaseException {
                switch (type) {
                        case READ:
                        {
diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncMultiProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncMultiProcedure.java
new file mode 100644 (file)
index 0000000..cc50ea9
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.impl;
+
+import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.procedure.AsyncMultiProcedure;
+
+public class BlockingAsyncMultiProcedure<Result> implements AsyncMultiProcedure<Result> {
+
+    private static final Object NO_RESULT = new Object();
+
+    private final Object key;
+    private final ReadGraphImpl graph;
+    private final AsyncMultiProcedure<Result> procedure;
+
+    private Object result = NO_RESULT;
+    private Throwable exception = null;
+
+    public BlockingAsyncMultiProcedure(ReadGraphImpl graph, AsyncMultiProcedure<Result> procedure, Object key) {
+        this.procedure = procedure;
+        this.key = key;
+        this.graph = ReadGraphImpl.newAsync(graph);
+        this.graph.asyncBarrier.inc();
+    }
+
+    @Override
+    public void execute(AsyncReadGraph graph, Result result) {
+        this.result = result;
+        try {
+            if(procedure != null) procedure.execute(graph, result);
+        } catch (Throwable throwable) {
+            Logger.defaultLogError("AsyncProcedure.execute threw for " + procedure, throwable);
+        }
+    }
+
+    @Override
+    public void finished(AsyncReadGraph graph) {
+        this.graph.asyncBarrier.dec();
+        try {
+            if(procedure != null) procedure.finished(graph);
+        } catch (Throwable throwable) {
+            Logger.defaultLogError("AsyncProcedure.finish threw for " + procedure, throwable);
+        }
+    }
+
+    @Override
+    public void exception(AsyncReadGraph graph, Throwable t) {
+        this.exception = t;
+        try {
+            if (procedure != null) procedure.exception(graph, t);
+        } catch (Throwable throwable) {
+            Logger.defaultLogError("AsyncProcedure.exception threw for " + procedure, throwable);
+        } finally {
+            this.graph.asyncBarrier.dec();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public Result get() throws DatabaseException {
+        graph.asyncBarrier.waitBarrier(key, graph);
+        if (exception != null) {
+            if (exception instanceof DatabaseException) throw (DatabaseException) exception;
+            throw new DatabaseException(exception);
+        } else {
+            return (Result) result;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public Result getResult() {
+        return (Result) result;
+    }
+
+    public Throwable getException() {
+        return exception;
+    }
+
+    @Override
+    public String toString() {
+        return "." + procedure; 
+    }
+
+}
diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java
new file mode 100644 (file)
index 0000000..4ae5303
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.impl;
+
+import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.procedure.AsyncProcedure;
+
+public class BlockingAsyncProcedure<Result> implements AsyncProcedure<Result> {
+
+    private static final Object NO_RESULT = new Object();
+
+    private final Object key;
+    private final ReadGraphImpl graph;
+    private final AsyncProcedure<Result> procedure;
+
+    private Object result = NO_RESULT;
+    private Throwable exception = null;
+
+    public BlockingAsyncProcedure(ReadGraphImpl graph, AsyncProcedure<Result> procedure, Object key) {
+        this.procedure = procedure;
+        this.key = key;
+        this.graph = ReadGraphImpl.newAsync(graph);
+        this.graph.asyncBarrier.inc();
+    }
+
+    @Override
+    public void execute(AsyncReadGraph graph, Result result) {
+        this.result = result;
+        this.graph.asyncBarrier.dec();
+        try {
+            if(procedure != null) procedure.execute(graph, result);
+        } catch (Throwable throwable) {
+            Logger.defaultLogError("AsyncProcedure.execute threw for " + procedure, throwable);
+        }
+    }
+
+    @Override
+    public void exception(AsyncReadGraph graph, Throwable t) {
+        this.exception = t;
+        try {
+            if(procedure != null) procedure.exception(graph, t);
+        } catch (Throwable throwable) {
+            Logger.defaultLogError("AsyncProcedure.exception threw for " + procedure, throwable);
+        } finally {
+            this.graph.asyncBarrier.dec();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public Result get() throws DatabaseException {
+
+        graph.asyncBarrier.waitBarrier(key, graph);
+
+        if(exception != null) {
+            if(exception instanceof DatabaseException) throw (DatabaseException)exception;
+            throw new DatabaseException(exception);
+        } else {
+            return (Result)result;
+        }
+
+    }
+
+    @SuppressWarnings("unchecked")
+    public Result getResult() {
+        return (Result)result;
+    }
+
+    public Throwable getException() {
+        return exception;
+    }
+
+    @Override
+    public String toString() {
+        return "." + procedure; 
+    }
+
+}
index 87acea43d4801c388154f5738b08f0b2428ed55d..a82a7490f3e1f506051b794c7cc17d3bf91fa5a1 100644 (file)
@@ -17,7 +17,7 @@ import java.util.function.Consumer;
 import org.simantics.db.Resource;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.service.ClusterUID;
 
 public interface ClusterI {
@@ -114,7 +114,7 @@ public interface ClusterI {
     public <C, T> int getSingleObject(int resourceKey, ForPossibleRelatedValueContextProcedure<C, T> procedure, ClusterSupport support)
     throws DatabaseException;
 
-    public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, AsyncMultiProcedure<Resource> procedure)
+    public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, SyncMultiProcedure<Resource> procedure)
     throws DatabaseException;
 
     public void forObjects(ReadGraphImpl graph, int resourceKey, ForEachObjectProcedure procedure)
index 188917994a26881ccafe58a313ac6cb4559c2a67..6bec3b7074b540f34f5970cd20bd73cbc113892f 100644 (file)
@@ -1,12 +1,13 @@
 package org.simantics.db.impl;
 
-import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.RelationInfo;
 import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.query.QueryProcessor;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
 
-public final class ForEachObjectContextProcedure<C> implements AsyncContextMultiProcedure<C, Resource> {
+public final class ForEachObjectContextProcedure<C> implements SyncContextMultiProcedure<C, Resource> {
 
        public final int predicateKey;
        public final int[] clusterKey;
@@ -14,9 +15,9 @@ public final class ForEachObjectContextProcedure<C> implements AsyncContextMulti
        public final RelationInfo info;
        public final QueryProcessor processor;
        public final ClusterI.CompleteTypeEnum completeType;
-       private final AsyncContextMultiProcedure<C, Resource> user;
+       private final SyncContextMultiProcedure<C, Resource> user;
        
-       public ForEachObjectContextProcedure(int predicateKey, RelationInfo info, QueryProcessor processor, AsyncContextMultiProcedure<C, Resource> user) {
+       public ForEachObjectContextProcedure(int predicateKey, RelationInfo info, QueryProcessor processor, SyncContextMultiProcedure<C, Resource> user) {
                this.predicateKey = predicateKey;
                this.completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); 
                this.info = info;
@@ -27,17 +28,17 @@ public final class ForEachObjectContextProcedure<C> implements AsyncContextMulti
        }
        
        @Override
-       public void execute(AsyncReadGraph graph, C context, Resource result) {
+       public void execute(ReadGraph graph, C context, Resource result) throws DatabaseException {
                user.execute(graph, context, result);
        }
 
        @Override
-       public void finished(AsyncReadGraph graph, C context) {
+       public void finished(ReadGraph graph, C context) throws DatabaseException {
                user.finished(graph, context);
        }
 
        @Override
-       public void exception(AsyncReadGraph graph, Throwable throwable) {
+       public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException {
                user.exception(graph, throwable);
        }
        
index 85790c4de02cbcce7b5b2d4b209a43ae6782625b..143d0a1868dc8b52be43ae91fff3b969b61a063b 100644 (file)
@@ -1,12 +1,13 @@
 package org.simantics.db.impl;
 
-import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.RelationInfo;
 import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.query.QueryProcessor;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 
-public final class ForEachObjectProcedure implements AsyncMultiProcedure<Resource> {
+public final class ForEachObjectProcedure implements SyncMultiProcedure<Resource> {
 
        public final int predicateKey;
        public final int[] clusterKey;
@@ -14,9 +15,9 @@ public final class ForEachObjectProcedure implements AsyncMultiProcedure<Resourc
        public final RelationInfo info;
        public final QueryProcessor processor;
        public final ClusterI.CompleteTypeEnum completeType;
-       private final AsyncMultiProcedure<Resource> user;
+       private final SyncMultiProcedure<Resource> user;
        
-       public ForEachObjectProcedure(int predicateKey, RelationInfo info, QueryProcessor processor, AsyncMultiProcedure<Resource> user) {
+       public ForEachObjectProcedure(int predicateKey, RelationInfo info, QueryProcessor processor, SyncMultiProcedure<Resource> user) {
                this.predicateKey = predicateKey;
                this.completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); 
                this.info = info;
@@ -27,17 +28,17 @@ public final class ForEachObjectProcedure implements AsyncMultiProcedure<Resourc
        }
        
        @Override
-       public void execute(AsyncReadGraph graph, Resource result) {
+       public void execute(ReadGraph graph, Resource result) throws DatabaseException {
                user.execute(graph, result);
        }
 
        @Override
-       public void finished(AsyncReadGraph graph) {
+       public void finished(ReadGraph graph) throws DatabaseException {
                user.finished(graph);
        }
 
        @Override
-       public void exception(AsyncReadGraph graph, Throwable throwable) {
+       public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException {
                user.exception(graph, throwable);
        }
        
index 0225656d5b9f3a7a584ea5811a65a8df6c4be0a9..d16853cdcbf1c380e7395201bef87a548eeee545 100644 (file)
@@ -1,19 +1,19 @@
 package org.simantics.db.impl;
 
-import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.RelationInfo;
-import org.simantics.db.procedure.AsyncContextProcedure;
+import org.simantics.db.procedure.SyncContextProcedure;
 
-public final class ForPossibleRelatedValueContextProcedure<C, T> implements AsyncContextProcedure<C, T> {
+public final class ForPossibleRelatedValueContextProcedure<C, T> implements SyncContextProcedure<C, T> {
 
        public final int predicateKey;
        public final int[] clusterKey;
        public final int[] predicateReference;
        public final RelationInfo info;
        public final ClusterI.CompleteTypeEnum completeType;
-       private final AsyncContextProcedure<C, T> user;
+       private final SyncContextProcedure<C, T> user;
        
-       public ForPossibleRelatedValueContextProcedure(int predicateKey, RelationInfo info, AsyncContextProcedure<C, T> user) {
+       public ForPossibleRelatedValueContextProcedure(int predicateKey, RelationInfo info, SyncContextProcedure<C, T> user) {
                this.predicateKey = predicateKey;
                this.completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); 
                this.info = info;
@@ -23,12 +23,12 @@ public final class ForPossibleRelatedValueContextProcedure<C, T> implements Asyn
        }
        
        @Override
-       public void execute(AsyncReadGraph graph, C context, T result) {
+       public void execute(ReadGraph graph, C context, T result) {
                user.execute(graph, context, result);
        }
 
        @Override
-       public void exception(AsyncReadGraph graph, Throwable throwable) {
+       public void exception(ReadGraph graph, Throwable throwable) {
                user.exception(graph, throwable);
        }
        
index 6dcb0ea104b30da2fb7442b1ab31495f47029267..bd5e0ccaaac3f81716731f5035f2c8d6ebebbc45 100644 (file)
@@ -1,19 +1,20 @@
 package org.simantics.db.impl;
 
-import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.RelationInfo;
-import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.SyncProcedure;
 
-public final class ForPossibleRelatedValueProcedure<T> implements AsyncProcedure<T> {
+public final class ForPossibleRelatedValueProcedure<T> implements SyncProcedure<T> {
 
        public final int predicateKey;
        public final int[] clusterKey;
        public final int[] predicateReference;
        public final RelationInfo info;
        public final ClusterI.CompleteTypeEnum completeType;
-       private final AsyncProcedure<T> user;
+       private final SyncProcedure<T> user;
        
-       public ForPossibleRelatedValueProcedure(int predicateKey, RelationInfo info, AsyncProcedure<T> user) {
+       public ForPossibleRelatedValueProcedure(int predicateKey, RelationInfo info, SyncProcedure<T> user) {
                this.predicateKey = predicateKey;
                this.completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); 
                this.info = info;
@@ -23,12 +24,12 @@ public final class ForPossibleRelatedValueProcedure<T> implements AsyncProcedure
        }
        
        @Override
-       public void execute(AsyncReadGraph graph, T result) {
+       public void execute(ReadGraph graph, T result) throws DatabaseException {
                user.execute(graph, result);
        }
 
        @Override
-       public void exception(AsyncReadGraph graph, Throwable throwable) {
+       public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException {
                user.exception(graph, throwable);
        }
        
index f4e722fe5adea864496e4a7864197ae7fb6e877d..f48a64e58f754d004ea881cdc9eec8516d40f965 100644 (file)
@@ -28,7 +28,6 @@ import org.simantics.databoard.serialization.Serializer;
 import org.simantics.databoard.serialization.SerializerConstructionException;
 import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.AsyncRequestProcessor;
-import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
 import org.simantics.db.Statement;
 import org.simantics.db.VirtualGraphContext;
@@ -423,7 +422,7 @@ public class TransientGraph implements VirtualGraphImpl, VirtualGraphContext {
     final private SerialisationSupport serialization;
     final private ResourceSupport resourceSupport;
     final private VirtualGraphServerSupport virtualGraphServerSupport;
-    final private RequestProcessor sessionRequestProcessor;
+    final private AsyncRequestProcessor sessionRequestProcessor;
     
     /*
      * Cluster array by index.
@@ -446,17 +445,17 @@ public class TransientGraph implements VirtualGraphImpl, VirtualGraphContext {
 
     int[] EMPTY = new int[0];
 
-    public static TransientGraph workspacePersistent(SerialisationSupport ss, VirtualGraphServerSupport vgss, ResourceSupport rs, RequestProcessor srp, String databaseId, String identifier) throws DatabaseException {
+    public static TransientGraph workspacePersistent(SerialisationSupport ss, VirtualGraphServerSupport vgss, ResourceSupport rs, AsyncRequestProcessor srp, String databaseId, String identifier) throws DatabaseException {
         TransientGraph graph = new TransientGraph(ss, vgss, rs, srp, databaseId, identifier, Persistency.WORKSPACE);
         graph.load();
         return graph;
     }
     
-    public static TransientGraph memoryPersistent(SerialisationSupport ss, VirtualGraphServerSupport vgss, ResourceSupport rs, RequestProcessor srp, String databaseId, String identifier) {
+    public static TransientGraph memoryPersistent(SerialisationSupport ss, VirtualGraphServerSupport vgss, ResourceSupport rs, AsyncRequestProcessor srp, String databaseId, String identifier) {
         return new TransientGraph(ss, vgss, rs, srp, databaseId, identifier, Persistency.MEMORY);
     }
     
-    private TransientGraph(SerialisationSupport ss, VirtualGraphServerSupport vgss, ResourceSupport rs, RequestProcessor srp, String databaseId, String identifier, Persistency persistency) {
+    private TransientGraph(SerialisationSupport ss, VirtualGraphServerSupport vgss, ResourceSupport rs, AsyncRequestProcessor srp, String databaseId, String identifier, Persistency persistency) {
         this.serialization = ss;
         this.virtualGraphServerSupport = vgss;
         this.sessionRequestProcessor = srp;
index 7184acbc5242de4029abe6606eb806e37f424193..229c3d6a9e965b5b14167896334c2e83b1b2508a 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -20,8 +20,6 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.simantics.db.common.utils.Logger;
 import org.simantics.db.exception.RuntimeDatabaseException;
 import org.simantics.db.impl.query.QueryProcessor.AsyncBarrier;
-import org.simantics.db.impl.query.QueryProcessor.SessionTask;
-import org.simantics.utils.Development;
 
 final public class AsyncBarrierImpl extends AtomicInteger implements AsyncBarrier {
 
@@ -39,6 +37,8 @@ final public class AsyncBarrierImpl extends AtomicInteger implements AsyncBarrie
 
        final private AsyncBarrierImpl caller;
 
+       //private final Semaphore sema = new Semaphore(0);
+
        public AsyncBarrierImpl(AsyncBarrierImpl caller) {
                super(0);
                if (BOOKKEEPING) {
@@ -294,7 +294,7 @@ final public class AsyncBarrierImpl extends AtomicInteger implements AsyncBarrie
 
                        while (get() != 0) {
 
-                               boolean executed = impl.processor.resume(impl);
+                               boolean executed = impl.performPending();
                                if(executed) waitCount = 0;
                                
                                ++waitCount;
@@ -321,18 +321,16 @@ final public class AsyncBarrierImpl extends AtomicInteger implements AsyncBarrie
 
                                        }
 
-                                       if(Development.DEVELOPMENT) {
-
-                                               impl.processor.threadLocks[0].lock();
-                                               System.err.println("-queues=" + impl.processor.queues[0].size());
-                                               impl.processor.threadLocks[0].unlock();
-                                               System.err.println("-own=" + impl.processor.ownTasks[0].size());
-                                               System.err.println("-ownSync=" + impl.processor.ownSyncTasks[0].size());
-                                               for(SessionTask task : impl.processor.ownSyncTasks[0]) {
-                                                       System.err.println("--" + task);
-                                               }
-
-                                       }
+//                                     if(Development.DEVELOPMENT) {
+//                                             impl.processor.threadLocks[0].lock();
+//                                             System.err.println("-queues=" + impl.processor.queues[0].size());
+//                                             impl.processor.threadLocks[0].unlock();
+//                                             System.err.println("-own=" + impl.processor.ownTasks[0].size());
+//                                             System.err.println("-ownSync=" + impl.processor.ownSyncTasks[0].size());
+//                                             for(SessionTask task : impl.processor.ownSyncTasks[0]) {
+//                                                     System.err.println("--" + task);
+//                                             }
+//                                     }
 
                                        throw new RuntimeDatabaseException("Request timed out.");
                                        //waitCount = 0;
index 4695b8b338c02b7a87e85c8985f83a20e54c301a..0f0ad8319413c997e2f932d70ffb4d7eb925f98f 100644 (file)
@@ -4,15 +4,15 @@ import org.simantics.db.Resource;
 import org.simantics.db.common.utils.Logger;
 import org.simantics.db.impl.query.IntProcedure;
 import org.simantics.db.impl.query.QuerySupport;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 
 public class MultiIntProcedure implements IntProcedure {
 
-       final private AsyncMultiProcedure<Resource> procedure;
+       final private SyncMultiProcedure<Resource> procedure;
        final private ReadGraphImpl impl;
        final private QuerySupport support;
        
-       public MultiIntProcedure(AsyncMultiProcedure<Resource> procedure, ReadGraphImpl impl, QuerySupport support) {
+       public MultiIntProcedure(SyncMultiProcedure<Resource> procedure, ReadGraphImpl impl, QuerySupport support) {
                this.procedure = procedure;
                this.impl = impl;
                this.support = support;
index 614a96df3c47d29ea45e249dfb10df9653aaedf4..b5da0b92f7bae6521487e2fa0907ca2b96a3c09b 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -26,6 +26,7 @@ import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Map;
 import java.util.Set;
 import java.util.function.Consumer;
 
@@ -89,6 +90,7 @@ import org.simantics.db.common.primitiverequest.ValueImplied;
 import org.simantics.db.common.primitiverequest.VariantValueImplied;
 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
+import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter;
 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
 import org.simantics.db.common.procedure.single.SyncReadProcedure;
@@ -104,6 +106,8 @@ import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiListener;
 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiProcedure;
 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
 import org.simantics.db.common.procedure.wrapper.NoneToAsyncSetProcedure;
+import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiListener;
+import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiProcedure;
 import org.simantics.db.common.procedure.wrapper.SyncToAsyncListener;
 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiListener;
 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiProcedure;
@@ -129,15 +133,17 @@ import org.simantics.db.exception.NoSingleResultException;
 import org.simantics.db.exception.ResourceNotFoundException;
 import org.simantics.db.exception.ServiceException;
 import org.simantics.db.exception.ValidationException;
+import org.simantics.db.impl.BlockingAsyncProcedure;
 import org.simantics.db.impl.RelationContextImpl;
 import org.simantics.db.impl.ResourceImpl;
 import org.simantics.db.impl.internal.RandomAccessValueSupport;
 import org.simantics.db.impl.internal.ResourceData;
-import org.simantics.db.impl.procedure.CallWrappedSingleQueryProcedure4;
-import org.simantics.db.impl.procedure.ResultCallWrappedQueryProcedure4;
-import org.simantics.db.impl.procedure.ResultCallWrappedSingleQueryProcedure4;
+import org.simantics.db.impl.procedure.ResultCallWrappedSyncQueryProcedure;
 import org.simantics.db.impl.query.CacheEntry;
+import org.simantics.db.impl.query.QueryCache;
+import org.simantics.db.impl.query.QueryCacheBase;
 import org.simantics.db.impl.query.QueryProcessor;
+import org.simantics.db.impl.query.QueryProcessor.SessionTask;
 import org.simantics.db.impl.query.QuerySupport;
 import org.simantics.db.impl.query.TripleIntProcedure;
 import org.simantics.db.impl.support.ResourceSupport;
@@ -166,7 +172,6 @@ import org.simantics.db.request.ExternalRead;
 import org.simantics.db.request.MultiRead;
 import org.simantics.db.request.Read;
 import org.simantics.db.request.ReadInterface;
-import org.simantics.db.request.RequestFlags;
 import org.simantics.db.request.Write;
 import org.simantics.db.request.WriteInterface;
 import org.simantics.db.request.WriteOnly;
@@ -182,16 +187,21 @@ import org.simantics.utils.DataContainer;
 import org.simantics.utils.Development;
 import org.simantics.utils.datastructures.Pair;
 import org.simantics.utils.datastructures.collections.CollectionUtils;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.map.hash.TObjectIntHashMap;
 
-public class ReadGraphImpl implements ReadGraph {
+public class ReadGraphImpl implements AsyncReadGraph {
+
+    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ReadGraphImpl.class);
 
     final static boolean EMPTY_RESOURCE_CHECK = false;
     
        final public CacheEntry parent;
        final public QueryProcessor processor;
        
+       public AsyncBarrierImpl asyncBarrier = null;
+       
        final static Binding DATA_TYPE_BINDING_INTERNAL = Bindings.getBindingUnchecked(Datatype.class);
        final static Serializer DATA_TYPE_SERIALIZER = Bindings.getSerializerUnchecked(DATA_TYPE_BINDING_INTERNAL);
 
@@ -278,8 +288,10 @@ public class ReadGraphImpl implements ReadGraph {
 
                try {
 
-                       return syncRequest(new org.simantics.db.common.primitiverequest.Resource(
-                                       id));
+                       Integer rid = QueryCache.resultURIToResource(this, id, parent, null);
+                       // FIXME: stupid to throw this here and catch and wrap it right away
+                       if(rid == 0) throw new ResourceNotFoundException(id);
+                       return processor.querySupport.getResource(rid);
 
                } catch (ResourceNotFoundException e) {
 
@@ -309,8 +321,7 @@ public class ReadGraphImpl implements ReadGraph {
 
                try {
 
-                       return syncRequest(new org.simantics.db.common.primitiverequest.Resource(
-                                       id));
+                       return getResource(id);
 
                } catch (ResourceNotFoundException e) {
                        
@@ -331,6 +342,32 @@ public class ReadGraphImpl implements ReadGraph {
                }
 
        }
+       
+       @Override
+       public Map<String, Resource> getChildren(Resource resource) throws ValidationException, ServiceException {
+               
+               assert (resource != null);
+
+               try {
+
+                       int rId = processor.querySupport.getId(resource);
+                       return QueryCache.resultChildMap(this, rId, parent, null);
+
+               } catch (ValidationException e) {
+
+                       throw new ValidationException(e);
+
+               } catch (ServiceException e) {
+
+                       throw new ServiceException(e);
+
+               } catch (DatabaseException e) {
+
+                       throw new ServiceException(INTERNAL_ERROR_STRING, e);
+
+               }
+               
+       }
 
        final public Resource getRootLibrary() {
                return processor.getRootLibraryResource();
@@ -1896,36 +1933,8 @@ public class ReadGraphImpl implements ReadGraph {
 
                assert (request != null);
 
-               if (parent != null) {
-
-                       try {
-                               return processor.queryRead(this, request, parent, null, null);
-                       } catch (Throwable e) {
-                               if(e instanceof DatabaseException) throw (DatabaseException)e;
-                               else throw new DatabaseException(e);
-                       }
-
-               } else {
-
-                       try {
-
-                               return processor.tryQuery(this, request);
+               return QueryCache.resultReadEntry(this, request, parent, null, null);
 
-                       } catch (Throwable throwable) {
-
-                               //Logger.defaultLogError("Internal read request failure", throwable);
-
-                               if (throwable instanceof DatabaseException)
-                                       throw (DatabaseException) throwable;
-                               else
-                                       throw new DatabaseException(
-                                                       "Unexpected exception in ReadGraph.syncRequest(Read,Procedure)",
-                                                       throwable);
-
-                       }
-
-               }
-               
        }
 
        @Override
@@ -1947,42 +1956,7 @@ public class ReadGraphImpl implements ReadGraph {
 
                ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
 
-               if (parent != null || listener != null) {
-                       
-                       try {
-                return processor.queryRead(this, request, parent, procedure, listener);
-            } catch (Throwable e) {
-                if(e instanceof DatabaseException) throw (DatabaseException)e;
-                else throw new DatabaseException(e);
-            }
-
-               } else {
-
-                       try {
-
-                               T t = processor.tryQuery(this, request);
-                               if(procedure != null)
-                                       procedure.execute(this, t);
-
-                               return t;
-
-                       } catch (Throwable throwable) {
-
-                               Logger.defaultLogError("Internal read request failure", throwable);
-
-                               if(procedure != null)
-                                       procedure.exception(this, throwable);
-                               
-                               if (throwable instanceof DatabaseException)
-                                       throw (DatabaseException) throwable;
-                               else
-                                       throw new DatabaseException(
-                                                       "Unexpected exception in ReadGraph.syncRequest(Read,Procedure)",
-                                                       throwable);
-
-                       }
-
-               }
+               return QueryCache.resultReadEntry(this, request, parent, listener, procedure);
 
        }
 
@@ -2022,7 +1996,7 @@ public class ReadGraphImpl implements ReadGraph {
                                        throw (DatabaseException) exception;
                                else
                                        throw new DatabaseException(
-                                                       "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
+                                                       "Unexpected exception in ReadGraph.syncRequest(AsyncRead)",
                                                        exception);
                        }
                }
@@ -2038,12 +2012,10 @@ public class ReadGraphImpl implements ReadGraph {
                        throws DatabaseException {
 
                assert (request != null);
-               AsyncReadProcedure<T> procedure = new AsyncReadProcedure<T>();
-               syncRequest(request, procedure);
-               procedure.checkAndThrow();
-               return procedure.result;
-               
-//             return syncRequest(request, new AsyncProcedureAdapter<T>());
+               asyncBarrier = new AsyncBarrierImpl(null);
+               BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, null, request);
+               syncRequest(request, ap);
+               return ap.get();
 
        }
 
@@ -2071,71 +2043,13 @@ public class ReadGraphImpl implements ReadGraph {
 
                assert (request != null);
 
-               // System.out.println("syncRequest " + request + " syncParent=" +
-               // syncParent);
-
                ListenerBase listener = getListenerBase(procedure);
 
-               if (parent != null || listener != null || ((request.getFlags() & RequestFlags.SCHEDULE) > 0)) {
-
-//                     Object syncParent = request;
-
-//                     final ReadGraphImpl newGraph = newSync();
-
-                       final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
-                                       procedure, request);
-                       
-                       processor.query(this, request, parent, wrapper, listener);
-
-//                     newGraph.waitAsync(syncParent);
-                       
-                       Throwable e = wrapper.getException();
-                       if (e != null) {
-                               // The request was async - produce meaningful stack trace by
-                               // wrapping
-                               if (e instanceof DatabaseException)
-                                       throw (DatabaseException) e;
-                               else
-                                       throw new DatabaseException(e);
-                       }
-                       
-                       return wrapper.getResult();
-
-               } else {
-
-                       // System.out.println("direct call " + request );
-
-                       // Do not set the sync state.parent for external threads
-//                     Object syncParent = request;
-
-//                     final ReadGraphImpl newGraph = newSync();
-
-                       final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
-                                       procedure, request);
-
-                       try {
-
-                               processor.tryQuery(this, request, wrapper);
-
-                       } catch (Throwable t) {
-
-                               wrapper.exception(this, t);
-
-                       }
+               BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
 
-                       Throwable e = wrapper.getException();
-                       if (e != null) {
-                               // The request was async - produce meaningful stack trace by
-                               // wrapping
-                               if (e instanceof DatabaseException)
-                                       throw (DatabaseException) e;
-                               else
-                                       throw new DatabaseException(e);
-                       }
-                       
-                       return wrapper.getResult();
+               QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true);
 
-               }
+               return ap.get();
 
        }
 
@@ -2143,40 +2057,14 @@ public class ReadGraphImpl implements ReadGraph {
 
                assert (request != null);
 
-               // System.out.println("syncRequest " + request + " syncParent=" +
-               // syncParent);
-
                ListenerBase listener = getListenerBase(procedure);
+               assert(listener == null);
 
-               if (parent != null || listener != null || ((request.getFlags() & RequestFlags.SCHEDULE) > 0)) {
+               BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
 
-//                     final ReadGraphImpl newGraph = newSync();
-
-                       final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
-                                       procedure, request);
+               QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true);
 
-                       processor.query(this, request, parent, wrapper, listener);
-
-               } else {
-
-                       try {
-
-//                             final ReadGraphImpl newGraph = newSync();
-                               processor.tryQuery(this, request, procedure);
-//                             newGraph.waitAsync(null);
-                               waitAsyncProcedure(procedure);
-
-                       } catch (Throwable t) {
-                               if(Development.DEVELOPMENT) {
-                                       if(Development.<Boolean>getProperty(DevelopmentKeys.WRITEGRAPH_EXCEPTION_STACKTRACES, Bindings.BOOLEAN)) {
-                                       t.printStackTrace();
-                                       }
-                               }
-                               procedure.exception(this, t);
-                               waitAsyncProcedure(procedure);
-                       }
-
-               }
+               ap.get();
 
        }
 
@@ -2201,21 +2089,21 @@ public class ReadGraphImpl implements ReadGraph {
                final ArrayList<T> result = new ArrayList<T>();
                final DataContainer<Throwable> exception = new DataContainer<Throwable>();
 
-               syncRequest(request, new AsyncMultiProcedure<T>() {
+               syncRequest(request, new SyncMultiProcedure<T>() {
 
                        @Override
-                       public void execute(AsyncReadGraph graph, T t) {
+                       public void execute(ReadGraph graph, T t) {
                                synchronized (result) {
                                        result.add(t);
                                }
                        }
 
                        @Override
-                       public void finished(AsyncReadGraph graph) {
+                       public void finished(ReadGraph graph) {
                        }
 
                        @Override
-                       public void exception(AsyncReadGraph graph, Throwable t) {
+                       public void exception(ReadGraph graph, Throwable t) {
                                exception.set(t);
                        }
 
@@ -2240,39 +2128,35 @@ public class ReadGraphImpl implements ReadGraph {
 
        }
 
-       @Override
-       public <T> Collection<T> syncRequest(MultiRead<T> request,
-                       AsyncMultiListener<T> procedure) {
-               return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
-       }
-
        @Override
        public <T> Collection<T> syncRequest(MultiRead<T> request,
                        SyncMultiListener<T> procedure) {
-               return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
+               return syncRequest(request, (SyncMultiProcedure<T>)procedure);
        }
 
        @Override
        public <T> Collection<T> syncRequest(MultiRead<T> request,
                        MultiListener<T> procedure) {
-               return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
+               return syncRequest(request, new NoneToSyncMultiListener<T>(procedure));
        }
 
        @Override
        public <T> Collection<T> syncRequest(MultiRead<T> request,
-                       AsyncMultiProcedure<T> procedure) {
+                       SyncMultiProcedure<T> procedure) {
 
                assert (request != null);
 
                ListenerBase listener = getListenerBase(procedure);
 
+               final ResultCallWrappedSyncQueryProcedure<T> wrapper = new ResultCallWrappedSyncQueryProcedure<T>(procedure);
+
                if (parent != null || listener != null) {
 
 //                     Object syncParent = request;
 
 //                     final ReadGraphImpl newGraph = newSync();
 
-                       processor.query(this, request, parent, procedure, listener);
+                       processor.query(this, request, parent, wrapper, listener);
 
 //                     newGraph.waitAsync(syncParent);
 
@@ -2282,36 +2166,22 @@ public class ReadGraphImpl implements ReadGraph {
 
 //                     final ReadGraphImpl newGraph = newSync();
 
-                       final ResultCallWrappedQueryProcedure4<T> wrapper = new ResultCallWrappedQueryProcedure4<T>(procedure);
-
                        try {
-
                                request.perform(this, wrapper);
-
                        } catch (Throwable t) {
-
                                wrapper.exception(this, t);
-//                             newGraph.waitAsync(syncParent);
-
                        }
 
                }
 
-               // TODO
-               return null;
-
-       }
+               return wrapper.get();
 
-       @Override
-       public <T> Collection<T> syncRequest(MultiRead<T> request,
-                       SyncMultiProcedure<T> procedure) {
-               return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
        }
 
        @Override
        public <T> Collection<T> syncRequest(MultiRead<T> request,
                        MultiProcedure<T> procedure) {
-               return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
+               return syncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
        }
 
        static class AsyncMultiReadProcedure<T> extends ArrayList<T> implements AsyncMultiProcedure<T> {
@@ -2542,70 +2412,10 @@ public class ReadGraphImpl implements ReadGraph {
        final public <T> T syncRequest(final ExternalRead<T> request,
                        final Procedure<T> procedure) throws DatabaseException {
 
-               assert (request != null);
-
-               ListenerBase listener = getListenerBase(procedure);
-
-               final DataContainer<Throwable> exception = new DataContainer<Throwable>();
-               final DataContainer<T> result = new DataContainer<T>();
-
-               if (parent != null || listener != null) {
-
-//                     final ReadGraphImpl newGraph = newSync();
-                       
-                       processor.query(this, request, parent, new Procedure<T>() {
-
-                               @Override
-                               public void exception(Throwable throwable) {
-                                       exception.set(throwable);
-                                       procedure.exception(throwable);
-                               }
-
-                               @Override
-                               public void execute(T t) {
-                                       result.set(t);
-                                       procedure.execute(t);
-                               }
-
-                       }, listener);
-
-//                     newGraph.waitAsync(request);
-
-               } else {
-
-                       try {
-
-                               T t = processor.tryQuery(this, request);
-                               result.set(t);
-                               procedure.execute(t);
-
-                       } catch (Throwable t) {
-
-                           if (t instanceof DatabaseException) {
-                               exception.set((DatabaseException)t);
-                               procedure.exception(exception.get());
-                           } else {
-                               exception.set(new DatabaseException(
-                                       "Unexpected exception in ReadGraph.syncRequest(Read)",
-                                       t));
-                               procedure.exception(exception.get());
-                           }
-
-                       }
-
-               }
-
-               Throwable t = exception.get();
-               if (t != null) {
-                       if (t instanceof DatabaseException)
-                               throw (DatabaseException) t;
-                       else
-                               throw new DatabaseException(
-                                               "Unexpected exception in ReadGraph.syncRequest(Read)",
-                                               t);
-               }
+        assert (request != null);
 
-               return result.get();            
+        ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
+        return QueryCache.resultExternalReadEntry(this, request, parent, listener, procedure);
 
        }
 
@@ -3252,42 +3062,19 @@ public class ReadGraphImpl implements ReadGraph {
 
        }
 
-//     @Override
-//     final public void forEachDirectObject(final Resource subject,
-//                     final Resource relation,
-//                     final AsyncMultiProcedure<Resource> procedure) {
-//
-//             processor.forEachDirectObject(this, subject, relation, procedure);
-//
-//     }
-//
-//     @Override
-//     public void forEachDirectObject(Resource subject, Resource relation,
-//                     SyncMultiProcedure<Resource> procedure) {
-//             forEachDirectObject(subject, relation,
-//                             new SyncToAsyncMultiProcedure<Resource>(procedure));
-//     }
-//
-//     @Override
-//     public void forEachDirectObject(Resource subject, Resource relation,
-//                     MultiProcedure<Resource> procedure) {
-//             forEachDirectObject(subject, relation,
-//                             new NoneToAsyncMultiProcedure<Resource>(procedure));
-//     }
-       
        @Override
-       final public void forEachDirectPredicate(final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
+       final public void forEachDirectPredicate(final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
                processor.forEachDirectPredicate(this, subject, procedure);
        }
 
        @Override
-       public void forEachDirectPredicate(Resource subject, SyncMultiProcedure<Resource> procedure) {
-               forEachDirectPredicate(subject, new SyncToAsyncMultiProcedure<Resource>(procedure));
+       final public void forEachDirectPredicate(final Resource subject, final SyncProcedure<Set<Resource>> procedure) {
+               forEachDirectPredicate(subject, new SyncToAsyncProcedure<Set<Resource>>(procedure));
        }
 
        @Override
-       public void forEachDirectPredicate(Resource subject, MultiProcedure<Resource> procedure) {
-               forEachDirectPredicate(subject, new NoneToAsyncMultiProcedure<Resource>(procedure));
+       public void forEachDirectPredicate(Resource subject, Procedure<Set<Resource>> procedure) {
+               forEachDirectPredicate(subject, new NoneToAsyncProcedure<Set<Resource>>(procedure));
        }
 
        @Override
@@ -4655,14 +4442,6 @@ public class ReadGraphImpl implements ReadGraph {
                                listener);
        }
 
-//     @Override
-//     final public <T> void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding,
-//                     final AsyncProcedure<T> procedure) {
-//             
-//             forPossibleRelatedValue(subject, relation, binding, procedure, false);
-//             
-//     }
-
        final public <T> void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding,
                        final AsyncProcedure<T> procedure) {
 
@@ -5351,11 +5130,6 @@ public class ReadGraphImpl implements ReadGraph {
                return processor.getSession();
        }
 
-//     @Override
-//     final public Builtins getBuiltins() {
-//             return processor.getSession().getBuiltins();
-//     }
-
        @Override
        public <T> void asyncRequest(final Read<T> request) {
 
@@ -5400,46 +5174,20 @@ public class ReadGraphImpl implements ReadGraph {
 
                assert (request != null);
                assert (procedure != null);
+       
+               processor.schedule(new SessionTask(false) {
 
-               final ListenerBase listener = getListenerBase(procedure);
-
-               if (parent != null || listener != null) {
-
-                       try {
-                               processor.queryRead(this, request, parent, procedure,
-                                               listener);
-                       } catch (Throwable e) {
-                               // This throwable has already been transferred to procedure at this point - do nothing about it
-                               //Logger.defaultLogError("Internal error ", e);
-                       }
-                       
-               } else {
-
-//                     final ReadGraphImpl newGraph = newSync();
-
-                       try {
-
-                               T result = request.perform(this);
-                               
-                               try {
-                                       procedure.execute(this, result);
-                               } catch (Throwable t) {
-                                       Logger.defaultLogError(t);
-                               }
-
-                       } catch (Throwable t) {
-
+                       @Override
+                       public void run(int thread) {
                                try {
-                                       procedure.exception(this, t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
+                                       final ListenerBase listener = getListenerBase(procedure);
+                                       QueryCache.runnerReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false);
+                               } catch (DatabaseException e) {
+                                       Logger.defaultLogError(e);
                                }
-
-                       } finally {
-
                        }
-
-               }
+                       
+               });
 
        }
 
@@ -5447,10 +5195,6 @@ public class ReadGraphImpl implements ReadGraph {
         return new ReadGraphImpl(null, support);
     }
 
-    public static ReadGraphImpl forRecompute(CacheEntry entry, QueryProcessor support) {
-        return new ReadGraphImpl(entry, support);       
-    }
-
        @Override
        public <T> void asyncRequest(Read<T> request, SyncProcedure<T> procedure) {
                asyncRequest(request, new SyncToAsyncProcedure<T>(procedure));
@@ -5511,33 +5255,19 @@ public class ReadGraphImpl implements ReadGraph {
                assert (request != null);
                assert (procedure != null);
 
-               final ListenerBase listener = getListenerBase(procedure);
-
-               if (parent != null || listener != null) {
-
-                       processor.query(this, request, parent, procedure, listener);
-
-               } else {
-
-                       try {
-                               
-                               request.perform(this, new CallWrappedSingleQueryProcedure4<T>(procedure, request));
-
-                       } catch (Throwable t) {
-
-                               if (t instanceof DatabaseException)
-                                       procedure.exception(this, t);
-                               else
-                                       procedure
-                                                       .exception(
-                                                                       this,
-                                                                       new DatabaseException(
-                                                                                       "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)",
-                                                                                       t));
+               processor.schedule(new SessionTask(false) {
 
+                       @Override
+                       public void run(int thread) {
+                               try {
+                                       final ListenerBase listener = getListenerBase(procedure);
+                                       QueryCache.runnerAsyncReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false);
+                               } catch (DatabaseException e) {
+                                       Logger.defaultLogError(e);
+                               }
                        }
-
-               }
+                       
+               });
 
        }
 
@@ -5558,9 +5288,9 @@ public class ReadGraphImpl implements ReadGraph {
 
                assert (request != null);
 
-               asyncRequest(request, new AsyncMultiProcedureAdapter<T>() {
+               asyncRequest(request, new SyncMultiProcedureAdapter<T>() {
                        @Override
-                       public void exception(AsyncReadGraph graph, Throwable t) {
+                       public void exception(ReadGraph graph, Throwable t) {
                        Logger.defaultLogError(t);
                        }
 
@@ -5572,27 +5302,22 @@ public class ReadGraphImpl implements ReadGraph {
 
        }
 
-       @Override
-       public <T> void asyncRequest(MultiRead<T> request,
-                       AsyncMultiListener<T> procedure) {
-               asyncRequest(request, (AsyncMultiProcedure<T>) procedure);
-       }
-
        @Override
        public <T> void asyncRequest(MultiRead<T> request,
                        SyncMultiListener<T> procedure) {
-               asyncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
+               asyncRequest(request, (SyncMultiProcedure<T>)procedure);
        }
 
        @Override
        public <T> void asyncRequest(MultiRead<T> request,
                        MultiListener<T> procedure) {
-               asyncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
+               asyncRequest(request, new NoneToSyncMultiListener<T>(procedure));
        }
 
+       
        @Override
        public <T> void asyncRequest(final MultiRead<T> request,
-                       final AsyncMultiProcedure<T> procedure) {
+                       final SyncMultiProcedure<T> procedure) {
 
                assert (request != null);
                assert (procedure != null);
@@ -5614,7 +5339,11 @@ public class ReadGraphImpl implements ReadGraph {
 
                    } catch (Throwable t) {
 
-                       procedure.exception(this, t);
+                       try {
+                                       procedure.exception(this, t);
+                               } catch (DatabaseException e) {
+                                       LOGGER.error("Unexpected exception while handling exception", e);
+                               }
 
                    }                           
 
@@ -5622,16 +5351,10 @@ public class ReadGraphImpl implements ReadGraph {
 
        }
 
-       @Override
-       public <T> void asyncRequest(MultiRead<T> request,
-                       SyncMultiProcedure<T> procedure) {
-               asyncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
-       }
-
        @Override
        public <T> void asyncRequest(MultiRead<T> request,
                        MultiProcedure<T> procedure) {
-               asyncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
+               asyncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
        }
 
        @Override
@@ -5771,51 +5494,41 @@ public class ReadGraphImpl implements ReadGraph {
                assert (request != null);
                assert (procedure != null);
 
-               ListenerBase listener = getListenerBase(procedure);
+               final ListenerBase listener = getListenerBase(procedure);
 
                if (parent != null || listener != null) {
 
-                       processor.query(this, request, parent, procedure, listener);
-
-               } else {
-
                        try {
+                               QueryCacheBase.resultExternalReadEntry(this, request, parent, listener, procedure);
+                       } catch (DatabaseException e) {
+                               Logger.defaultLogError(e);
+                               // This throwable has already been transferred to procedure at this point - do nothing about it
+                       }
 
-                               request.register(this, new Listener<T>() {
-
-                                       @Override
-                                       public void execute(T result) {
-                                               procedure.execute(result);
-                                       }
-
-                                       @Override
-                                       public void exception(Throwable t) {
-                                               procedure.exception(t);
-                                       }
-
-                                       @Override
-                                       public String toString() {
-                                               return "asyncRequest(PrimitiveRead) -> " + request;
-                                       }
+               } else {
 
-                                       @Override
-                                       public boolean isDisposed() {
-                                               return true;
-                                       }
+                       request.register(this, new Listener<T>() {
+                               @Override
+                               public void execute(T result) {
+                                       procedure.execute(result);
+                               }
 
-                               });
+                               @Override
+                               public void exception(Throwable t) {
+                                       procedure.exception(t);
+                               }
 
-                       } catch (Throwable t) {
+                               @Override
+                               public String toString() {
+                                       return "asyncRequest(PrimitiveRead) -> " + request;
+                               }
 
-                               if (t instanceof DatabaseException)
-                                       procedure.exception(t);
-                               else
-                                       procedure
-                                                       .exception(new DatabaseException(
-                                                                       "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)",
-                                                                       t));
+                               @Override
+                               public boolean isDisposed() {
+                                       return true;
+                               }
 
-                       }
+                       });
 
                }
 
@@ -5936,53 +5649,23 @@ public class ReadGraphImpl implements ReadGraph {
                return thread == Integer.MIN_VALUE;
        }
 
-//     final private boolean isSync(int thread) {
-//             return thread < -1 && thread > Integer.MIN_VALUE;
-//     }
-
        ReadGraphImpl(ReadGraphImpl graph) {
                this(graph.parent, graph.processor);
        }
 
        ReadGraphImpl(CacheEntry parent, QueryProcessor support) {
-//             this.state = new ReadGraphState(barrier, support);
                this.parent = parent;
                this.processor = support;
        }
-       
-       ReadGraphImpl(final QueryProcessor support) {
-               
-//             this.state = state;
-               this.processor = support;
-               this.parent = null;
-               
-       }
-
-//     public static ReadGraphImpl createSync(int syncThread, Object syncParent,
-//                     ReadGraphSupportImpl support) {
-//             return new ReadGraphImpl(syncThread, syncThread, syncParent, null,
-//                             support, new AsyncBarrierImpl(null));
-//     }
 
        public static ReadGraphImpl create(QueryProcessor support) {
-               return new ReadGraphImpl(support);
+               return new ReadGraphImpl(null, support);
        }
 
-//     public ReadGraphImpl newAsync() {
-//             return this;
-////           if(!state.synchronizedExecution) {
-////                   return this;
-////           } else {
-////                   return new ReadGraphImpl(false, parent, state.support, state.barrier);
-////           }
-//     }
-
-//     public ReadGraphImpl newSync() {
-//             return new ReadGraphImpl(parent, processor);
-//     }
-
-       public ReadGraphImpl newSync(CacheEntry parentEntry) {
-               return new ReadGraphImpl(parentEntry, processor);
+       public static ReadGraphImpl newAsync(ReadGraphImpl parent) {
+               ReadGraphImpl result = new ReadGraphImpl(parent);
+               result.asyncBarrier = new AsyncBarrierImpl(parent.asyncBarrier);
+               return result;
        }
 
        public ReadGraphImpl newRestart(ReadGraphImpl impl) {
@@ -5990,41 +5673,10 @@ public class ReadGraphImpl implements ReadGraph {
                WriteGraphImpl write = processor.getSession().getService(
                                WriteGraphImpl.class);
 
-//             if (write.callerThread != impl.callerThread)
-//                     return new WriteGraphImpl(impl.callerThread, parent, state.support, write.writeSupport, write.provider, write.state.barrier);
                return write;
 
        }
 
-//     public ReadGraphImpl newSync(Object parentRequest) {
-//             return new ReadGraphImpl(callerThread, state.parent, state.support, new AsyncBarrierImpl(state.barrier));
-//     }
-
-//     public ReadGraphImpl newSync(final int callerThread, Object parentRequest) {
-//             assert (state.syncThread == callerThread || (state.syncThread == Integer.MIN_VALUE && callerThread != Integer.MIN_VALUE));
-//             return new ReadGraphImpl(callerThread, callerThread, parentRequest,
-//                             state.parent, state.support, new AsyncBarrierImpl(state.barrier));
-//     }
-//
-//     public ReadGraphImpl newSyncAsync(Object parentRequest) {
-////           assert (callerThread < 0);
-//             return new ReadGraphImpl(callerThread, state.syncThread, parentRequest,
-//                             state.parent, state.support, new AsyncBarrierImpl(state.barrier));
-//     }
-//
-//     public ReadGraphImpl newSyncAsync(final int callerThread,
-//                     Object parentRequest) {
-////           assert (callerThread < 0);
-//             // assert(state.syncThread == callerThread || (state.syncThread == Integer.MIN_VALUE
-//             // && callerThread != Integer.MIN_VALUE) );
-//             return new ReadGraphImpl(callerThread, callerThread, parentRequest,
-//                             state.parent, state.support, new AsyncBarrierImpl(state.barrier));
-//     }
-
-       public ReadGraphImpl withAsyncParent(CacheEntry parent) {
-               return new ReadGraphImpl(parent, processor);
-       }
-
        public ReadGraphImpl withParent(CacheEntry parent) {
                if(parent == this.parent) return this;
                else return new ReadGraphImpl(parent, processor);
@@ -6041,56 +5693,13 @@ public class ReadGraphImpl implements ReadGraph {
                
                assert(procedure.done());
                
-//             while (!procedure.done()) {
-//
-//                     boolean executed = processor.resumeTasks(callerThread, null, null);
-//                     if (!executed) {
-//                             try {
-//                                     Thread.sleep(1);
-//                                     //                                                              sema.tryAcquire(1, TimeUnit.MILLISECONDS);
-//                             } catch (InterruptedException e) {
-//                                     e.printStackTrace();
-//                             }
-//                     }
-//
-//             }
-               
        }
 
        public <T> void waitAsyncProcedure(AsyncReadProcedure<T> procedure) {
                
                assert(procedure.done());
                
-//             while (!procedure.done()) {
-//
-//                     boolean executed = processor.processor.resume(this);
-//                     if (!executed) {
-//                             try {
-//                                     Thread.sleep(1);
-//                                     //                                                              sema.tryAcquire(1, TimeUnit.MILLISECONDS);
-//                             } catch (InterruptedException e) {
-//                                     e.printStackTrace();
-//                             }
-//                     }
-//
-//             }
-               
        }
-       
-//     public void waitAsync(Object request) {
-//             try {
-//                     state.barrier.waitBarrier(request, this);
-//             } catch (Throwable t) {
-//                     t.printStackTrace();
-//                     processor.scanPending();
-//                     processor.querySupport.checkTasks();
-//                     throw new RuntimeDatabaseException(t);
-//             }
-//     }
-
-//     public void restart() {
-//             state.barrier.restart();
-//     }
 
        public boolean resumeTasks() {
                return processor.resumeTasks(this);
@@ -6665,17 +6274,23 @@ public class ReadGraphImpl implements ReadGraph {
             throw new DatabaseException(e);
         }
     }
-    
+
+    private static ThreadLocal<Boolean> syncGraph = new ThreadLocal<Boolean>() {
+        protected Boolean initialValue() {
+            return true;
+        }
+    };
+
     @Override
     public boolean setSynchronous(boolean value) {
-        boolean old = processor.synch;
-        processor.synch = value;
+        boolean old = getSynchronous();
+        syncGraph.set(value);
         return old;
     }
-    
+
     @Override
     public boolean getSynchronous() {
-        return processor.synch;
+        return syncGraph.get();
     }
     
     public void ensureLoaded(int resource) {
@@ -6706,5 +6321,10 @@ public class ReadGraphImpl implements ReadGraph {
     public Object getModificationCounter() {
        return processor.getSession().getModificationCounter();
     }
-    
+
+    @Override
+    public boolean performPending() {
+        return processor.performPending(processor.thread.get());
+    }
+
 }
index dea87d54ea35c01ccaf4fa482e285d01e4d33fca..f8d42fba5b72b568a8037db2b6eab9f51a2ce24b 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -13,7 +13,6 @@ package org.simantics.db.impl.graph;
 
 import java.util.Set;
 
-import org.simantics.db.DirectStatements;
 import org.simantics.db.RelationInfo;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
@@ -27,13 +26,10 @@ import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.procedure.AsyncSetListener;
 import org.simantics.db.procedure.ListenerBase;
 import org.simantics.db.procedure.MultiProcedure;
-import org.simantics.db.procedure.Procedure;
 import org.simantics.db.procedure.StatementProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.request.AsyncMultiRead;
-import org.simantics.db.request.AsyncRead;
-import org.simantics.db.request.ExternalRead;
 import org.simantics.db.request.MultiRead;
-import org.simantics.db.request.Read;
 
 public interface ReadGraphSupport {
 
@@ -53,9 +49,7 @@ public interface ReadGraphSupport {
     void forEachAssertedStatement(ReadGraphImpl graph, Resource subject, Resource predicate, AsyncMultiProcedure<Statement> procedure);
     void forEachObject(ReadGraphImpl graph, Resource subject, Resource predicate, MultiProcedure<Resource> procedure);
     void forEachObject(ReadGraphImpl graph, Resource subject, Resource predicate, AsyncMultiProcedure<Resource> procedure);
-    void forEachDirectPredicate(ReadGraphImpl graph, Resource subject, AsyncMultiProcedure<Resource> procedure);
-    void forEachDirectStatement(ReadGraphImpl graph, Resource subject, Procedure<DirectStatements> procedure);
-    void forEachDirectStatement(ReadGraphImpl graph, Resource subject, AsyncProcedure<DirectStatements> procedure, boolean ignoreVirtual);
+    void forEachDirectPredicate(ReadGraphImpl graph, Resource subject, AsyncProcedure<Set<Resource>> procedure);
     void forObjectSet(ReadGraphImpl graph, Resource subject, Resource predicate, AsyncSetListener<Resource> procedure);
     void forPredicateSet(ReadGraphImpl graph, Resource subject, AsyncSetListener<Resource> procedure);
     void forPrincipalTypeSet(ReadGraphImpl graph, Resource subject, AsyncSetListener<Resource> procedure);
@@ -64,7 +58,8 @@ public interface ReadGraphSupport {
     void forEachPrincipalType(ReadGraphImpl graph, Resource subject, AsyncMultiProcedure<Resource> procedure);
     void forEachPrincipalType(ReadGraphImpl graph, Resource subject, MultiProcedure<Resource> procedure);
 
-    void forRelationInfo(ReadGraphImpl graph, Resource subject, AsyncProcedure<RelationInfo> procedure);
+    RelationInfo getRelationInfo(ReadGraphImpl graph, Resource subject) throws DatabaseException;
+    
     void forTypes(ReadGraphImpl graph, Resource subject, AsyncProcedure<Set<Resource>> procedure);
     IntSet getTypes(ReadGraphImpl graph, Resource subject) throws Throwable;
     void forSupertypes(ReadGraphImpl graph, Resource subject, AsyncProcedure<Set<Resource>> procedure);
@@ -72,7 +67,7 @@ public interface ReadGraphSupport {
     void forPossibleSuperrelation(ReadGraphImpl graph, Resource subject, AsyncProcedure<Resource> procedure);
     void forSuperrelations(ReadGraphImpl graph, Resource subject, AsyncProcedure<Set<Resource>> procedure);
     byte[] getValue(ReadGraphImpl graph, Resource subject) throws DatabaseException;
-    byte[] forValue(ReadGraphImpl graph, Resource subject, AsyncProcedure<byte[]> procedure);
+    void forValue(ReadGraphImpl graph, Resource subject, AsyncProcedure<byte[]> procedure);
     void forPossibleValue(ReadGraphImpl graph, Resource subject, AsyncProcedure<byte[]> procedure);
     void forInverse(ReadGraphImpl graph, Resource relation, AsyncProcedure<Resource> procedure);
     void forResource(ReadGraphImpl graph, String id, AsyncProcedure<Resource> procedure);
@@ -85,15 +80,9 @@ public interface ReadGraphSupport {
     void forHasValue(ReadGraphImpl graph, Resource subject, AsyncProcedure<Boolean> procedure);
     void forOrderedSet(ReadGraphImpl graph, Resource subject, AsyncMultiProcedure<Resource> procedure);
 
-    <T> T queryRead(ReadGraphImpl graph, Read<T> request, CacheEntry parent, AsyncProcedure<T> procedure, ListenerBase listener) throws Throwable;
-    <T> void query(ReadGraphImpl graph, MultiRead<T> request, CacheEntry parent, AsyncMultiProcedure<T> procedure, ListenerBase listener);
-    <T> void query(ReadGraphImpl graph, AsyncRead<T> request, CacheEntry parent, AsyncProcedure<T> procedure, ListenerBase listener);
+    <T> void query(ReadGraphImpl graph, MultiRead<T> request, CacheEntry parent, SyncMultiProcedure<T> procedure, ListenerBase listener);
     <T> void query(ReadGraphImpl graph, AsyncMultiRead<T> request, CacheEntry parent, AsyncMultiProcedure<T> procedure, ListenerBase listener);
-    <T> void query(ReadGraphImpl graph, ExternalRead<T> request, CacheEntry parent, Procedure<T> procedure, ListenerBase listener);
-    
-    <T> T tryQuery(final ReadGraphImpl graph, final Read<T> request) throws DatabaseException;
-    <T> void tryQuery(final ReadGraphImpl graph, final AsyncRead<T> request, final AsyncProcedure<T> procedure);
-    
+
     VirtualGraph getProvider(Resource subject, Resource predicate, Resource object);
     VirtualGraph getProvider(Resource subject, Resource predicate);
     VirtualGraph getValueProvider(Resource subject);
index ca485f9893957ff784075f686b87221e843fce50..56fb9ec72f977e967b6a3db6a9366d4d20433657 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -128,11 +128,6 @@ final public class WriteGraphImpl extends ReadGraphImpl implements WriteGraph {
         return new WriteGraphImpl(parent, processor, writeSupport, provider);
     }
 
-    @Override
-    final public ReadGraphImpl withAsyncParent(CacheEntry parent2) {
-        return new WriteGraphImpl(parent2, processor, writeSupport, provider);
-    }
-
     @Override
     public ReadGraphImpl newRestart(ReadGraphImpl impl) {
 
@@ -801,7 +796,7 @@ final public class WriteGraphImpl extends ReadGraphImpl implements WriteGraph {
         
         Layer0 b = getBuiltins();
         initBuiltinValues(b);       
-        
+
         Statement literalStatement = getPossibleStatement(resource, predicate);
 
         if(literalStatement != null && resource.equals(literalStatement.getSubject())) {
index aa6425a8c11210d1cea94f01b4f37402ec96cd53..18345d632b73ef4ee0b9b6da137d540dd033218c 100644 (file)
  *******************************************************************************/
 package org.simantics.db.impl.procedure;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 
 
 
 public interface InternalProcedure<Result> {
     
-    void execute(ReadGraphImpl graph, Result result);
-    void exception(ReadGraphImpl graph, Throwable throwable);
+    void execute(ReadGraphImpl graph, Result result) throws DatabaseException;
+    void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException;
        
 }
diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/ResultCallWrappedSyncQueryProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/ResultCallWrappedSyncQueryProcedure.java
new file mode 100644 (file)
index 0000000..d2034fb
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.impl.procedure;
+
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.procedure.SyncMultiProcedure;
+
+public class ResultCallWrappedSyncQueryProcedure<Result> implements SyncMultiProcedure<Result> {
+
+    private final ArrayList<Result> result;
+    private Throwable exception = null;
+    private final SyncMultiProcedure<Result> procedure;
+    private final AtomicBoolean latch;
+
+    public ResultCallWrappedSyncQueryProcedure(SyncMultiProcedure<Result> procedure) {
+        this.procedure = procedure;
+        latch = new AtomicBoolean(false);
+        result = new ArrayList<Result>();
+    }
+
+    @Override
+    public void execute(ReadGraph graph, Result result) {
+        try {
+            synchronized(this.result) {
+                this.result.add(result);
+            }
+            procedure.execute(graph, result);
+        } catch (Throwable t) {
+            Logger.defaultLogError("AsyncMultiProcedure.execute failed for " + procedure, t);
+        }
+    }
+
+    @Override
+    public void finished(ReadGraph graph) {
+        if(latch.compareAndSet(false, true)) {
+            try {
+                procedure.finished(graph);
+            } catch (Throwable t) {
+                Logger.defaultLogError("AsyncMultiProcedure.exception failed for " + procedure, t);
+            } finally {
+            }
+        } else {
+            Logger.defaultLogError("Finished or exception was called many times (this time is finished)");
+        }
+    }
+
+    @Override
+    public void exception(ReadGraph graph, Throwable t) {
+        if(latch.compareAndSet(false, true)) {
+            try {
+                this.exception = t;
+                procedure.exception(graph, t);
+            } catch (Throwable throwable) {
+                Logger.defaultLogError("AsyncMultiProcedure.exception failed for " + procedure, throwable);
+            } finally {
+            }
+        } else {
+            Logger.defaultLogError("Finished or exception was called many times (this time is exception)");
+        }
+    }
+
+    public ArrayList<Result> get() {
+        return result;
+    }
+
+    public Throwable getException() {
+        return exception;
+    }
+
+    @Override
+    public String toString() {
+        return "ResultCallWrappedQueryProcedure4[" + procedure + "]"; 
+    }
+
+}
index 44e7aa38c2c692d38aa587a82a3e56f0929dcf66..9bb96a83617bcbe65539ff92c27be1ddb5f870d9 100644 (file)
@@ -11,6 +11,7 @@
  *******************************************************************************/
 package org.simantics.db.impl.procedure;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.query.TripleIntProcedure;
 
@@ -19,10 +20,10 @@ abstract public class TripleIntProcedureAdapter implements TripleIntProcedure {
     public TripleIntProcedureAdapter() {
     }
     @Override
-    public void execute(ReadGraphImpl graph, int s, int p, int o) {
+    public void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException {
     }
     @Override
-    public void finished(ReadGraphImpl graph) {
+    public void finished(ReadGraphImpl graph) throws DatabaseException {
     }
     
 }
index af8858e5a9954ba59415d1f915c204ec653cdfbf..b4104e965fbc0b56be90fc40a8f0cd07eef5ab3a 100644 (file)
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import java.util.concurrent.Semaphore;
-
 import org.simantics.db.RelationInfo;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.procedure.IntProcedureAdapter;
-import org.simantics.db.impl.procedure.InternalProcedure;
-import org.simantics.db.procedure.ListenerBase;
 
 
-final public class AssertedPredicates extends CollectionUnaryQuery<IntProcedure> {
-       
-//     public ArrayList<IntProcedure> procs = null;
+final public class AssertedPredicates extends UnaryQuery<IntProcedure> {
        
-    public AssertedPredicates(final int r) {
+    AssertedPredicates(final int r) {
         super(r);
     }
 
     public static AssertedPredicates newInstance(final int r) {
         return new AssertedPredicates(r);
     }
-    
-    final static void runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-
-        AssertedPredicates entry = (AssertedPredicates)provider.assertedPredicatesMap.get(r);
-        if(entry == null) {
-               
-               entry = new AssertedPredicates(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-            provider.performForEach(graph, entry, parent, listener, procedure);
-            
-        } else {
-               
-            if(!entry.isReady()) {
-               synchronized(entry) {
-                    if(!entry.isReady()) {
-                        throw new IllegalStateException();
-//                     if(entry.procs == null) entry.procs = new ArrayList<IntProcedure>();
-//                     entry.procs.add(procedure);
-//                     return;
-                    }
-               }
-            }
-            provider.performForEach(graph, entry, parent, listener, procedure);
-        }
 
+    @Override
+    final public void clearResult(QuerySupport support) {
+        setResult(new IntArray());
     }
     
-    final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-        
-       if(parent == null && listener == null) {
-               AssertedPredicates entry = (AssertedPredicates)provider.assertedPredicatesMap.get(r);
-               if(entry != null && entry.isReady()) { 
-                       entry.performFromCache(graph, provider, procedure);
-                       return;
-               }
-        }
-        
-        runner(graph, r, provider, parent, listener, procedure);
-         
-    }
-
     @Override
-    public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
-        return provider.assertedPredicatesMap.get(id);
+    final public void setReady() {
+        super.setReady();
+        IntArray v = (IntArray)getResult();
+        int size = v.size();
+        if(size == 0) setResult(IntArray.EMPTY);
+        else v.trim();
     }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-        provider.assertedPredicatesMap.put(id, this);
-       }
-
+    
        @Override
        final public void removeEntry(QueryProcessor provider) {
-           provider.assertedPredicatesMap.remove(id);
+           provider.cache.remove(this);
        }
        
-       void computeInheritedAssertions(ReadGraphImpl graph, int type, final QueryProcessor queryProvider, final IntProcedure proc, final boolean store) {
+       void computeInheritedAssertions(ReadGraphImpl graph, int type, final IntProcedure proc) throws DatabaseException {
+               
+               QueryProcessor processor = graph.processor;
 
-           DirectObjects.queryEach(graph, type, queryProvider.getInherits(), queryProvider, this, null, new SyncIntProcedure() {
+               QueryCache.runnerDirectObjects(graph, type, processor.getInherits(), this, null, new SyncIntProcedure() {
 
             @Override
             public void run(ReadGraphImpl graph) {
-                
-//                finish(graph, queryProvider);
-//                     proc.finished(graph);
-                
             }
 
             @Override
-            public void execute(ReadGraphImpl graph,int inh) {
+            public void execute(ReadGraphImpl graph,int inh) throws DatabaseException {
 
                inc();
                 
-                AssertedPredicates.queryEach(graph, inh, queryProvider, AssertedPredicates.this, null, new IntProcedure() {
+                QueryCache.runnerAssertedPredicates(graph, inh, AssertedPredicates.this, null, new IntProcedure() {
 
                     @Override
                     public void execute(ReadGraphImpl graph, int ass) {
-                            
                        addOrSet(ass);
-//                     proc.execute(graph, ass);
-                        
                     }
 
                     @Override
-                    public void finished(ReadGraphImpl graph) {
+                    public void finished(ReadGraphImpl graph) throws DatabaseException {
                         dec(graph);
                     }
                                
                                @Override
                                public void exception(ReadGraphImpl graph, Throwable t) {
-//                                     proc.exception(graph, t);
                     }
                     
                 });
@@ -132,33 +82,32 @@ final public class AssertedPredicates extends CollectionUnaryQuery<IntProcedure>
             }
 
             @Override
-            public void finished(ReadGraphImpl graph) {
-               
+            public void finished(ReadGraphImpl graph) throws DatabaseException {
                 dec(graph);
-                
             }
             
         });
 
        }
 
-    @Override
-    public Object computeForEach(ReadGraphImpl graph, final QueryProcessor queryProvider, final IntProcedure proc, final boolean store) {
+    //@Override
+    public Object compute(ReadGraphImpl graph, final IntProcedure proc) throws DatabaseException {
 
-        computeInheritedAssertions(graph, id, queryProvider, proc, store);
+       QueryProcessor processor = graph.processor;
+       
+        computeInheritedAssertions(graph, id, proc);
 
-       DirectObjects.queryEach(graph, id, queryProvider.getAsserts(), queryProvider, this, null, new IntProcedure() {
+       QueryCache.runnerDirectObjects(graph, id, processor.getAsserts(), this, null, new IntProcedure() {
 
             @Override
-            public void execute(ReadGraphImpl graph, final int ass) {
+            public void execute(ReadGraphImpl graph, final int ass) throws DatabaseException {
                 
-                DirectObjects.queryEach(graph, ass, queryProvider.getHasPredicate(), queryProvider, AssertedPredicates.this, null, new IntProcedure() {
+               QueryCache.runnerDirectObjects(graph, ass, processor.getHasPredicate(), AssertedPredicates.this, null, new IntProcedure() {
 
                     @Override
-                    public void execute(ReadGraphImpl graph, final int pred) {
+                    public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException {
 
                        addOrSetHiding(graph, pred, AssertedPredicates.this);
-//                     proc.execute(graph, pred);
                         return;
                         
                     }
@@ -187,9 +136,9 @@ final public class AssertedPredicates extends CollectionUnaryQuery<IntProcedure>
             
         });
        
-        finish(graph, queryProvider);
+        finish(graph, processor);
 
-       performFromCache(graph, queryProvider, proc);
+       performFromCache(graph, proc);
         
         return getResult();
         
@@ -204,31 +153,10 @@ final public class AssertedPredicates extends CollectionUnaryQuery<IntProcedure>
         
        assert(!isReady());
 
-//        ArrayList<IntProcedure> p = null;
-
         synchronized(this) {
-
                setReady();
-//            p = procs;
-//            procs = null; 
-        
         }
 
-//        if(p != null) {
-//             IntArray v = (IntArray)getResult();
-//             if(v.data == null) {
-//                 if(v.sizeOrData != IntArray.NO_DATA) {
-//                     for(IntProcedure proc : p) proc.execute(graph, v.sizeOrData);
-//                 }
-//             } else {
-//                 for(IntProcedure proc : p) {
-//                     for(int i = 0;i < v.sizeOrData ; i++) proc.execute(graph, v.data[i]);
-//                 }
-//             }
-//             
-//             for(IntProcedure proc : p) proc.finished(graph);
-//        }
-
     }
 
     synchronized private void addOrSet(int add) {
@@ -240,40 +168,16 @@ final public class AssertedPredicates extends CollectionUnaryQuery<IntProcedure>
         
     }
 
-       final static InternalProcedure<RelationInfo> ip = new InternalProcedure<RelationInfo>() {
-
-               @Override
-               public void execute(ReadGraphImpl graph, RelationInfo result) {
-               }
-
-               @Override
-               public void exception(ReadGraphImpl graph, Throwable throwable) {
-               }
-
-       };
-
-       final static InternalProcedure<IntSet> ip2 = new InternalProcedure<IntSet>() {
-
-               @Override
-               public void execute(ReadGraphImpl graph, IntSet result) {
-               }
-
-               @Override
-               public void exception(ReadGraphImpl graph, Throwable throwable) {
-               }
-
-       };
-
-       synchronized private void addOrSetHiding(ReadGraphImpl graph, int add, CacheEntry parent) {
+       synchronized private void addOrSetHiding(ReadGraphImpl graph, int add, CacheEntry parent) throws DatabaseException {
 
        assert(isPending());
        
         IntArray value = (IntArray)getResult(); 
-               RelationInfo ri = RelationInfoQuery.queryEach(graph, add, graph.processor, parent, null, ip);
+               RelationInfo ri = QueryCacheBase.resultRelationInfoQuery(graph, add, parent, null);
                if(ri.isFunctional) {
                        // Replace existing functional predicate if found
                        try {
-                               IntSet supers = SuperRelations.queryEach2(graph, add, graph.processor, parent, null, ip2);
+                               IntSet supers = QueryCache.resultSuperRelations(graph, add, parent, null); 
                        if(value.data == null) {
                            if(value.sizeOrData != IntArray.NO_DATA) {
                                if(supers.contains(value.sizeOrData)) {
@@ -301,7 +205,7 @@ final public class AssertedPredicates extends CollectionUnaryQuery<IntProcedure>
     }
     
     @Override
-    public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, final IntProcedure procedure) {
+    public Object performFromCache(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException {
 
        assert(isReady());
        
@@ -321,30 +225,21 @@ final public class AssertedPredicates extends CollectionUnaryQuery<IntProcedure>
     }
     
     @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-        
-        final Semaphore s = new Semaphore(0);
+    public void recompute(ReadGraphImpl graph) throws DatabaseException {
 
-        computeForEach(graph, provider, new IntProcedureAdapter() {
+        compute(graph, new IntProcedureAdapter() {
 
             @Override
             public void finished(ReadGraphImpl graph) {
-                s.release();
             }
 
             @Override
             public void exception(ReadGraphImpl graph, Throwable t) {
-               s.release();
                 new Error("Error in recompute.", t).printStackTrace();
             }
 
-        }, true);
-
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
+        });
         
     }
     
-    
 }
index 41b8e08d59486690543fd79494195c76395a01f9..8649de32eeee907b1e551a4e681b165c1edd1768 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.simantics.db.RelationInfo;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.procedure.InternalProcedure;
 import org.simantics.db.impl.procedure.TripleIntProcedureAdapter;
-import org.simantics.db.procedure.ListenerBase;
 import org.simantics.db.request.RequestFlags;
 
 
 final public class AssertedStatements extends CollectionBinaryQuery<TripleIntProcedure> {
     
-//    public ArrayList<TripleIntProcedure> procs;
-    
     public AssertedStatements(final int r1, final int r2) {
         super(r1, r2);
     }
@@ -34,82 +31,20 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
     public static AssertedStatements newInstance(final int r1, final int r2) {
         return new AssertedStatements(r1, r2);
     }
-    
-    final static AssertedStatements runner(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, final AssertedStatements cached, final CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) {
-        
-        AssertedStatements entry = cached != null ? cached : (AssertedStatements)provider.assertedStatementsMap.get(id(r1,r2)); 
-        if(entry == null) {
-               
-               entry = new AssertedStatements(r1, r2);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-            provider.performForEach(graph, entry, parent, listener, procedure);
-            
-            return entry;
-            
-        } else {
-               
-            if(entry.isPending()) {
-                synchronized(entry) {
-                    if(entry.isPending()) {
-                        throw new IllegalStateException();
-//                     if(entry.procs == null) entry.procs = new ArrayList<TripleIntProcedure>();
-//                        entry.procs.add(procedure);
-//                        provider.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                        return entry;
-                    }
-                }
-            }
-            provider.performForEach(graph, entry, parent, listener, procedure);
-        }
-        
-        return entry;
-        
-    }
-    
-    final public static AssertedStatements queryEach(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) {
-        
-        assert(r1 != 0);
-        assert(r2 != 0);
-        
-        final AssertedStatements entry = (AssertedStatements)provider.assertedStatementsMap.get(id(r1,r2));
-        
-        if(parent == null && !(listener != null)) {
-            if(entry != null && entry.isReady()) { 
-                entry.performFromCache(graph, provider, procedure);
-                return entry;
-            }
-        }
-
-        return runner(graph, r1, r2, provider, entry, parent, listener, procedure);
-         
-    }
-
-    @Override
-    public BinaryQuery<TripleIntProcedure> getEntry(QueryProcessor provider) {
-        return provider.assertedStatementsMap.get(id);
-    }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-        provider.assertedStatementsMap.put(id, this);
-       }
 
        @Override
        final public void removeEntry(QueryProcessor provider) {
-           provider.assertedStatementsMap.remove(id);
+           provider.cache.remove(this);
        }
        
-       void computeInheritedAssertions(ReadGraphImpl graph, int type, final int predicate, final RelationInfo ri, final QueryProcessor queryProvider, final TripleIntProcedure proc) {
+       static void computeInheritedAssertions(ReadGraphImpl graph, int type, final int predicate, final RelationInfo ri, final AssertedStatements entry, final TripleIntProcedure proc) throws DatabaseException {
            
-//        final AtomicBoolean found = new AtomicBoolean(0);
+        QueryProcessor processor = graph.processor;
 
-           DirectObjects.queryEach(graph, type, queryProvider.getInherits(), queryProvider, this, null, new SyncIntProcedure() {
+        QueryCache.runnerDirectObjects(graph, type, processor.getInherits(), entry, null, new SyncIntProcedure() {
 
             @Override
-            public void run(ReadGraphImpl graph) {
+            public void run(ReadGraphImpl graph) throws DatabaseException {
 
 //                if(ri.isFunctional && found.get() == 1) {
 //
@@ -120,29 +55,29 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
 //                    
 //                }
 
-                finish(graph, queryProvider);
+                finish(graph, entry);
                 proc.finished(graph);
                 
             }
 
             @Override
-            public void execute(ReadGraphImpl graph, int inh) {
+            public void execute(ReadGraphImpl graph, int inh) throws DatabaseException {
                 
 //                if(ri.isFunctional && found.get() == 1) return;
 
                 inc();
                 
-                AssertedStatements.queryEach(graph, inh, predicate, queryProvider, AssertedStatements.this, null, new TripleIntProcedureAdapter() {
+                QueryCache.runnerAssertedStatements(graph, inh, predicate, entry, null, new TripleIntProcedureAdapter() {
 
                     @Override
-                    public void execute(ReadGraphImpl graph, int s, int p, int o) {
+                    public void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException {
 
 //                        if(ri.isFunctional) {
 //                            
 ////                            if(found.get() == 1) return;
 //
 //                            if(found.compareAndSet(0, o)) {
-                                if(addOrSet(s,p,o))
+                                if(addOrSet(s,p,o, entry))
                                        proc.execute(graph, s, p, o);
 //                            }
 //                            // If this was a duplicate, we can ignore this
@@ -164,12 +99,12 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
                     }
 
                     @Override
-                    public void finished(ReadGraphImpl graph) {
+                    public void finished(ReadGraphImpl graph) throws DatabaseException {
                         dec(graph);
                     }
                                
                                @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
+                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                        proc.exception(graph, t);
                                        dec(graph);
                     }
@@ -179,7 +114,7 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
             }
 
             @Override
-            public void finished(ReadGraphImpl graph) {
+            public void finished(ReadGraphImpl graph) throws DatabaseException {
                 dec(graph);
             }
             
@@ -187,47 +122,62 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
 
        }
 
-    void computeLocalAssertions(ReadGraphImpl graph, final int type, final int predicate, final RelationInfo ri, final QueryProcessor queryProvider, final TripleIntProcedure proc) {
+    static void computeLocalAssertions(ReadGraphImpl graph, final int type, final int predicate, final RelationInfo ri, final AssertedStatements entry, final TripleIntProcedure proc) throws DatabaseException {
+        
         
+    }
+
+       //@Override
+       public Object compute(ReadGraphImpl graph, final TripleIntProcedure procedure) throws DatabaseException {
+               computeForEach(graph, r1(), r2(), this, procedure);
+               return getResult();
+       }
+
+    public static void computeForEach(ReadGraphImpl graph, final int type, final int predicate, final AssertedStatements entry, final TripleIntProcedure procedure) throws DatabaseException {
+
+       RelationInfo ri = QueryCache.resultRelationInfoQuery(graph, predicate, entry, null);
+       
         final AtomicInteger found = new AtomicInteger(0);
 
-        DirectObjects.queryEach(graph, type, queryProvider.getAsserts(), queryProvider, this, null, new SyncIntProcedure() {
+        QueryProcessor processor = graph.processor;
+        
+        QueryCache.runnerDirectObjects(graph, type, processor.getAsserts(), entry, null, new SyncIntProcedure() {
 
             @Override
-            public void run(ReadGraphImpl graph) {
+            public void run(ReadGraphImpl graph) throws DatabaseException {
                 
                 if(ri.isFunctional && found.get() > 1) {
 
                     ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one asserted statement.");
-                    except(exception);
-                    proc.exception(graph, exception);
+                    except(exception, entry);
+                    procedure.exception(graph, exception);
                     return;
                     
                 }
 
                 if(ri.isFunctional && found.get() == 1) {
                                         
-                    finish(graph, queryProvider);
-                    proc.finished(graph);
+                    finish(graph, entry);
+                    procedure.finished(graph);
                     return;
                     
                 }
 
-                computeInheritedAssertions(graph, type, predicate, ri, queryProvider, proc);
+                computeInheritedAssertions(graph, type, predicate, ri, entry, procedure);
                 
             }
 
             @Override
-            public void execute(ReadGraphImpl graph, final int ass) {
+            public void execute(ReadGraphImpl graph, final int ass) throws DatabaseException {
                 
                 if(ri.isFunctional && found.get() > 1) return;
                 
                 inc();
                 
-                DirectObjects.queryEach(graph, ass, queryProvider.getHasPredicate(), queryProvider, AssertedStatements.this, null, new IntProcedure() {
+                QueryCache.runnerDirectObjects(graph, ass, processor.getHasPredicate(), entry, null, new IntProcedure() {
 
                     @Override
-                    public void execute(ReadGraphImpl graph, final int pred) {
+                    public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException {
                         
                         if(ri.isFunctional) {
                             
@@ -235,18 +185,18 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
 
                             inc();
 
-                            DirectObjects.queryEach(graph, ass, queryProvider.getHasObject(), queryProvider, AssertedStatements.this, null, new IntProcedure() {
+                            QueryCache.runnerDirectObjects(graph, ass, processor.getHasObject(), entry, null, new IntProcedure() {
 
                                 @Override
-                                public void execute(ReadGraphImpl graph, final int object) {
+                                public void execute(ReadGraphImpl graph, final int object) throws DatabaseException {
                                     
                                     if(found.get() > 1) return;
 
                                     if(pred == predicate) {
 
                                        if(found.getAndIncrement() == 0) {
-                                               if(addOrSet(type, pred, object))
-                                                       proc.execute(graph, type, pred, object);
+                                               if(addOrSet(type, pred, object, entry))
+                                                       procedure.execute(graph, type, pred, object);
                                        }
                                        
                                         return;
@@ -257,10 +207,10 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
 
                                         inc();
 
-                                        SuperRelations.queryEach(graph, pred, queryProvider, AssertedStatements.this, null, new InternalProcedure<IntSet>() {
+                                        QueryCache.runnerSuperRelations(graph, pred, entry, null, new InternalProcedure<IntSet>() {
                                             
                                             @Override
-                                            public void execute(ReadGraphImpl graph, IntSet result) {
+                                            public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
                                                 
                                                 if(found.get() > 1) {
                                                     dec(graph);
@@ -270,8 +220,8 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
                                                 if(result.contains(predicate)) {
                     
                                                     if(found.getAndIncrement() == 0) {
-                                                               if(addOrSet(type, pred, object))
-                                                                       proc.execute(graph, type, pred, object);
+                                                               if(addOrSet(type, pred, object, entry))
+                                                                       procedure.execute(graph, type, pred, object);
                                                        }
                                                     
                                                 }
@@ -281,9 +231,9 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
                                             }
                                                        
                                                        @Override
-                                                       public void exception(ReadGraphImpl graph, Throwable t) {
+                                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                            
-                                                               proc.exception(graph, t);
+                                                               procedure.exception(graph, t);
                                                 dec(graph);
                                                                
                                             }
@@ -295,13 +245,13 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
                                 }
                                 
                                 @Override
-                                public void finished(ReadGraphImpl graph) {
+                                public void finished(ReadGraphImpl graph) throws DatabaseException {
                                     dec(graph);
                                 }
                                        
                                        @Override
-                                       public void exception(ReadGraphImpl graph, Throwable t) {
-                                               proc.exception(graph, t);
+                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                                               procedure.exception(graph, t);
                                     dec(graph);
                                 }
 
@@ -311,15 +261,15 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
 
                             inc();
 
-                            DirectObjects.queryEach(graph, ass, queryProvider.getHasObject(), queryProvider, AssertedStatements.this, null, new IntProcedure() {
+                            QueryCache.runnerDirectObjects(graph, ass, processor.getHasObject(), entry, null, new IntProcedure() {
 
                                 @Override
-                                public void execute(ReadGraphImpl graph, final int object) {
+                                public void execute(ReadGraphImpl graph, final int object) throws DatabaseException {
                                     
                                     if(pred == predicate) {
 
-                                        addOrSet(type, pred, object);
-                                        proc.execute(graph, type, pred, object);
+                                        addOrSet(type, pred, object, entry);
+                                        procedure.execute(graph, type, pred, object);
                                         return;
                                         
                                     }
@@ -328,15 +278,15 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
 
                                         inc();
 
-                                        SuperRelations.queryEach(graph, pred, queryProvider, AssertedStatements.this, null, new InternalProcedure<IntSet>() {
+                                        QueryCache.runnerSuperRelations(graph, pred, entry, null, new InternalProcedure<IntSet>() {
                                             
                                             @Override
-                                            public void execute(ReadGraphImpl graph, IntSet result) {
+                                            public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
                                                 
                                                 if(result.contains(predicate)) {
                     
-                                                    addOrSet(type, pred, object);
-                                                    proc.execute(graph, type, pred, object);
+                                                    addOrSet(type, pred, object, entry);
+                                                    procedure.execute(graph, type, pred, object);
 
                                                 }
                                                 
@@ -345,8 +295,8 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
                                             }
                                                        
                                                        @Override
-                                                       public void exception(ReadGraphImpl graph, Throwable t) {
-                                                               proc.exception(graph, t);
+                                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                                                               procedure.exception(graph, t);
                                                 dec(graph);
                                             }
  
@@ -357,13 +307,13 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
                                 }
                                 
                                 @Override
-                                public void finished(ReadGraphImpl graph) {
+                                public void finished(ReadGraphImpl graph) throws DatabaseException {
                                     dec(graph);
                                 }
                                        
                                        @Override
-                                       public void exception(ReadGraphImpl graph, Throwable t) {
-                                               proc.exception(graph, t);
+                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                                               procedure.exception(graph, t);
                                     dec(graph);
                                 }
 
@@ -374,13 +324,13 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
                     }
 
                     @Override
-                    public void finished(ReadGraphImpl graph) {
+                    public void finished(ReadGraphImpl graph) throws DatabaseException {
                         dec(graph);
                     }
                                
                                @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
-                                       proc.exception(graph, t);
+                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                                       procedure.exception(graph, t);
                         dec(graph);
                     }
 
@@ -389,42 +339,21 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
             }
 
             @Override
-            public void finished(ReadGraphImpl graph) {
+            public void finished(ReadGraphImpl graph) throws DatabaseException {
                 dec(graph);
             }
             
         });
         
-    }
-
-       @Override
-    public void computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final TripleIntProcedure procedure, boolean store) {
-        
-        RelationInfoQuery.queryEach(graph, r2(), provider, this, null, new InternalProcedure<RelationInfo>() {
-
-            @Override
-            public void execute(ReadGraphImpl graph, RelationInfo ri) {
-                
-                computeLocalAssertions(graph, r1(), r2(), ri, provider, procedure);
-                
-            }
-                       
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               procedure.exception(graph, t);
-            }
-        });
-        
     }
     
     @Override
     public String toString() {
-       return "AssertedStatements2[" + r1() + " - " + r2() + "]";
+       return "AssertedStatements[" + r1() + " - " + r2() + "]";
     }
 
     private boolean addOrSet(int s, int p, int o) {
-        
+       
        assert(isPending());
         
         IntArray value = (IntArray)getResult();
@@ -449,39 +378,39 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
         
     }
     
-    final private void finish(ReadGraphImpl graph, QueryProcessor provider) {
+    static boolean addOrSet(int s, int p, int o, AssertedStatements entry) {
+       if(entry != null) {
+               return entry.addOrSet(s, p, o);
+       } else {
+               return true;
+       }
+    }
+    
+    static void finish(ReadGraphImpl graph, AssertedStatements entry) {
         
-       assert(isPending());
-
-//        ArrayList<TripleIntProcedure> p = null;
-
-        synchronized(this) {
-               
-               setReady();
-//            p = procs;
-//            procs = null; 
-        
-        }
-        
-//        if(p != null) {
-//             final IntArray value = (IntArray)getResult();
-//             for(TripleIntProcedure proc : p) {
-//                     for(int i=0;i<value.size();i+=3) {
-//                             proc.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
-//                     }
-//             }
-//
-//             for(TripleIntProcedure proc : p) proc.finished(graph);
-//        }
+       assert(entry.isPending());
+       if(entry != null) {
+               synchronized(entry) {
+                       entry.setReady();
+               }
+       }
 
     }
+    
+    static void except(Throwable t, AssertedStatements entry) {
+       if(entry != null) {
+               synchronized(entry) {
+                       entry.except(t);
+               }
+       }
+    }
 
     @Override
-    public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, final TripleIntProcedure procedure) {
+    public Object performFromCache(ReadGraphImpl graph, final TripleIntProcedure procedure) throws DatabaseException {
         
        assert(isReady());
         
-       if(handleException(graph, procedure)) return;
+       if(handleException(graph, procedure)) return getResult();
        
         final IntArray value = (IntArray)getResult();
         for(int i=0;i<value.size();i+=3) {
@@ -490,18 +419,17 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
 
         procedure.finished(graph);
         
+        return value;
+        
     }
     
     @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
+    public void recompute(ReadGraphImpl graph) throws DatabaseException {
         
-        final Semaphore s = new Semaphore(0);
-
-        computeForEach(graph, provider, new TripleIntProcedureAdapter() {
+        compute(graph, new TripleIntProcedureAdapter() {
 
             @Override
             public void finished(ReadGraphImpl graph) {
-                s.release();
             }
                        
                        @Override
@@ -509,13 +437,7 @@ final public class AssertedStatements extends CollectionBinaryQuery<TripleIntPro
                                throw new Error("Error in recompute", t);
             }
     
-        }, true);
-        
-        try {
-            s.acquire();
-        } catch (InterruptedException e) {
-            throw new Error(e);
-        }
+        });
         
     }
     
index fac6b011f23d2137e14755430efd88fa1365cc1e..24f8e5375f65660a41e08396e97a393b5ce4b5b1 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -14,19 +14,22 @@ package org.simantics.db.impl.query;
 import java.util.ArrayList;
 
 import org.simantics.db.AsyncReadGraph;
-import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.BlockingAsyncMultiProcedure;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.procedure.AsyncMultiProcedure;
 import org.simantics.db.request.AsyncMultiRead;
 import org.simantics.db.request.RequestFlags;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-final public class AsyncMultiReadEntry<T> extends CacheEntryBase {
+final public class AsyncMultiReadEntry<T> extends CacheEntryBase<AsyncMultiProcedure<T>> {
 
-//    public ArrayList<AsyncMultiProcedure<T>> procs = null;
+    private static final Logger LOGGER = LoggerFactory.getLogger(AsyncMultiReadEntry.class);
 
     protected AsyncMultiRead<T> request;
     
-    public AsyncMultiReadEntry(AsyncMultiRead<T> request) {
+    AsyncMultiReadEntry(AsyncMultiRead<T> request) {
        this.request = request;
     }
     
@@ -49,55 +52,22 @@ final public class AsyncMultiReadEntry<T> extends CacheEntryBase {
     
     final synchronized public void finish(AsyncReadGraph graph) {
        
-//     new Exception("finish " + this).printStackTrace();
-       
-       if(!isPending()) {
-               System.err.println("aff");
-       }
-       
        assert(isPending());
 
-//        ArrayList<AsyncMultiProcedure<T>> p = null;
-
         synchronized(this) {
-
                setReady();
-//            p = procs;
-//            procs = null; 
-        
         }
         
-//        if(p != null) {
-//             ArrayList<T> v = (ArrayList<T>)getResult();
-//             if(v != null) {
-//                 for(AsyncMultiProcedure<T> proc : p) {
-//                     for(T t : v) proc.execute(graph, t);
-//                 }
-//             }
-//             
-//             for(AsyncMultiProcedure<T>  proc : p) proc.finished(graph);
-//        }
-        
     }
 
     final synchronized public void except(AsyncReadGraph graph, Throwable t) {
 
        assert(isPending());
 
-//        ArrayList<AsyncMultiProcedure<T>> p = null;
-
         synchronized(this) {
-
                except(t);
-//            p = procs;
-//            procs = null; 
-        
         }
         
-//        if(p != null) {
-//             for(AsyncMultiProcedure<T>  proc : p) proc.exception(graph, t);
-//        }
-        
     }
 
     @SuppressWarnings("unchecked")
@@ -121,42 +91,43 @@ final public class AsyncMultiReadEntry<T> extends CacheEntryBase {
         return new Query() {
 
                        @Override
-                       public void recompute(ReadGraphImpl graph, Object provider, CacheEntry entry) {
-                               
-                               QueryProcessor qp = (QueryProcessor)provider;
-
-                               final ReadGraphImpl parentGraph = ReadGraphImpl.forRecompute(entry, qp); 
+                       public void recompute(ReadGraphImpl graph) {
 
                                try {
 
-                                   request.perform(parentGraph , new AsyncMultiProcedure<T>() {
+                                       BlockingAsyncMultiProcedure<T> proc = new BlockingAsyncMultiProcedure<>(graph, new AsyncMultiProcedure<T>() {
 
-                        @Override
-                        public void execute(AsyncReadGraph graph, T result) {
-                            addOrSet(result);
-                        }
-                        
-                        public void finished(AsyncReadGraph graph) {
-                               finish(graph);
-                        };
-                                       
-                                       @Override
-                                       public void exception(AsyncReadGraph graph, Throwable t) {
-                            except(t);
-                           }
+                                               @Override
+                                               public void execute(AsyncReadGraph graph, T result) {
+                                                       addOrSet(result);
+                                               }
 
-                    });
+                                               public void finished(AsyncReadGraph graph) {
+                                                       finish(graph);
+                                               };
+
+                                               @Override
+                                               public void exception(AsyncReadGraph graph, Throwable t) {
+                                                       except(t);
+                                               }
+
+                                       }, request);
+
+                                       request.perform(graph , proc);
+
+                                       proc.get();
 
                                } catch (Throwable t) {
-                    except(t);
-                    if(DebugException.DEBUG) new DebugException(t).printStackTrace();
-                }
+                                       
+                                       except(t);
+                                       
+                               }
                                
                        }
 
                        @Override
                        public void removeEntry(QueryProcessor processor) {
-                       processor.asyncMultiReadMap.remove(request);
+                       processor.cache.remove(AsyncMultiReadEntry.this);
                        }
 
                        @Override
@@ -176,51 +147,38 @@ final public class AsyncMultiReadEntry<T> extends CacheEntryBase {
 
        @SuppressWarnings("unchecked")
        @Override
-       public void performFromCache(ReadGraphImpl graph, Object provider, Object procedure) {
-               
-               final AsyncMultiProcedure<T> proc = (AsyncMultiProcedure<T>)procedure;
+       public Object performFromCache(ReadGraphImpl graph, AsyncMultiProcedure<T> proc) {
 
         if(isExcepted()) {
 
             try {
                 proc.exception(graph, (Throwable)getResult());
             } catch (Throwable t) {
-                t.printStackTrace();
+                LOGGER.error("performFromCache proc.exception failed", t);
             }
-            
-            
+
         } else {
-            
+
             final ArrayList<T> values = (ArrayList<T>)getResult();
             for(T value : values) {
                 try {
                     proc.execute(graph, value);
                 } catch (Throwable t) {
-                    t.printStackTrace();
+                    LOGGER.error("performFromCache proc.execute failed", t);
                 }
             }
 
             try {
                 proc.finished(graph);
             } catch (Throwable t) {
-                t.printStackTrace();
+                LOGGER.error("performFromCache proc.finished failed", t);
             }
 
         }
                
-               
+               return getResult();
                
        }
-
-//     @Override
-//     public void performFromCache(int callerThread, Object provider,
-//                     Object procedure) {
-//
-//         QueryProvider2 queryProvider = (QueryProvider2)provider;
-//         ReadGraphImpl graph = ReadGraphImpl.forFromCache(callerThread, null, new ReadGraphSupportImpl(null, queryProvider, null));
-//             performFromCache(graph, provider, procedure);
-//             
-//     }
        
        @Override
        public String toString() {
@@ -228,4 +186,8 @@ final public class AsyncMultiReadEntry<T> extends CacheEntryBase {
                else return request.toString() + statusOrException;
        }
 
+       public Object compute(ReadGraphImpl graph, AsyncMultiProcedure<T> procedure) throws DatabaseException {
+               return graph.processor.cache.performQuery(graph, request, this, procedure);
+       }
+
 }
index a9726a75d6ac4eb5df323625ffd19da9369bcb9b..00abbebf65859e76d0e8dad481d01097cab04621 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
 package org.simantics.db.impl.query;
 
 import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.RuntimeDatabaseException;
+import org.simantics.db.impl.BlockingAsyncProcedure;
 import org.simantics.db.impl.DebugPolicy;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.request.AsyncRead;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-final public class AsyncReadEntry<T> extends CacheEntryBase {
+final public class AsyncReadEntry<T> extends CacheEntryBase<AsyncProcedure<T>> implements AsyncProcedure<T> {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AsyncReadEntry.class);
 
     protected AsyncRead<T> request;
 
-    public AsyncReadEntry(AsyncRead<T> request) {
-       this.request = request;
-       if(DebugPolicy.QUERY_STATE) System.out.println("[QUERY STATE]: created " + this);
+    AsyncReadEntry(AsyncRead<T> request) {
+        this.request = request;
+        if (DebugPolicy.QUERY_STATE)
+            System.out.println("[QUERY STATE]: created " + this);
     }
 
     @Override
     int makeHash() {
-       return request.hashCode();
+        return request.hashCode();
     }
-    
+
     @Override
     public Object getOriginalRequest() {
         return request;
     }
-    
+
     @Override
     public void discard() {
-       super.discard();
-       //request = null;
-       setResult(null);
+        super.discard();
+        setResult(null);
     }
-    
-    final public void addOrSet(AsyncReadGraph graph, Object item) {
-
-       assert(isPending());
-        
-//        ArrayList<AsyncProcedure<T>> p = null;
-
-        synchronized(this) {
-               
-            setResult(item);
-               setReady();
-//            p = procs;
-//            procs = null;
-            
-        }
 
-//        if(p != null)
-//            for(AsyncProcedure<T> proc : p) {
-//             proc.execute(graph, (T)item);
-////                proc.first.execute(graph, (T)item);
-////                proc.second.dec();
-//            }
-        
-    }
-    
-    
     public void except(AsyncReadGraph graph, Throwable t) {
-       
-       assert(isPending());
-        
-//        ArrayList<AsyncProcedure<T>> p = null;
 
-        synchronized(this) {
-               
+        assert (isPending());
+
+        synchronized (this) {
             except(t);
-////            p = procs;
-//            procs = null;
-            
         }
 
-//        if(p != null)
-//            for(AsyncProcedure<T> proc : p) {
-//             proc.exception(graph, t);
-//            }
-       
     }
-    
-    
+
     @Override
     final public Query getQuery() {
-       
-        return new Query() {
 
-                       @Override
-                       public void recompute(ReadGraphImpl graph, Object provider, CacheEntry entry) {
-                               
-                               QueryProcessor qp = (QueryProcessor)provider;
+        return new Query() {
 
-                               final ReadGraphImpl parentGraph = ReadGraphImpl.forRecompute(entry, qp); 
+            @Override
+            public void recompute(ReadGraphImpl graph) {
 
-                               try {
+                try {
 
-                                   request.perform(parentGraph , new AsyncProcedure<T>() {
+                    BlockingAsyncProcedure<T> proc = new BlockingAsyncProcedure<>(graph, new AsyncProcedure<T>() {
 
                         @Override
                         public void execute(AsyncReadGraph graph, T result) {
-                            addOrSet(graph, result);
+                            setResult(result);
+                            setReady();
                         }
-                               
-                               @Override
-                               public void exception(AsyncReadGraph graph, Throwable t) {
-                                   except(t);
+
+                        @Override
+                        public void exception(AsyncReadGraph graph, Throwable t) {
+                            except(t);
                         }
 
-                    });
+                    }, request);
+
+                    request.perform(graph, proc);
 
-                               } catch (Throwable t) {
-                                   except(t);
+                    proc.get();
+
+                } catch (Throwable t) {
+                    except(t);
                 }
-                               
-                       }
-
-                       @Override
-                       public void removeEntry(QueryProcessor qp) {
-                       qp.asyncReadMap.remove(request);
-                       }
-
-                       @Override
-                       public int type() {
-                               return request.getFlags();
-                       }
-                       
-                       @Override
-                       public String toString() {
-                               if(request == null) return "DISCARDED";
-                               else if(isExcepted()) return request.toString() + " " + getResult();
-                               else return request.toString() + " " + statusOrException;
-                       }
-               
+
+            }
+
+            @Override
+            public void removeEntry(QueryProcessor qp) {
+                qp.cache.remove(AsyncReadEntry.this);
+            }
+
+            @Override
+            public int type() {
+                return request.getFlags();
+            }
+
+            @Override
+            public String toString() {
+                if (request == null)
+                    return "DISCARDED";
+                else if (isExcepted())
+                    return request.toString() + " " + getResult();
+                else
+                    return request.toString() + " " + statusOrException;
+            }
+
         };
-        
+
     }
 
-       @SuppressWarnings("unchecked")
-       public void performFromCache(ReadGraphImpl graph, Object provider, Object procedure) {
-               
-        AsyncProcedure<T> proc = (AsyncProcedure<T>)procedure;
+    @Override
+    public Object performFromCache(ReadGraphImpl graph, AsyncProcedure<T> proc) {
+
+        if (isExcepted()) {
 
-           if(isExcepted()) {
-            
             try {
-                proc.exception(graph, (Throwable)getResult());
+                proc.exception(graph, (Throwable) getResult());
             } catch (Throwable t) {
-                t.printStackTrace();
+                LOGGER.error("performFromCache proc.exception failed", t);
             }
-            
+
         } else {
-            
+
             try {
-                proc.execute(graph, (T)getResult());
+                proc.execute(graph, (T) getResult());
             } catch (Throwable t) {
-                t.printStackTrace();
+                LOGGER.error("performFromCache proc.execute failed", t);
             }
-            
+
         }
-               
-       }
-
-       @Override
-       public String toString() {
-               if(isDiscarded()) return "DISCARDED " + request.toString();
-               else if(isExcepted()) return request.toString() + " " + getResult();
-               else return request.toString() + " " + statusOrException;
-       }
+
+        return getResult();
+
+    }
+
+    public static <T> void computeForEach(ReadGraphImpl parentGraph, AsyncRead<T> request, AsyncReadEntry<T> entry,
+            AsyncProcedure<T> procedure_) throws DatabaseException {
+
+        AsyncProcedure<T> procedure = entry != null ? entry : procedure_;
+
+        ReadGraphImpl queryGraph = parentGraph.withParent(entry);
+        
+        BlockingAsyncProcedure<T> proc = new BlockingAsyncProcedure<>(queryGraph, new AsyncProcedure<T>() {
+
+            @Override
+            public void execute(AsyncReadGraph returnGraph, T result) {
+                try {
+                    procedure.execute(parentGraph, result);
+                } catch (Throwable t) {
+                    LOGGER.error("computeForEach procedure.execute failed", t);
+                }
+            }
+
+            @Override
+            public void exception(AsyncReadGraph returnGraph, Throwable t) {
+                try {
+                    procedure.exception(parentGraph, t);
+                } catch (Throwable t2) {
+                    LOGGER.error("computeForEach procedure.exception failed", t2);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return procedure.toString();
+            }
+
+        }, request);
+
+        request.perform(queryGraph, proc);
+        
+        proc.get();
+
+        if (entry != null)
+            entry.performFromCache(parentGraph, procedure_);
+
+    }
+
+    @Override
+    public String toString() {
+        if (isDiscarded())
+            return "DISCARDED " + request.toString();
+        else if (isExcepted())
+            return request.toString() + " " + getResult();
+        else
+            return request.toString() + " " + statusOrException;
+    }
+
+    @Override
+    public void execute(AsyncReadGraph graph, T result) {
+        setResult(result);
+        setReady();
+    }
+
+    @Override
+    public void exception(AsyncReadGraph graph, Throwable throwable) {
+        except(throwable);
+    }
 
 }
index cb2df4eea79b5f25d0e0ffb63912c5e63d7c07f7..d699ea825d9823cfb8c1f3454f13115ff4518455 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.request.RequestFlags;
 
-
-abstract public class BinaryQuery<Procedure> extends CacheEntryBase implements Query {
+public abstract class BinaryQuery<Procedure> extends CacheEntryBase<Procedure> implements Query {
 
        final public long id;
 
@@ -65,23 +63,7 @@ abstract public class BinaryQuery<Procedure> extends CacheEntryBase implements Q
     final public Query getQuery() {
         return this;
     }
-    
-    @Override
-    public void recompute(ReadGraphImpl graph, Object provider, CacheEntry entry) {
-        recompute(graph, (QueryProcessor)provider);
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Override
-    public void performFromCache(ReadGraphImpl graph, Object provider, Object procedure) {
-        performFromCache(graph, (QueryProcessor)provider, (Procedure)procedure);
-    }
 
-    abstract public void recompute(ReadGraphImpl graph, QueryProcessor provider);
-    abstract public void computeForEach(ReadGraphImpl graph, QueryProcessor provider, Procedure procedure, boolean store);
-    abstract public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, Procedure procedure);
-    abstract public void putEntry(QueryProcessor provider);
     abstract public void removeEntry(QueryProcessor provider);
-    abstract public BinaryQuery<Procedure> getEntry(QueryProcessor provider);
 
 }
index f09ccc082c4a425fc5ab2b5cc25169f9bcea7712..b460a22bd06762b5d4b253b470813b9a92bc7875 100644 (file)
@@ -15,6 +15,7 @@ import gnu.trove.impl.hash.THash;
 
 import java.lang.reflect.Array;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 
 
@@ -34,66 +35,23 @@ abstract public class BinaryQueryHash<Procedure> extends THash {
 
     protected final BinaryQuery<Procedure> REMOVED = new BinaryQuery<Procedure>(-1, -1) {
 
-        @Override
-        public void computeForEach(ReadGraphImpl graph, QueryProcessor provider, Object procedure, boolean store) {
-            throw new Error("Not possible!");
-        }
-
-        @Override
-        public void putEntry(QueryProcessor provider) {
-            throw new Error("Not possible!");
-        }
-
-        @Override
-        public BinaryQuery<Procedure> getEntry(QueryProcessor provider) {
-            throw new Error("Not possible!");
-        }
-
-        @Override
-        public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-            throw new Error("Not possible!");
-        }
-
         @Override
         public void removeEntry(QueryProcessor provider) {
             throw new Error("Not possible!");
         }
 
-//        @Override
-//        public ICacheEntry2 cachedEntry(Object provider) {
-//            throw new Error("Not possible!");
-//        }
-//
-//        @Override
-//        public void computeForEach(int callerThread, Object provider, ICacheEntry2 parent, Object procedure) {
-//            throw new Error("Not possible!");
-//        }
-
         @Override
         public int type() {
             throw new Error("Not possible!");
         }
 
-//        @Override
-//        public void reset() {
-//            throw new Error("Not possible!");
-//        }
-
                @Override
-               public void performFromCache(ReadGraphImpl graph, QueryProcessor provider,
-                               Procedure procedure) {
+               Object performFromCache(ReadGraphImpl graph, Procedure procedure) throws DatabaseException {
             throw new Error("Not possible!");
                }
 
-//             @Override
-//             public void performFromCache(int callerThread, Object provider,
-//                             Object procedure) {
-//            throw new Error("Not possible!");
-//             }
-
                @Override
-               public void performFromCache(ReadGraphImpl graph, Object provider,
-                               Object procedure) {
+               public void recompute(ReadGraphImpl graph) throws DatabaseException {
             throw new Error("Not possible!");
                }
         
index d65622dadd0a18ecafb1c15b3c7c22b15b345cb0..8489256225da47bfa52c2aa29940ffbba386e24b 100644 (file)
@@ -16,7 +16,7 @@ import org.simantics.db.impl.graph.ReadGraphImpl;
 
 
 
-public abstract class CacheEntry {
+public abstract class CacheEntry<Procedure> {
        
     final public static int HAS_BEEN_BOUND = 1;
 
@@ -32,25 +32,26 @@ public abstract class CacheEntry {
     abstract void setPending();
     abstract void discard();
     abstract void except(Throwable t);
-    abstract void setResult(Object result);
     abstract void clearResult(QuerySupport support);
 
     abstract void prepareRecompute(QuerySupport querySupport);
     
     abstract public Object getOriginalRequest();
     abstract Query getQuery();
-    abstract <T> T getResult();
 
     abstract CacheEntry pruneFirstParents();
     abstract void removeParent(CacheEntry entry);
     abstract void addParent(CacheEntry entry);
     abstract boolean hasParents();
-    abstract Iterable<CacheEntry> getParents(QueryProcessor processor);
+    abstract Iterable<CacheEntry<?>> getParents(QueryProcessor processor);
     abstract CacheEntry getFirstParent(QueryProcessor processor);
     abstract boolean moreThanOneParent(QueryProcessor processor);
     abstract int parentCount(QueryProcessor processor);
     
-    abstract void performFromCache(ReadGraphImpl graph, Object provider, Object procedure);
+    abstract <T> T getResult();
+    abstract void setResult(Object result);
+    
+    abstract Object performFromCache(ReadGraphImpl graph, Procedure procedure) throws DatabaseException;
     
     abstract boolean isImmutable(ReadGraphImpl graph) throws DatabaseException;
     
index d30d59320b656b1178d9dab10730fa2d2ca61d0d..7c87b50e3acfa0e4630f3eb93ba8859c1eb13c90 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -21,7 +21,7 @@ import org.simantics.db.impl.procedure.InternalProcedure;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-abstract public class CacheEntryBase extends CacheEntry {
+public abstract class CacheEntryBase<Procedure> extends CacheEntry<Procedure> {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(CacheEntryBase.class);
     
@@ -34,11 +34,11 @@ abstract public class CacheEntryBase extends CacheEntry {
        
     final public static CacheEntryBase[] NONE = new CacheEntryBase[0];
 
-       static private Object NO_RESULT = new Object();
+       static Object NO_RESULT = new Object();
        static protected Object INVALID_RESULT = new Object();
        
-       // Just created
-    static protected Object FRESH = new Object() { public String toString() { return "CREATED"; }};
+//     // Just created
+//    static protected Object FRESH = new Object() { public String toString() { return "CREATED"; }};
     // Result is computed - no exception
     static protected Object READY = new Object() { public String toString() { return "READY"; }};
     // Computation is under way
@@ -46,12 +46,12 @@ abstract public class CacheEntryBase extends CacheEntry {
     // Entry is discarded and is waiting for garbage collect
     static protected Object DISCARDED = new Object() { public String toString() { return "DISCARDED"; }};
     // The result has been invalidated
-    static protected Object REFUTED = new Object() { public String toString() { return "REFUTED"; }};
+    static protected Object REQUIRES_COMPUTATION = new Object() { public String toString() { return "REFUTED"; }};
     // The computation has excepted - the exception is in the result
     static protected Object EXCEPTED = new Object() { public String toString() { return "EXCEPTED"; }};
 
     // This indicates the status of the entry
-    public Object statusOrException = FRESH;
+    public Object statusOrException = REQUIRES_COMPUTATION;
     
     private CacheEntry p1 = null;
     private Object p2OrParents = null;
@@ -67,10 +67,10 @@ abstract public class CacheEntryBase extends CacheEntry {
     abstract int makeHash();
     
     // This can be tested to see if the result is finished
-    private Object result = NO_RESULT;
+    Object result = NO_RESULT;
     
     final public boolean isFresh() {
-       return FRESH == statusOrException;
+       return REQUIRES_COMPUTATION == statusOrException;
     }
 
     public void setReady() {
@@ -96,23 +96,23 @@ abstract public class CacheEntryBase extends CacheEntry {
     @Override
     final public void refute() {
        if(DebugPolicy.QUERY_STATE) System.out.println("[QUERY STATE]: refuted " + this);
-       statusOrException = REFUTED;
+       statusOrException = REQUIRES_COMPUTATION;
     }
     
     @Override
     final public boolean isRefuted() {
-        return REFUTED == statusOrException;
+        return REQUIRES_COMPUTATION == statusOrException;
     }
 
     @Override
-    final public void except(Throwable t) {
+    public void except(Throwable throwable) {
        if(DebugPolicy.QUERY_STATE) System.out.println("[QUERY STATE]: excepted " + this);
        if(statusOrException != DISCARDED) {
                statusOrException = EXCEPTED;
-               result = t;
+               result = throwable;
        } else {
-               LOGGER.warn("Cache entry got excepted status after being discarded: " + getClass().getSimpleName(), t);
-               result = t;
+               LOGGER.warn("Cache entry got excepted status after being discarded: " + getClass().getSimpleName(), throwable);
+               result = throwable;
        }
     }
     
@@ -130,7 +130,7 @@ abstract public class CacheEntryBase extends CacheEntry {
     }
 
     @Override
-    final public void setPending() {
+    public void setPending() {
        statusOrException = PENDING;
     }
     
@@ -139,6 +139,10 @@ abstract public class CacheEntryBase extends CacheEntry {
         return PENDING == statusOrException;
     }
     
+    final public boolean requiresComputation() {
+       return REQUIRES_COMPUTATION == statusOrException;
+    }
+    
     final public boolean assertPending() {
        boolean result = isPending();
        if(!result) {
@@ -319,9 +323,9 @@ abstract public class CacheEntryBase extends CacheEntry {
     }
     
     @Override
-       final public Iterable<CacheEntry> getParents(QueryProcessor processor) {
+       final public Iterable<CacheEntry<?>> getParents(QueryProcessor processor) {
 
-               ArrayList<CacheEntry> result = new ArrayList<CacheEntry>();
+               ArrayList<CacheEntry<?>> result = new ArrayList<CacheEntry<?>>();
                if(p1 != null) result.add(p1);
                if(p2OrParents != null) {
                if(p2OrParents instanceof QueryIdentityHashSet) {
@@ -361,8 +365,7 @@ abstract public class CacheEntryBase extends CacheEntry {
        
     }
     
-    protected void fillImpliedParents(QueryProcessor processor, ArrayList<CacheEntry> result) {
-       
+    protected void fillImpliedParents(QueryProcessor processor, ArrayList<CacheEntry<?>> result) {
     }
     
     protected String internalError() {
@@ -370,7 +373,7 @@ abstract public class CacheEntryBase extends CacheEntry {
     }
 
     
-    protected boolean handleException(ReadGraphImpl graph, IntProcedure procedure) {
+    protected boolean handleException(ReadGraphImpl graph, IntProcedure procedure) throws DatabaseException {
        if(isExcepted()) {
                procedure.exception(graph, (Throwable)getResult());
                return true;
@@ -379,7 +382,7 @@ abstract public class CacheEntryBase extends CacheEntry {
        }
     }
     
-    protected boolean handleException(ReadGraphImpl graph, TripleIntProcedure procedure) {
+    protected boolean handleException(ReadGraphImpl graph, TripleIntProcedure procedure) throws DatabaseException {
        if(isExcepted()) {
                procedure.exception(graph, (Throwable)getResult());
                return true;
@@ -388,7 +391,7 @@ abstract public class CacheEntryBase extends CacheEntry {
        }
     }
 
-    protected <T> boolean handleException(ReadGraphImpl graph, InternalProcedure<T> procedure) {
+    protected <T> boolean handleException(ReadGraphImpl graph, InternalProcedure<T> procedure) throws DatabaseException {
        if(isExcepted()) {
                procedure.exception(graph, (Throwable)getResult());
                return true;
@@ -425,10 +428,6 @@ abstract public class CacheEntryBase extends CacheEntry {
                clearResult(querySupport);
     }
     
-    /*
-     * 
-     * 
-     */
     @Override
     int getGCStatus() {
        return GCStatus;
@@ -454,5 +453,8 @@ abstract public class CacheEntryBase extends CacheEntry {
        // This is the original request for all built-in queries
        return getQuery();
     }
-    
+
+    public CacheEntryBase() {
+    }
+
 }
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
new file mode 100644 (file)
index 0000000..8effbb1
--- /dev/null
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.impl.query;
+
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.serialization.Serializer;
+import org.simantics.db.ObjectResourceIdMap;
+import org.simantics.db.common.WriteBindings;
+import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.impl.procedure.InternalProcedure;
+import org.simantics.db.service.CollectionSupport;
+
+public final class ChildMap extends UnaryQueryP<ObjectResourceIdMap<String>> {
+
+    ChildMap(final int r) {
+        super(r);
+    }
+
+    @Override
+    public final void removeEntry(QueryProcessor provider) {
+        provider.cache.remove(this);
+    }
+
+    @Override
+    public void compute(ReadGraphImpl graph, final InternalProcedure<ObjectResourceIdMap<String>> procedure)
+            throws DatabaseException {
+        computeForEach(graph, id, this, procedure);
+    }
+
+    public static void computeForEach(ReadGraphImpl graph, final int root, final ChildMap entry,
+            final InternalProcedure<ObjectResourceIdMap<String>> procedure_) throws DatabaseException {
+
+        InternalProcedure<ObjectResourceIdMap<String>> procedure = entry != null ? entry : procedure_;
+
+        computeForEach2(graph, root, entry, procedure);
+
+        if (entry != null)
+            entry.performFromCache(graph, procedure_);
+
+    }
+
+    public static void computeForEach2(ReadGraphImpl graph, final int root, final ChildMap parent,
+            final InternalProcedure<ObjectResourceIdMap<String>> procedure) throws DatabaseException {
+
+        if (root == 0) {
+            procedure.execute(graph, null);
+            return;
+        }
+
+        QueryProcessor processor = graph.processor;
+
+        final int consistsOf = processor.getConsistsOf();
+        final int hasName = processor.getHasName();
+
+        ObjectResourceIdMap<String> result = graph.getService(CollectionSupport.class)
+                .createObjectResourceMap(String.class);
+
+        QueryCache.runnerObjects(graph, root, consistsOf, parent, null, new SyncIntProcedure() {
+
+            @Override
+            public void run(ReadGraphImpl graph) throws DatabaseException {
+                procedure.execute(graph, result);
+            }
+
+            @Override
+            public void finished(ReadGraphImpl graph) throws DatabaseException {
+                dec(graph);
+            }
+
+            @Override
+            public void execute(ReadGraphImpl graph, final int obj) throws DatabaseException {
+
+                inc();
+
+                QueryCache.runnerObjects(graph, obj, hasName, parent, null, new IntProcedure() {
+
+                    @Override
+                    public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+
+                        inc();
+
+                        QueryCache.runnerValueQuery(graph, i, parent, null, new InternalProcedure<byte[]>() {
+
+                            @Override
+                            public void execute(ReadGraphImpl graph, byte[] value) throws DatabaseException {
+
+                                if (value != null) {
+
+                                    try {
+
+                                        Binding b = WriteBindings.STRING;
+                                        Serializer serializer = b.serializer();
+                                        final String part = (String) serializer.deserialize(value);
+                                        result.putId(part, obj);
+
+                                    } catch (Throwable e) {
+                                        if (DebugException.DEBUG)
+                                            new DebugException(e).printStackTrace();
+                                    }
+
+                                }
+
+                                dec(graph);
+
+                            }
+
+                            @Override
+                            public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                                dec(graph);
+                            }
+
+                        });
+
+                    }
+
+                    @Override
+                    public void finished(ReadGraphImpl graph) throws DatabaseException {
+                        dec(graph);
+                    }
+
+                    @Override
+                    public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                        dec(graph);
+                    }
+
+                });
+
+            }
+
+        });
+
+    }
+
+    @Override
+    public String toString() {
+        return "ChildMap[" + id + "]";
+    }
+
+}
diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java
new file mode 100644 (file)
index 0000000..89892ed
--- /dev/null
@@ -0,0 +1,216 @@
+package org.simantics.db.impl.query;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+
+import org.simantics.utils.FileUtils;
+
+public class CodeGen {
+
+       int indent = 4;
+
+       String[] signatureR1RelationInfo = { "int r", "r", "keyR", "long", "InternalProcedure<RelationInfo>", "entry.id" };
+       String[] signatureR1Bytes = { "int r", "r", "keyR", "long", "InternalProcedure<byte[]>", "entry.id" };
+       String[] signatureR1IntSet = { "int r", "r", "keyR", "long", "InternalProcedure<IntSet>", "entry.id" };
+       String[] signatureR1IP = { "int r", "r", "keyR", "long", "IntProcedure", "entry.id" };
+       String[] signatureR2IP = { "int r1, int r2", "r1,r2", "keyR2", "long", "IntProcedure", "entry.id" };
+       String[] signatureR2TIP = { "int r1, int r2", "r1,r2", "keyR2", "long", "TripleIntProcedure", "entry.id" };
+       String[] signatureID1 = { "String id", "id", "keyID", "String", "InternalProcedure<Integer>", "entry.id" };
+       String[] signatureID2 = { "String id", "id", "keyID", "String", "InternalProcedure<TObjectIntHashMap<String>>", "entry.id" };
+       String[] signatureChildMap = { "int r", "r", "keyR", "long", "InternalProcedure<ObjectResourceIdMap<String>>", "entry.id" };
+       String[] signatureRead = { "Read<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
+       String[] signatureAsyncRead = { "AsyncRead<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
+       String[] signatureMultiRead = { "MultiRead<?> r", "r", "id", "long", "SyncMultiProcedure", "entry.request" };
+       String[] signatureAsyncMultiRead = { "AsyncMultiRead<?> r", "r", "id", "long", "AsyncMultiProcedure", "entry.request" };
+       String[] signatureExternalRead = { "ExternalRead<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
+
+       private void line(StringBuilder content, String line) {
+               for(int i=0;i<indent;i++)
+                       content.append(" ");
+               content.append(line);
+               content.append("\n");
+       }
+
+       public void generateQuery(StringBuilder content, String clazz, String[] signature, boolean runnerShortcut, boolean genAsync) {
+               generateGetOrCreate(content, clazz, signature, genAsync);
+               generateRemove(content, clazz, signature);
+               generateRunner(content, clazz, signature, runnerShortcut, genAsync);
+       }
+
+       public void generateRunner(StringBuilder content, String clazz, String[] signature, boolean shortcut, boolean genAsync) {
+
+               line(content, "public static void runner" + clazz + "(ReadGraphImpl graph, " + signature[0] + ", CacheEntry parent, ListenerBase listener, final " + signature[4] + " procedure" + (genAsync ? ", boolean isSync" : "") + ") throws DatabaseException {");
+               line(content, "    QueryCache cache  = graph.processor.cache;");
+               if(shortcut) {
+                       line(content, "    if(parent == null && listener == null && !cache.shouldCache(graph.processor, " + signature[1] + ")) {");
+                       line(content, "        " + clazz + ".computeForEach(graph, " + signature[1] + ", null, procedure);");
+                       line(content, "        return;");
+                       line(content, "    }");
+               }
+               line(content, "    " + clazz + " entry = (" + clazz + ")cache.getOrCreate" + clazz + "(graph.processor, " + signature[1] + (genAsync ? ", isSync" : "") + ");");
+               if(genAsync) {
+                       line(content, "    if(entry == null) {");
+                       line(content, "        graph.processor.schedule(new SessionTask(false) {");
+                       line(content, "            @Override");
+                       line(content, "            public void run(int thread) {");
+                       line(content, "                try {");
+                       line(content, "                    assert(!isSync);");
+                       line(content, "                    runner" + clazz + "(graph, r, parent, listener, procedure, isSync);");
+                       line(content, "                } catch (DatabaseException e) {");
+                       line(content, "                    Logger.defaultLogError(e);");
+                       line(content, "                }");
+                       line(content, "            }");
+                       line(content, "        });");
+                       line(content, "        return;");
+                       line(content, "    }");
+               }
+               line(content, "    " + signature[4] + " procedure_ = procedure != null ? procedure : emptyProcedure" + clazz + ";");
+               line(content, "    ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);");
+               line(content, "    if(entry.isReady()) entry.performFromCache(graph, procedure_);");
+               line(content, "    else {");
+               line(content, "      assert(entry.isPending());");
+               if(shortcut) line(content, "        " + clazz + ".computeForEach(graph, " + signature[1] + ", entry, procedure_);");
+               else line(content, "        entry.compute(graph, procedure_);"); 
+               line(content, "        if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());");
+               line(content, "    }");
+               line(content, "}");
+               line(content, "");
+
+       }
+
+       public void generateRemove(StringBuilder content, String clazz, String[] signature) {
+
+               String lower = Character.toLowerCase(clazz.charAt(0)) + clazz.substring(1);
+
+               line(content, "void remove(" + clazz + " entry) {");
+               line(content, "    synchronized(" + lower + "Map) {");
+               line(content, "        " + lower + "Map.remove(" + signature[5] + ");");
+               line(content, "    }");
+               line(content, "}");
+               line(content, "");
+
+       }
+
+       public void generateGetOrCreate(StringBuilder content, String clazz, String[] signature, boolean genAsync) {
+
+               String lower = Character.toLowerCase(clazz.charAt(0)) + clazz.substring(1);
+
+               line(content, "" + clazz + " getOrCreate" + clazz + "(QueryProcessor processor, " + signature[0] + (genAsync ? ", boolean isSync" : "") + ") throws DatabaseException {");
+               line(content, "    " + clazz + " existing = null;");
+               line(content, "    synchronized(" + lower + "Map) {");
+               line(content, "        existing = (" + clazz + ")" + lower + "Map.get(" + signature[1] + ");");
+               line(content, "        if(existing == null) {");
+               line(content, "            existing = new " + clazz + "(" + signature[1] + ");");
+               line(content, "            existing.clearResult(querySupport);");
+               line(content, "            existing.setPending();");
+               line(content, "            " + lower + "Map.put(" + signature[2] + "(" + signature[1] + "), existing);");
+               line(content, "            size++;");
+               line(content, "            return existing;");
+               line(content, "        }");
+               line(content, "        if(existing.requiresComputation()) {");
+               line(content, "            existing.setPending();");
+               line(content, "            return existing;");
+               line(content, "        }");
+               line(content, "    }");
+               if(genAsync) {
+                       line(content, "    if(existing.isPending()) {");
+                       line(content, "      if(isSync) waitPending(processor, existing);");
+                       line(content, "      else return null;");
+                       line(content, "    }");
+               } else {
+                       line(content, "    if(existing.isPending()) waitPending(processor, existing);");
+               }
+               line(content, "    return existing;");
+               line(content, "}");
+               line(content, "");
+
+       }
+
+       public void generate() {
+
+               URL classLocation = CodeGen.class.getResource(".");
+               if (classLocation != null) {
+                       if (classLocation.getProtocol().equals("file")) {
+                               try {
+                                       URL resource = new URL(classLocation, ".");
+                                       File path = new File(URLDecoder.decode(resource.getPath(), "UTF-8"));
+                                       String target = path.getAbsolutePath().replace("\\", "/");
+                                       target = target.replace("/bin/", "/src/") + "/QueryCache.java";
+                                       System.err.println("target=" + target);
+                                       File source = new File(target);
+                                       StringBuilder content = new StringBuilder();
+                                       content.append("package org.simantics.db.impl.query;\n");
+                                       content.append("\n");
+
+                                       content.append("import org.simantics.db.ObjectResourceIdMap;\n");
+                                       content.append("import org.simantics.db.RelationInfo;\n");
+                                       content.append("import org.simantics.db.common.utils.Logger;\n");
+                                       content.append("import org.simantics.db.exception.DatabaseException;\n");
+                                       content.append("import org.simantics.db.impl.graph.ReadGraphImpl;\n");
+                                       content.append("import org.simantics.db.impl.procedure.InternalProcedure;\n");
+                                       content.append("import org.simantics.db.impl.query.QueryProcessor.SessionTask;\n");
+                                       content.append("import org.simantics.db.procedure.AsyncMultiProcedure;\n");
+                                       content.append("import org.simantics.db.procedure.AsyncProcedure;\n");
+                                       content.append("import org.simantics.db.procedure.ListenerBase;\n");
+                                       content.append("import org.simantics.db.procedure.SyncMultiProcedure;\n");
+                                       content.append("import org.simantics.db.request.AsyncMultiRead;\n");
+                                       content.append("import org.simantics.db.request.AsyncRead;\n");
+                                       content.append("import org.simantics.db.request.ExternalRead;\n");
+                                       content.append("import org.simantics.db.request.MultiRead;\n");
+                                       content.append("import org.simantics.db.request.Read;\n");
+                                       content.append("\n");
+
+                                       content.append("public class QueryCache extends QueryCacheBase {\n");
+                                       content.append("\n");
+                                       line(content,"public QueryCache(QuerySupport querySupport, int threads) {");
+                                       line(content,"    super(querySupport, threads);");
+                                       line(content,"}");
+                                       content.append("\n");
+
+                                       generateQuery(content, "Objects", signatureR2IP, true, false);
+                                       generateQuery(content, "Statements", signatureR2TIP, true, false);
+                                       generateQuery(content, "DirectObjects", signatureR2IP, true, false);
+                                       generateQuery(content, "RelationInfoQuery", signatureR1RelationInfo, true, false);
+                                       generateQuery(content, "URIToResource", signatureID1, true, false);
+                                       generateQuery(content, "ValueQuery", signatureR1Bytes, true, false);
+                                       generateQuery(content, "OrderedSet", signatureR1IP, true, false);
+                                       generateQuery(content, "PrincipalTypes", signatureR1IP, true, false);
+                                       generateQuery(content, "DirectPredicates", signatureR1IntSet, true, false);
+                                       generateQuery(content, "Predicates", signatureR1IntSet, true, false);
+                                       generateQuery(content, "ReadEntry", signatureRead, true, true);
+                                       generateQuery(content, "AsyncReadEntry", signatureAsyncRead, true, true);
+                                       generateQuery(content, "Types", signatureR1IntSet, true, false);
+                                       generateQuery(content, "ChildMap", signatureChildMap, true, false);
+                                       generateQuery(content, "TypeHierarchy", signatureR1IntSet, true, false);
+                                       generateQuery(content, "SuperTypes", signatureR1IntSet, true, false);
+                                       generateQuery(content, "SuperRelations", signatureR1IntSet, true, false);
+
+                                       generateQuery(content, "AssertedPredicates", signatureR1IP, false, false);
+                                       generateQuery(content, "AssertedStatements", signatureR2TIP, false, false);
+                                       generateQuery(content, "DirectSuperRelations", signatureR1IP, false, false);
+                                       generateQuery(content, "MultiReadEntry", signatureMultiRead, false, false);
+                                       generateQuery(content, "AsyncMultiReadEntry", signatureAsyncMultiRead, false, false);
+                                       generateQuery(content, "ExternalReadEntry", signatureExternalRead, false, false);
+                                       content.append("}\n");
+                                       FileUtils.writeFile(source, content.toString().getBytes());
+                               } catch (MalformedURLException e) {
+                                       e.printStackTrace();
+                               } catch (UnsupportedEncodingException e) {
+                                       e.printStackTrace();
+                               } catch (IOException e) {
+                                       e.printStackTrace();
+                               }
+                       }
+               }
+
+       }
+
+       public static void main(String[] args) {
+               new CodeGen().generate();
+       }
+
+}
index bde26c36d319cfcb5445f227717ad40b93fe1c5c..90bb0355447acfeac8089b3f080d435f062a23e8 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.impl.procedure.IntProcedureAdapter;
 
-
-
-abstract public class CollectionUnaryQuery<T> extends UnaryQuery<T> {
+public abstract class CollectionUnaryQuery extends UnaryQuery<IntProcedure> implements IntProcedure {
     
     public CollectionUnaryQuery(final int id) {
         super(id);
     }
     
+    public abstract void compute(ReadGraphImpl graph, IntProcedure procedure) throws DatabaseException;
+
     @Override
-    public void clearResult(QuerySupport support) {
+    public final void clearResult(QuerySupport support) {
        setResult(new IntArray());
     }
     
     @Override
-    public void setReady() {
+    public final void setReady() {
        super.setReady();
        IntArray v = (IntArray)getResult();
        int size = v.size();
@@ -34,4 +37,63 @@ abstract public class CollectionUnaryQuery<T> extends UnaryQuery<T> {
         else v.trim();
     }
     
+    @Override
+    public final Object performFromCache(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException {
+
+        assert(isReady());
+
+        if(handleException(graph, procedure)) return EXCEPTED;
+        
+        final IntArray value = (IntArray)getResult();
+        if(value.data == null) {
+            if(value.sizeOrData != IntArray.NO_DATA) procedure.execute(graph, value.sizeOrData);
+        } else {
+            for(int i = 0;i < value.sizeOrData ; i++) procedure.execute(graph, value.data[i]);
+        }
+
+        procedure.finished(graph);
+        
+        return getResult();
+
+    }
+
+    @Override
+    public final void recompute(ReadGraphImpl graph) throws DatabaseException {
+
+        compute(graph, new IntProcedureAdapter() {
+
+            @Override
+            public void finished(ReadGraphImpl graph) {
+            }
+
+            @Override
+            public void exception(ReadGraphImpl graph, Throwable t) {
+                new Error("Error in recompute.", t).printStackTrace();
+            }
+
+        });
+
+    }
+    
+    @Override
+    final boolean isImmutable(ReadGraphImpl graph) {
+        return graph.processor.isImmutable(id);
+    }
+
+    @Override
+    public final void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+        IntArray v = (IntArray)getResult();
+        v.add(i);
+    }
+
+    @Override
+    public final void finished(ReadGraphImpl graph) throws DatabaseException {
+        setReady();
+    }
+
+    @Override
+    public final void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+        except(throwable);
+    }
+
 }
index 2c106476ef263cf36c1a23835d7bc5fbd24152e0..9bcb6ddb8b4c61400194e2cec39aceb514b9c908 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import java.util.Collection;
-import java.util.concurrent.Semaphore;
-
-import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.ListenerBase;
 import org.simantics.db.request.RequestFlags;
 
-final public class DirectObjects extends CollectionBinaryQuery<IntProcedure> {
+final public class DirectObjects extends CollectionBinaryQuery<IntProcedure> implements IntProcedure {
 
-       private DirectObjects(final int r1, final int r2) {
-               super(r1, r2);
-       }
+    DirectObjects(final int r1, final int r2) {
+        super(r1, r2);
+    }
 
-       @Override
-       public int type() {
-               return RequestFlags.INVALIDATE;
-       }
-       
     @Override
-    public void clearResult(QuerySupport support) {
-       setResult(INVALID_RESULT);
+    public int type() {
+        return RequestFlags.INVALIDATE;
     }
 
-       final static DirectObjects entry(final QueryProcessor provider, final int r1, final int r2) {
-
-               return (DirectObjects)provider.directObjectsMap.get(id(r1,r2));
-
-       }
-       
-       final static Collection<DirectObjects> entries(final QueryProcessor processor, final int r1) {
-               DoubleKeyQueryHashMap<IntProcedure> hash = processor.directObjectsMap;
-               return hash.values(r1);
-       }
-
-       final static void runner(ReadGraphImpl graph, final int r1, final int r2, CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-
-       QueryProcessor processor = graph.processor;
-               
-               DirectObjects entry = (DirectObjects)processor.directObjectsMap.get(id(r1,r2));
-               if(entry == null) {
-                       
-               entry = new DirectObjects(r1, r2);
-               entry.setPending();
-               entry.clearResult(processor.querySupport);
-               entry.putEntry(processor);
-               
-                       processor.performForEach(graph, entry, parent, listener, procedure);
-                       
-               } else {
-                       
-            if(entry.isPending()) {
-                synchronized(entry) {
-                    if(entry.isPending()) {
-                        processor.registerDependencies(graph, entry, parent, listener, procedure, false);
-                                               entry.computeForEach(graph, processor, procedure, true);
-                        return;
-                    }
-                }
-            }
-               
-                       processor.performForEach(graph, entry, parent, listener, procedure);
-                       
-               }
-
-       }
-
-       final public static void queryEach(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
+    @Override
+    public final void removeEntry(QueryProcessor provider) {
+        provider.cache.remove(this);
+    }
 
-        assert(r1 != 0);
-        assert(r2 != 0);
-        
-        if(parent == null && listener == null) {
-               DirectObjects.computeForEach(graph, r1, r2, null, procedure);
-        } else {
-               runner(graph, r1, r2, parent, listener, procedure);
-        }
+    // @Override
+    public Object compute(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException {
+        computeForEach(graph, r1(), r2(), this, procedure);
+        return getResult();
+    }
 
-       }
+    public static void computeForEach(ReadGraphImpl graph, int r1, int r2, final DirectObjects entry,
+            final IntProcedure procedure_) throws DatabaseException {
 
-       @Override
-       public BinaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
-               return provider.directObjectsMap.get(id);
-       }
+        IntProcedure procedure = entry != null ? entry : procedure_;
 
-       @Override
-       public void putEntry(QueryProcessor provider) {
-               provider.directObjectsMap.put(id, this);
-       }
+        QueryProcessor processor = graph.processor;
 
-       @Override
-       final public void removeEntry(QueryProcessor provider) {
-               provider.directObjectsMap.remove(id);
-       }
+        processor.querySupport.ensureLoaded(graph, r1, r2);
 
-       @Override
-       public void computeForEach(ReadGraphImpl graph, final QueryProcessor queryProvider, final IntProcedure procedure, final boolean store) {
-               computeForEach(graph, r1(), r2(), this, procedure);
-       }
+        processor.querySupport.getObjects(graph, r1, r2, procedure);
 
-       static public void computeForEach(ReadGraphImpl graph, int r1, int r2, final DirectObjects entry, final IntProcedure procedure) {
+        procedure.finished(graph);
 
-               QueryProcessor processor = graph.processor;
-               
-               processor.querySupport.ensureLoaded(graph, r1, r2);
+        if (entry != null)
+            entry.performFromCache(graph, procedure_);
 
-               processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() {
+    }
 
-                       @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-                               procedure.execute(graph, i);
-                       }
+    @Override
+    public String toString() {
+        return "DirectObjects[" + r1() + " - " + r2() + "]";
+    }
 
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                       }
+    @Override
+    public void setReady() {
+        statusOrException = READY;
+    }
 
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               if(DebugException.DEBUG) new DebugException(t).printStackTrace();
-                       }
+    @Override
+    public Object performFromCache(ReadGraphImpl graph, IntProcedure procedure) throws DatabaseException {
 
-               });
+        assert (isReady());
 
-               if(entry != null) entry.finish(graph, processor);
-               procedure.finished(graph);
+        if (handleException(graph, procedure))
+            return getResult();
 
-       }
+        final IntArray value = (IntArray) getResult();
+        if (value.data == null) {
+            if (value.sizeOrData != IntArray.NO_DATA)
+                procedure.execute(graph, value.sizeOrData);
+        } else {
+            for (int i = 0; i < value.sizeOrData; i++)
+                procedure.execute(graph, value.data[i]);
+        }
 
-       @Override
-       public String toString() {
-               return "DirectObjects[" + r1() + " - " + r2() + "]";
-       }
+        procedure.finished(graph);
 
-       @Override
-       public void setReady() {
-               statusOrException = READY;
-       }
-       
-       final private void finish(ReadGraphImpl graph, QueryProcessor provider) {
-               setReady();
-       }
+        return value;
 
-       @Override
-       public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, IntProcedure procedure) {
+    }
 
-               assert(isReady());
-               computeForEach(graph, provider, procedure, false);
+    @Override
+    public void recompute(ReadGraphImpl graph) throws DatabaseException {
 
-       }
+        compute(graph, new IntProcedure() {
 
-       @Override
-       public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
+            @Override
+            public void finished(ReadGraphImpl graph) {
+            }
 
-        final Semaphore s = new Semaphore(0);
-               
-               computeForEach(graph, provider, new IntProcedure() {
+            @Override
+            public void exception(ReadGraphImpl graph, Throwable t) {
+                throw new Error("Error in recompute.", t);
+            }
 
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               s.release();
-                       }
+            @Override
+            public void execute(ReadGraphImpl graphd, int i) {
+            }
 
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               throw new Error("Error in recompute.", t);
-                       }
+        });
 
-                       @Override
-                       public void execute(ReadGraphImpl graphd, int i) {
-                       }
+    }
 
-               }, true);
+    @Override
+    boolean isImmutable(ReadGraphImpl graph) {
+        return graph.processor.isImmutable(r1());
+    }
 
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
+    @Override
+    public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+        IntArray value = (IntArray) getResult();
+        value.add(i);
+    }
 
-       }
+    @Override
+    public void finished(ReadGraphImpl graph) throws DatabaseException {
+        setReady();
+    }
 
     @Override
-    boolean isImmutable(ReadGraphImpl graph) {
-       return graph.processor.isImmutable(r1());
+    public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+        except(throwable);
     }
-       
-}
 
+}
index 606afa430c1e35e870aaed5e35abbb51612aa0ef..1a006369a1d6867c0c788449f61900eae12d55ee 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import java.util.concurrent.Semaphore;
-
 import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.impl.procedure.IntProcedureAdapter;
-import org.simantics.db.procedure.ListenerBase;
+import org.simantics.db.impl.procedure.InternalProcedure;
 
-final public class DirectPredicates extends CollectionUnaryQuery<IntProcedure> {
+public final class DirectPredicates extends UnaryQueryP<IntSet> {
 
-       private DirectPredicates(final int resource) {
+       DirectPredicates(final int resource) {
                super(resource);
        }
 
-       final static DirectPredicates entry(final QueryProcessor provider, final int r) {
-
-               return (DirectPredicates)provider.directPredicatesMap.get(r);
-
-       }
-
-       final static void runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-
-               DirectPredicates entry = (DirectPredicates)provider.directPredicatesMap.get(r);
-               if(entry == null) {
-
-                       entry = new DirectPredicates(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-                       
-                       provider.performForEach(graph, entry, parent, listener, procedure);
-                       
-               } else {
-                       
-                       if(!entry.isReady()) {
-                               synchronized(entry) {
-                                       if(!entry.isReady()) {
-                                               provider.registerDependencies(graph, entry, parent, listener, procedure, false);
-                                               entry.computeForEach(graph, provider, procedure, true);
-                                               return;
-                                       }
-                               }
-                       }
-                       
-                       provider.performForEach(graph, entry, parent, listener, procedure);
-                       
-               }
-
-       }
-
-       final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-
-               if(parent == null && listener == null) {
-                       DirectPredicates entry = (DirectPredicates)provider.directPredicatesMap.get(r);
-                       if(entry != null && entry.isReady()) { 
-                               entry.performFromCache(graph, provider, procedure);
-                               return;
-                       } else {
-                           computeForEach(graph, r, null, procedure, false);
-                           return;
-                       }
-               }
-
-               runner(graph, r, provider, parent, listener, procedure);
-
-       }
-
-       
-       @Override
-       public void clearResult(QuerySupport support) {
-               // The cached result is never used
-               setResult(INVALID_RESULT);
-       }
-       
        @Override
-       public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
-               return provider.directPredicatesMap.get(id);
+       public final void removeEntry(QueryProcessor provider) {
+               provider.cache.remove(this);
        }
 
        @Override
-       public void putEntry(QueryProcessor provider) {
-               provider.directPredicatesMap.put(id, this);
+       public void compute(ReadGraphImpl graph, InternalProcedure<IntSet> procedure) throws DatabaseException {
+               computeForEach(graph, id, this, procedure);
        }
 
-       @Override
-       final public void removeEntry(QueryProcessor provider) {
-               provider.directPredicatesMap.remove(id);
-       }
+       public static Object computeForEach(ReadGraphImpl graph, int id, final DirectPredicates entry, final InternalProcedure<IntSet> procedure_) throws DatabaseException {
 
-       @Override
-       public Object computeForEach(ReadGraphImpl graph, QueryProcessor provider, IntProcedure procedure, boolean store) {
-           return computeForEach(graph, id, this, procedure, store);
-       }
-       
-       public static Object computeForEach(ReadGraphImpl graph, int id, final DirectPredicates entry, final IntProcedure procedure, final boolean store) {
+               InternalProcedure<IntSet> procedure = entry != null ? entry : procedure_;
 
                graph.processor.querySupport.ensureLoaded(graph, id);
-               
-               final IntArray list = new IntArray();
+
+               final IntSet list = new IntSet(graph.processor.querySupport);
 
                graph.processor.querySupport.getPredicates(graph, id, new IntProcedure() {
 
@@ -128,17 +58,10 @@ final public class DirectPredicates extends CollectionUnaryQuery<IntProcedure> {
 
                });
 
-               if(entry != null)
-                   entry.finish(graph, graph.processor);
+               procedure.execute(graph, list);
 
-               if(list.data == null) {
-                       if(list.sizeOrData != IntArray.NO_DATA) procedure.execute(graph, list.sizeOrData);
-               } else {
-                       for(int i = 0;i < list.sizeOrData ; i++) procedure.execute(graph, list.data[i]);
-               }
+               if(entry != null) entry.performFromCache(graph, procedure_);
 
-               procedure.finished(graph);
-               
                return list;
 
        }
@@ -148,56 +71,4 @@ final public class DirectPredicates extends CollectionUnaryQuery<IntProcedure> {
                return "DirectPredicates[" + id + "]";
        }
 
-       @Override
-       public void setReady() {
-               statusOrException = READY;
-       }
-       
-       final private void finish(ReadGraphImpl graph, QueryProcessor provider) {
-
-               setReady();
-
-       }
-
-       @Override
-       public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, IntProcedure procedure) {
-
-               assert(isReady());
-
-               return computeForEach(graph, provider, procedure, false);
-
-       }
-
-       @Override
-       public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-
-               final Semaphore s = new Semaphore(0);
-
-               computeForEach(graph, provider, new IntProcedureAdapter() {
-
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               s.release();
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               s.release();
-                               new Error("Error in recompute.", t).printStackTrace();
-                       }
-
-               }, true);
-
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
-
-       }
-
-
-    @Override
-    boolean isImmutable(ReadGraphImpl graph) {
-       return graph.processor.isImmutable(id);
-    }
-
 }
index c11e9f262118ceca8fdb0f2f4c7070f23c293c38..47db3c8d8425acc839f86a8757d02db250110fe3 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import gnu.trove.procedure.TIntProcedure;
-import gnu.trove.set.hash.TIntHashSet;
-
-import java.util.ArrayList;
-
+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;
-import org.simantics.db.procedure.ListenerBase;
+import org.simantics.db.impl.procedure.IntProcedureAdapter;
 
-final public class DirectSuperRelations extends UnaryQuery<IntProcedure> {
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.set.hash.TIntHashSet;
 
-       public ArrayList<InternalProcedure<IntSet>> procs = null;
+public final class DirectSuperRelations extends UnaryQuery<IntProcedure> {
 
-       private DirectSuperRelations(final int resource) {
+       DirectSuperRelations(int resource) {
                super(resource);
        }
 
-       final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-
-               new DirectSuperRelations(r).computeForEach(graph, provider, procedure, false);
-
-       }
-
-       @Override
-       public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
-               return null;
-       }
-
        @Override
-       public void putEntry(QueryProcessor provider) {
+       public final void removeEntry(QueryProcessor provider) {
+               provider.cache.remove(this);
        }
 
-       @Override
-       final public void removeEntry(QueryProcessor provider) {
-       }
-
-       class Koss {
+       private static class Ints {
 
                private TIntHashSet set = null;
                public int single = 0;
@@ -70,15 +53,6 @@ final public class DirectSuperRelations extends UnaryQuery<IntProcedure> {
 
                }
 
-               //        public int[] toArray() {
-                       //            
-                       //            int[] result = Arrays.copyOf(set.toArray(), set.size() + 1);
-                       //            result[set.size()] = single;
-                       //            return result;
-                       //            
-                       //        }
-               //        
-
                public void forEach(TIntProcedure proc) {
                        if(single > 0) proc.execute(single);
                        if(set != null) set.forEach(proc);
@@ -86,23 +60,24 @@ final public class DirectSuperRelations extends UnaryQuery<IntProcedure> {
 
        }
 
-       @Override
-       public Object computeForEach(final ReadGraphImpl graph, final QueryProcessor provider, final IntProcedure procedure, final boolean store) {
+       public Object compute(final ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException {
 
-               provider.querySupport.ensureLoaded(graph, id);
-               
-               int single = provider.querySupport.getSingleSuperrelation(id);
+               QueryProcessor processor = graph.processor;
+
+               processor.querySupport.ensureLoaded(graph, id);
+
+               int single = processor.querySupport.getSingleSuperrelation(id);
                if(single > 0) {
                        procedure.execute(graph, single);
                        procedure.finished(graph);
                        return single;
                }
 
-               final int subrelationOf = provider.getSubrelationOf();
+               final int subrelationOf = processor.getSubrelationOf();
 
-               final IntSet result = new IntSet(provider.querySupport);
+               final IntSet result = new IntSet(processor.querySupport);
 
-               final class DirectProcedure extends Koss implements IntProcedure, TIntProcedure {
+               final class DirectProcedure extends Ints implements IntProcedure, TIntProcedure {
                        @Override
                        final public boolean execute(int r) {
                                result.add(r);
@@ -128,7 +103,7 @@ final public class DirectSuperRelations extends UnaryQuery<IntProcedure> {
 
                final DirectProcedure directProc = new DirectProcedure();
 
-               provider.querySupport.getObjects(graph, id, subrelationOf, directProc);
+               processor.querySupport.getObjects(graph, id, subrelationOf, directProc);
 
                int size = directProc.size();
 
@@ -148,7 +123,11 @@ final public class DirectSuperRelations extends UnaryQuery<IntProcedure> {
                                @Override
                                public boolean execute(int arg0) {
 
-                                       procedure.execute(graph, arg0);
+                                       try {
+                                               procedure.execute(graph, arg0);
+                                       } catch (DatabaseException e) {
+                                               Logger.defaultLogError(e);
+                                       }
                                        return true;
 
                                }
@@ -166,16 +145,33 @@ final public class DirectSuperRelations extends UnaryQuery<IntProcedure> {
 
        @Override
        public String toString() {
-               return "SuperRelations2[" + id + "]";
+               return "DirectSuperRelations[" + id + "]";
        }
 
        @Override
-       public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, IntProcedure procedure) {
-               throw new UnsupportedOperationException();
+       public Object performFromCache(ReadGraphImpl graph, IntProcedure procedure) throws DatabaseException {
+
+               assert(isReady());
+
+               return compute(graph, procedure);
+
        }
 
        @Override
-       public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
+       public void recompute(ReadGraphImpl graph) throws DatabaseException {
+
+               compute(graph, new IntProcedureAdapter() {
+
+                       @Override
+                       public void finished(ReadGraphImpl graph) {
+                       }
+
+                       @Override
+                       public void exception(ReadGraphImpl graph, Throwable t) {
+                               new Error("Error in recompute.", t).printStackTrace();
+                       }
+
+               });
 
        }
 
index f1aa887bba51ac1f425e7de97e74869fb7a528c0..d59f5beb80a3e54e2246785fc997a0bb3d9ab105 100644 (file)
@@ -193,9 +193,9 @@ public class DoubleKeyQueryHashMap<Procedure> extends DoubleKeyQueryHash<Procedu
        
     }
 
-    final public ArrayList<CacheEntry> values() {
+    final public <T extends BinaryQuery> ArrayList<T> values() {
 
-       ArrayList<CacheEntry> result = new ArrayList<CacheEntry>();
+       ArrayList<T> result = new ArrayList<T>();
        
         for (int i = _set.length; i-- > 0;) {
             if(_set[i] != null && _set[i] != REMOVED) {
index 18d91dc0618643e092aa4d242f6a50545cbf6c6e..d61049744a3cbdbdb09c85040833ffc0e8329d91 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import java.util.ArrayList;
 import java.util.LinkedList;
 
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.DebugPolicy;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.Procedure;
+import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.request.ExternalRead;
 import org.simantics.db.request.RequestFlags;
 
-final public class ExternalReadEntry<T> extends CacheEntryBase {
+final public class ExternalReadEntry<T> extends CacheEntryBase<AsyncProcedure<T>> {
 
     final LinkedList<T> items = new LinkedList<T>();
-    
-//    public ArrayList<Procedure<T>> procs;
 
     protected ExternalRead<T> request;
 
@@ -47,6 +46,15 @@ final public class ExternalReadEntry<T> extends CacheEntryBase {
         request = null;
         super.discard();
     }
+
+    @Override
+    public void setPending() {
+        //if(result != NO_RESULT) {
+            //new Exception("result = " + result).printStackTrace();
+        //}
+        statusOrException = PENDING;
+        result = REQUIRES_COMPUTATION;
+    }
     
     public ExternalReadEntry(ExternalRead<T> request) {
         assert request != null;
@@ -67,7 +75,7 @@ final public class ExternalReadEntry<T> extends CacheEntryBase {
         
             assert(isPending());
 
-            ArrayList<Procedure<T>> p = null;
+            //ArrayList<Procedure<T>> p = null;
 
             synchronized(this) {
 
@@ -89,43 +97,53 @@ final public class ExternalReadEntry<T> extends CacheEntryBase {
         
     }
     
+    @Override
+    public void except(Throwable t) {
+        if(DebugPolicy.QUERY_STATE) System.out.println("[QUERY STATE]: excepted " + this);
+        if(statusOrException != DISCARDED) {
+            statusOrException = EXCEPTED;
+            result = t;
+        } else {
+            result = t;
+        }
+        assert(isExcepted());
+    }
+    
+    @Override
+    public void setResult(Object result) {
+        super.setResult(result);
+        assert(!(result instanceof Throwable));
+        assert(!isExcepted());
+    }
+
     @Override
     final public Query getQuery() {
        
         return new Query() {
 
                        @Override
-                       public void recompute(ReadGraphImpl graph, Object provider, CacheEntry entry) {
-
-                           final QueryProcessor qp = (QueryProcessor)provider;
-                           synchronized(items) {
-
-                               if(entry.isExcepted()) {
-                                       
-                                       // Exception persists
-                                       
-                               } else {
-                               
-                                       // Update
-                                       if(!items.isEmpty()) {
-                                               setResult(items.removeFirst());
-                                       }
-                                       // Reschedule
-                                           if(!items.isEmpty()) {
-                                               qp.updatePrimitive(request);
-                                           }
-                                           
+                       public void recompute(ReadGraphImpl graph) {
+
+                               synchronized(items) {
+
+
+                                       // Update
+                                       if(!items.isEmpty()) {
                                            setReady();
-                                           
-                               }
-                               
-                           }
+                                               setResult(items.removeFirst());
+                                       }
+                                       // Reschedule
+                                       if(!items.isEmpty()) {
+                                               graph.processor.updatePrimitive(request);
+                                       }
+
+                               }
                                
                        }
 
                        @Override
                        public void removeEntry(QueryProcessor processor) {
-                               processor.externalReadMap.remove(request);
+                               processor.cache.remove(ExternalReadEntry.this);
                        }
 
                        @Override
@@ -143,36 +161,29 @@ final public class ExternalReadEntry<T> extends CacheEntryBase {
         
     }
 
-       public void performFromCache(Object procedure) {
-               
-        Procedure<T> proc = (Procedure<T>)procedure;
+       @Override
+       public String toString() {
+               if(request == null) return "DISCARDED ExternalRead " + System.identityHashCode(this);
+               else return request.toString() + " " + + System.identityHashCode(this);
+       }
+
+    @Override
+    public Object performFromCache(ReadGraphImpl graph, AsyncProcedure<T> procedure) {
+       
+        AsyncProcedure<T> proc = (AsyncProcedure<T>)procedure;
 
            if(isExcepted()) {
             
-            proc.exception((Throwable)getResult());
+            proc.exception(graph, (Throwable)getResult());
             
         } else {
             
-            proc.execute((T)getResult());
+            proc.execute(graph, (T)getResult());
 
         }
-               
-       }
-
-       @Override
-       public String toString() {
-               if(request == null) return "DISCARDED ExternalRead " + System.identityHashCode(this);
-               else return request.toString() + " " + + System.identityHashCode(this);
-       }
-
-    @Override
-    public void performFromCache(ReadGraphImpl graph, Object provider, Object procedure) {
-        performFromCache(procedure);
-    }
-    
-    @Override
-    public void setReady() {
-       super.setReady();
+           
+           return getResult();
+       
     }
     
     @Override
@@ -180,4 +191,8 @@ final public class ExternalReadEntry<T> extends CacheEntryBase {
        // Do nothing - the state is already set and cannot be recomputed on demand
     }
 
+    public Object compute(ReadGraphImpl graph, AsyncProcedure<T> procedure) throws DatabaseException {
+        return graph.processor.cache.performQuery(graph, request, this, procedure);
+    }
+
 }
index 0a9ccad900745d8af16d98fb8a321bae5bf18f98..4a7bbdb28acf9e52a4e68149a51c4c0add5c3c3e 100644 (file)
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 
 
 public interface IntProcedure {
 
-    void execute(ReadGraphImpl graph, int i);
-    void finished(ReadGraphImpl graph);
-    void exception(ReadGraphImpl graph, Throwable throwable);
+    void execute(ReadGraphImpl graph, int i) throws DatabaseException;
+    void finished(ReadGraphImpl graph) throws DatabaseException;
+    void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException;
     
 }
index 7c32b8e593e19ea7757355d3c1768c0757abe7c1..3ef19b8f335ec9dbf60aeaf1df6bf818251d67a2 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -11,8 +11,6 @@
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import gnu.trove.procedure.TIntProcedure;
-
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
@@ -20,9 +18,13 @@ import java.util.Set;
 
 import org.simantics.db.Resource;
 import org.simantics.db.ResourceSet;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.ResourceImpl;
+import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.support.ResourceSupport;
 
+import gnu.trove.procedure.TIntProcedure;
+
 
 final public class IntSet implements ResourceSet {
 
@@ -40,10 +42,10 @@ final public class IntSet implements ResourceSet {
     
     private static final Object[] EMPTY_ARRAY = new Object[0];
 
-    public IntSet() {
+    public static IntSet EMPTY = new IntSet();
+
+    private IntSet() {
         support = null;
-        data = null;
-        sizeOrData = NO_DATA;
     }
 
     public IntSet(QuerySupport support) {
@@ -287,4 +289,15 @@ final public class IntSet implements ResourceSet {
         }
     }
 
+    public void forEach(ReadGraphImpl graph, IntProcedure procedure) throws DatabaseException {
+        if (data != null) {
+            for (int i=0;i<sizeOrData;++i)
+                procedure.execute(graph, data[i]);
+        } else if(sizeOrData == NO_DATA) {
+        } else {
+            procedure.execute(graph, sizeOrData);
+        }
+        procedure.finished(graph);
+    }
+
 }
\ No newline at end of file
index d0bb436d74e88e994a66fa9e27474f5a31139bfd..6b7415c9780f7a45c715068c83c4f02f1fe1fb29 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -14,21 +14,24 @@ package org.simantics.db.impl.query;
 import java.util.ArrayList;
 
 import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.impl.query.QueryProcessor.AsyncBarrier;
 import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.request.MultiRead;
 import org.simantics.db.request.RequestFlags;
-import org.simantics.utils.datastructures.Pair;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-final public class MultiReadEntry<T> extends CacheEntryBase {
+public final class MultiReadEntry<T> extends CacheEntryBase<SyncMultiProcedure<T>> {
 
-//    public ArrayList<Pair<AsyncMultiProcedure<T>, AsyncBarrier>> procs;
+    private static final Logger LOGGER = LoggerFactory.getLogger(MultiReadEntry.class);
 
     protected MultiRead<T> request;
     
-    public MultiReadEntry(MultiRead<T> request) {
+    MultiReadEntry(MultiRead<T> request) {
        this.request = request;
     }
 
@@ -49,34 +52,14 @@ final public class MultiReadEntry<T> extends CacheEntryBase {
        setResult(null);
     }
     
-    synchronized public void finish(AsyncReadGraph graph) {
+    synchronized public void finish(ReadGraph graph) {
        
        assert(isPending());
 
-        ArrayList<Pair<AsyncMultiProcedure<T>, AsyncBarrier>> p = null;
-
-        synchronized(this) {
-
+       synchronized(this) {
                setReady();
-               
-//            p = procs;
-//            procs = null; 
-        
         }
         
-//        if(p != null) {
-//             ArrayList<T> v = (ArrayList<T>)getResult();
-//             if(v != null) {
-//                     for(Pair<AsyncMultiProcedure<T>, AsyncBarrier> pair : p) {
-//                             for(T t : v) pair.first.execute(graph, t);
-//                     }
-//             }
-//             for(Pair<AsyncMultiProcedure<T>, AsyncBarrier> pair : p) {
-//                     pair.first.finished(graph);
-//                     pair.second.dec();
-//             }
-//        }
-        
     }
 
     @Override
@@ -99,41 +82,30 @@ final public class MultiReadEntry<T> extends CacheEntryBase {
         return new Query() {
 
                        @Override
-                       public void recompute(ReadGraphImpl graph, Object provider, CacheEntry entry) {
+                       public void recompute(ReadGraphImpl graph) {
                                
-                               QueryProcessor qp = (QueryProcessor)provider;
-
-                               final ReadGraphImpl parentGraph = ReadGraphImpl.forRecompute(entry, qp); 
-//                parentGraph.state.barrier.inc();
-
                                try {
 
-                                   request.perform(parentGraph , new AsyncMultiProcedure<T>() {
+                                   request.perform(graph , new SyncMultiProcedure<T>() {
 
                         @Override
-                        public void execute(AsyncReadGraph graph, T result) {
+                        public void execute(ReadGraph graph, T result) {
                             addOrSet(result);
-//                            parentGraph.state.barrier.dec();
                         }
                         
-                        public void finished(AsyncReadGraph graph) {
+                        public void finished(ReadGraph graph) {
                                finish(graph);
-//                            parentGraph.state.barrier.dec();
                         };
                                        
                                        @Override
-                                       public void exception(AsyncReadGraph graph, Throwable t) {
+                                       public void exception(ReadGraph graph, Throwable t) {
                             except(t);
-//                            parentGraph.state.barrier.dec();
                            }
 
                     });
 
-//                                     parentGraph.waitAsync(request);
-
                                } catch (Throwable t) {
                     except(t);
-//                    parentGraph.state.barrier.dec();
                     if(DebugException.DEBUG) new DebugException(t).printStackTrace();
                 }
                                
@@ -141,7 +113,7 @@ final public class MultiReadEntry<T> extends CacheEntryBase {
 
                        @Override
                        public void removeEntry(QueryProcessor processor) {
-                       processor.multiReadMap.remove(request);
+                       processor.cache.remove(MultiReadEntry.this);
                        }
 
                        @Override
@@ -168,7 +140,7 @@ final public class MultiReadEntry<T> extends CacheEntryBase {
             try {
                 proc.exception(graph, (Throwable)getResult());
             } catch (Throwable t) {
-                t.printStackTrace();
+                LOGGER.error("performFromCache proc.exception failed", t);
             }
 //            parentBarrier.dec();
             
@@ -179,33 +151,30 @@ final public class MultiReadEntry<T> extends CacheEntryBase {
                 try {
                     proc.execute(graph, value);
                 } catch (Throwable t) {
-                    t.printStackTrace();
+                    LOGGER.error("performFromCache proc.execute failed", t);
                 }
             }
 
             try {
                 proc.finished(graph);
             } catch (Throwable t) {
-                t.printStackTrace();
+                LOGGER.error("performFromCache proc.finished failed", t);
             }
 //            parentBarrier.dec();
 
         }
         
     }
-    
-       @Override
-       public void performFromCache(ReadGraphImpl graph, Object provider,
-                       Object procedure) {
-               
-               final AsyncMultiProcedure<T> proc = (AsyncMultiProcedure<T>)procedure;
+
+    @Override
+    public Object performFromCache(ReadGraphImpl graph, SyncMultiProcedure<T> proc) {
 
         if(isExcepted()) {
             
             try {
                 proc.exception(graph, (Throwable)getResult());
             } catch (Throwable t) {
-                t.printStackTrace();
+                LOGGER.error("performFromCache(Sync) proc.exception failed", t);
             }
             
         } else {
@@ -215,26 +184,30 @@ final public class MultiReadEntry<T> extends CacheEntryBase {
                 try {
                     proc.execute(graph, value);
                 } catch (Throwable t) {
-                    t.printStackTrace();
+                    LOGGER.error("performFromCache(Sync) proc.execute failed", t);
                 }
             }
 
             try {
                 proc.finished(graph);
             } catch (Throwable t) {
-                t.printStackTrace();
+                LOGGER.error("performFromCache(Sync) proc.finished failed", t);
             }
 
         }
-               
-               
-               
+
+        return null;
+
        }
-       
+
        @Override
        public String toString() {
                if(request == null) return "DISCARDED";
                else return request.toString() + statusOrException;
        }
 
+       public Object compute(ReadGraphImpl graph, SyncMultiProcedure<T> procedure) throws DatabaseException {
+               return graph.processor.cache.performQuery(graph, request, this, procedure);
+       }
+
 }
diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/NamespaceIndex.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/NamespaceIndex.java
deleted file mode 100644 (file)
index 5267280..0000000
+++ /dev/null
@@ -1,320 +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.query;
-
-import gnu.trove.map.hash.TObjectIntHashMap;
-
-import java.util.concurrent.Semaphore;
-
-import org.simantics.databoard.binding.Binding;
-import org.simantics.databoard.serialization.Serializer;
-import org.simantics.databoard.util.URIStringUtils;
-import org.simantics.db.common.WriteBindings;
-import org.simantics.db.common.exception.DebugException;
-import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.impl.procedure.InternalProcedure;
-import org.simantics.db.procedure.ListenerBase;
-
-final public class NamespaceIndex extends StringQuery<InternalProcedure<TObjectIntHashMap<String>>> {
-    
-//     public ArrayList<InternalProcedure<TObjectIntHashMap<String>>> procs = null;
-       
-    private NamespaceIndex(final String id) {
-        super(id);
-    }
-    
-    final static void runner(ReadGraphImpl graph, final String id, final QueryProcessor provider, NamespaceIndex cached, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<TObjectIntHashMap<String>> procedure) {
-
-       NamespaceIndex entry = cached != null ? cached : (NamespaceIndex)provider.namespaceIndexMap22.get(id); 
-        if(entry == null) {
-               
-               entry = new NamespaceIndex(id);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-
-            provider.performForEach(graph, entry, parent, listener, procedure);
-            
-        } else {
-
-            if(entry.isPending()) {
-               synchronized(entry) {
-                    if(entry.isPending()) {
-                        throw new IllegalStateException();
-//                     if(entry.procs == null) entry.procs = new ArrayList<InternalProcedure<TObjectIntHashMap<String>>>(); 
-//                     entry.procs.add(procedure);
-//                        provider.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                     return;
-                    }
-               }
-            }
-            provider.performForEach(graph, entry, parent, listener, procedure);
-        }
-        
-    }
-    
-    final public static void queryEach(ReadGraphImpl graph, final String id, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<TObjectIntHashMap<String>> procedure) {
-
-       final NamespaceIndex entry = (NamespaceIndex)provider.namespaceIndexMap22.get(id);
-        
-       if(parent == null && listener == null && entry != null && entry.isReady()) {
-               entry.performFromCache(graph, provider, procedure);
-               return;
-       }
-       
-        runner(graph, id, provider, entry, parent, listener, procedure);
-        
-    }
-     
-       @Override
-       public NamespaceIndex getEntry(QueryProcessor provider) {
-        return provider.namespaceIndexMap22.get(id);
-       }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-        provider.namespaceIndexMap22.put(id, this);
-       }
-
-       @Override
-       final public void removeEntry(QueryProcessor provider) {
-               provider.namespaceIndexMap22.remove(id);
-       }
-       
-       final private void index(ReadGraphImpl graph, final QueryProcessor provider, int root, final InternalProcedure<TObjectIntHashMap<String>> procedure) {
-               
-               if(root == 0) {
-            add2(graph, null);
-            procedure.execute(graph, null);
-//            System.err.println("NamespaceIndex[" + id + "]->null");
-            return;
-               }
-
-               final int consistsOf = provider.getConsistsOf();
-               final int hasName = provider.getHasName();
-        
-        final TObjectIntHashMap<String> result = new TObjectIntHashMap<String>();
-        
-        Objects.runner(graph, root, consistsOf, graph.parent, null, new SyncIntProcedure() {
-               
-               @Override
-                       public void run(ReadGraphImpl graph) {
-                       
-                       if(isPending()) { 
-                    add2(graph, result);
-                    procedure.execute(graph, result);
-//                    System.err.println("NamespaceIndex[" + id + "]->" + result.size());
-                       } else {
-                               procedure.exception(graph, (Throwable)statusOrException);
-                       }
-                               
-                       }
-
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                           
-                               dec(graph);
-                               
-                       }
-
-               @Override
-               public void execute(ReadGraphImpl graph, final int obj) {
-                       
-                       //System.out.println(id + " => " + obj);
-
-                       inc();
-                       
-                       Objects.runner(graph, obj, hasName, graph.parent, null, new IntProcedure() {
-                       
-                       @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-
-                               inc();
-
-                               ValueQuery.queryEach(graph, i, NamespaceIndex.this, null, new InternalProcedure<byte[]>() {
-                                       
-                                       @Override
-                                       public void execute(ReadGraphImpl graph, byte[] value) {
-                                               
-                                               if(value != null) {
-
-                                       try {
-
-                                               Binding b = WriteBindings.STRING;
-                                           Serializer serializer = b.serializer();
-                                           final String part = (String)serializer.deserialize(value);
-       
-                                           synchronized(result) {
-                                               Object previous = result.put(URIStringUtils.escape(part), obj);
-                                               // TODO: this is not the most elegant solution
-                                               if(previous != null) previous = "";
-                                           }
-                                           
-                                               } catch (Throwable e) {
-                                           if(DebugException.DEBUG) new DebugException(e).printStackTrace();
-                                       }
-                                               
-                                               }
-                                               
-                                       dec(graph);
-                                       
-                                       }
-                                       
-                                       @Override
-                                       public void exception(ReadGraphImpl graph, Throwable t) {
-                                                       except(t);
-                                               dec(graph);
-                            }
-
-                               });
-                               
-                       }
-                       
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               dec(graph);
-                       }
-                               
-                               @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
-                                               except(t);
-                        dec(graph);
-                    }
-
-                });
-
-               }
-               
-        });
-        
-    }
-
-    @Override
-       public void computeForEach(ReadGraphImpl graph, final QueryProcessor processor, final InternalProcedure<TObjectIntHashMap<String>> procedure) {
-       
-//     System.err.println("NamespaceIndex " + id);
-       
-        if("http://".equals(id) || "http:/".equals(id)) {
-            index(graph, processor, processor.getRootLibrary(), procedure);
-        } else {
-            final String[] parts = URIStringUtils.splitURI(id);
-            if(parts != null) {
-                NamespaceIndex.queryEach(graph, parts[0], processor, this, null, new InternalProcedure<TObjectIntHashMap<String>>() {
-    
-                    @Override
-                    public void execute(ReadGraphImpl graph, TObjectIntHashMap<String> index) {
-    
-                        if(index != null) {
-                            index(graph, processor, index.get(parts[1]), procedure);
-                        } else {
-                            add2(graph, null);
-                            procedure.execute(graph, null);
-//                            System.err.println("NamespaceIndex[" + id + "]->null");
-                        }
-                        
-                    }
-    
-                    @Override
-                    public void exception(ReadGraphImpl graph, Throwable t) {
-                        if(DebugException.DEBUG) new DebugException(t).printStackTrace();
-                        except(t);
-                        procedure.exception(graph, t);
-                    }
-    
-                });
-            } else {
-                add2(graph, null);
-                procedure.execute(graph, null);
-//                System.err.println("NamespaceIndex[" + id + "]->null");
-            }
-
-        }
-        
-    }
-
-    @Override
-    public String toString() {
-       return "NamespaceIndex[" + id + "]";
-    }
-
-    synchronized private void add(TObjectIntHashMap<String> result) {
-       
-       throw new Error("Not possible!");
-       
-    }
-
-    private void add2(ReadGraphImpl graph, TObjectIntHashMap<String> result) {
-       
-       if(!isPending()) {
-               new Exception(""+hashCode()).printStackTrace();
-       }
-       
-       assert(isPending());
-
-//        ArrayList<InternalProcedure<TObjectIntHashMap<String>>> p = null;
-
-        synchronized(this) {
-
-            setResult(result);
-               setReady();
-//            p = procs;
-//            procs = null; 
-        
-        }
-        
-//        if(p != null) {
-//        
-//             for(InternalProcedure<TObjectIntHashMap<String>> proc : p) proc.execute(graph, result);
-//             
-//        }
-       
-    }
-    
-    @Override
-    public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<TObjectIntHashMap<String>> procedure) {
-        
-        assert(isReady());
-        
-       if(handleException(graph, procedure)) return;
-        
-        procedure.execute(graph, (TObjectIntHashMap<String>)getResult());
-        
-    }
-    
-    @Override
-    public synchronized void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-        
-        final Semaphore s = new Semaphore(0);
-        
-        computeForEach(graph, provider, new InternalProcedure<TObjectIntHashMap<String>>() {
-
-            @Override
-            public void execute(ReadGraphImpl graph, TObjectIntHashMap<String> result) {
-                s.release();
-            }
-                       
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                if(DebugException.DEBUG) new DebugException(t).printStackTrace();
-                               throw new Error("Error in recompute.", t);
-            }
-
-        });
-        
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
-        
-    }
-    
-}
-
index 0b3e1be34d3e8f16a135df845e95ebdbe4fc7ccb..f74344b2fdb807dad60e1b746580f81cb106ad80 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import java.util.Collection;
-import java.util.concurrent.Semaphore;
-
-import org.simantics.databoard.Bindings;
-import org.simantics.db.DevelopmentKeys;
 import org.simantics.db.RelationInfo;
 import org.simantics.db.Resource;
 import org.simantics.db.common.exception.DebugException;
@@ -25,9 +20,7 @@ import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.procedure.IntProcedureAdapter;
 import org.simantics.db.impl.procedure.InternalProcedure;
 import org.simantics.db.procedure.AsyncMultiProcedure;
-import org.simantics.db.procedure.ListenerBase;
 import org.simantics.db.request.RequestFlags;
-import org.simantics.utils.Development;
 
 /*
  * Size analysis:
@@ -42,150 +35,18 @@ import org.simantics.utils.Development;
  * 
  */
 
-final public class Objects extends CollectionBinaryQuery<IntProcedure> {
+public final class Objects extends CollectionBinaryQuery<IntProcedure> implements IntProcedure {
 
        public Objects(final int r1, final int r2) {
                super(r1, r2);
        }
 
-       final static Objects entry(final QueryProcessor provider, final int r1, final int r2) {
-               return (Objects)provider.objectsMap.get(r1,r2);
-       }
-
-       final static Collection<Objects> entries(final QueryProcessor processor, final int r1) {
-               return processor.objectsMap.values(r1);
-       }
-
-       public final static void runner(ReadGraphImpl graph, final int r1, final int r2, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) {
-
-               if(parent == null && listener == null) {
-                       Objects.computeForEach(graph, r1, r2, null, procedure);
-                       return;
-               }
-
-               QueryProcessor processor = graph.processor;
-
-               Objects entry = (Objects)processor.objectsMap.get(r1,r2);
-               if(entry == null) {
-
-                       entry = new Objects(r1, r2);
-                       entry.setPending();
-                       entry.clearResult(processor.querySupport);
-                       entry.putEntry(processor);
-
-                       processor.performForEach(graph, entry, parent, listener, procedure);
-
-               } else {
-
-                       if(entry.isPending()) {
-                               synchronized(entry) {
-                                       if(entry.isPending()) {
-                                               processor.registerDependencies(graph, entry, parent, listener, procedure, false);
-                                               computeForEach(graph, r1, r2, null, procedure);
-                                               return;
-                                       }
-                               }
-                       }
-
-                       processor.performForEach(graph, entry, parent, listener, procedure);
-
-               }
-
-       }
-
-       static class Runner2Procedure implements IntProcedure {
-           
-           public int single = 0;
-           public Throwable t = null;
-
-           public void clear() {
-               single = 0;
-               t = null;
-           }
-           
-        @Override
-        public void execute(ReadGraphImpl graph, int i) {
-            if(single == 0) single = i;
-            else single = -1;
-        }
-
-        @Override
-        public void finished(ReadGraphImpl graph) {
-            if(single == -1) single = 0;
-        }
-
-        @Override
-        public void exception(ReadGraphImpl graph, Throwable throwable) {
-            single = 0;
-            this.t = throwable;
-        }
-        
-        public int get() throws DatabaseException {
-            if(t != null) {
-                if(t instanceof DatabaseException) throw (DatabaseException)t;
-                else throw new DatabaseException(t);
-            }
-            return single;
-        }
-           
-       }
-       
-       static final Runner2Procedure runner2Procedure = new Runner2Procedure();
-       
-    public final static int runner2(ReadGraphImpl graph, final int r1, final int r2, CacheEntry parent) throws DatabaseException {
-
-        runner2Procedure.clear();
-
-        if(parent == null) {
-            Objects.computeForEach(graph, r1, r2, null, runner2Procedure);
-            return runner2Procedure.get();
-        }
-
-        QueryProcessor processor = graph.processor;
-
-        Objects entry = (Objects)processor.objectsMap.get(r1,r2);
-        if(entry == null) {
-
-            entry = new Objects(r1, r2);
-            entry.setPending();
-            entry.clearResult(processor.querySupport);
-            entry.putEntry(processor);
-
-            processor.performForEach(graph, entry, parent, null, runner2Procedure);
-            return runner2Procedure.get();
-
-        } else {
-
-            if(entry.isPending()) throw new IllegalStateException();
-
-            processor.performForEach(graph, entry, parent, null, runner2Procedure);
-            return runner2Procedure.get();
-
-        }
-
-    }
-       
-       @Override
-       public BinaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
-               return provider.objectsMap.get(id);
-       }
-
-       @Override
-       public void putEntry(QueryProcessor provider) {
-               if(Development.DEVELOPMENT) {
-                       if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_PUT, Bindings.BOOLEAN)) {
-                               System.err.println("put " + this);
-                       }
-               }
-               provider.objectsMap.put(id, this);
-       }
-
        @Override
        final public void removeEntry(QueryProcessor provider) {
-               provider.objectsMap.remove(id);
+               provider.cache.remove(this);
        }
 
-       final static private IntArray getAssertionMap(ReadGraphImpl graph, final int r1, final int r2, final Objects entry) {
+       final static private IntArray getAssertionMap(ReadGraphImpl graph, final int r1, final int r2, final Objects entry) throws DatabaseException {
 
                class AssertionMapProc implements IntProcedure {
 
@@ -215,10 +76,9 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                        }
 
                        @Override
-                       public void execute(ReadGraphImpl graph, int type) {
-                               AssertedStatements stms = AssertedStatements.queryEach(graph, type, r2, graph.processor, entry, null, NOPT);
+                       public void execute(ReadGraphImpl graph, int type) throws DatabaseException {
                                if(result == null) {
-                                       result = stms.getResult();
+                                       result = QueryCacheBase.resultAssertedStatements(graph, type, r2, entry, null);
                                } else {
                                        if (first) {
                                                IntArray ia = result;
@@ -228,7 +88,7 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                                                }
                                                first = false;
                                        }
-                                       IntArray ia = stms.getResult();
+                                       IntArray ia = QueryCacheBase.resultAssertedStatements(graph, type, r2, entry, null);
                                        if(ia.data != null) {
                                                for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]);
                                        }
@@ -248,51 +108,39 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                AssertionMapProc amp = new AssertionMapProc();
 
                // This dependency could be cut
-               PrincipalTypes.queryEach(graph, r1, graph.processor, entry, null, amp);
+               QueryCache.runnerPrincipalTypes(graph, r1, entry, null, amp);
 
                return amp.result;
 
        }
 
-       final static private void forSingleAssertion(ReadGraphImpl graph, final int r1, final int r2, final Objects entry, final IntProcedure procedure) {
+       final static private void forSingleAssertion(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, final IntProcedure procedure) throws DatabaseException {
 
-               IntArray map = getAssertionMap(graph, r1, r2, entry);
+               IntArray map = getAssertionMap(graph, r1, r2, parent);
                if(map == null) {
-                       if(entry != null) entry.finish(graph, procedure);
-                       else procedure.finished(graph);
+                       procedure.finished(graph);
                        return;
                }
 
                int size = map.size();
                if(size == 3) {
-
-                       int value = map.data[2];
-
-                       if(entry != null) {
-                               entry.addOrSetFunctional(value);
-                               entry.finish(graph, procedure);
-                       } else {
-                               procedure.execute(graph, value);
-                               procedure.finished(graph);
-                       }
-
+                   int value = map.data[2];
+                   procedure.execute(graph, value);
+                   procedure.finished(graph);
                } else if(size == 0) {
-
-                       if(entry != null) entry.finish(graph, procedure);
-                       else procedure.finished(graph);
-
+                       procedure.finished(graph);
                } else {
 
                        int candidateS = map.data[0];
                        int candidateO = map.data[2];
 
-                       SuperTypes candidate = SuperTypes.queryEach(graph, candidateS, graph.processor, entry, null, NOP);
-                       if(candidate.isExcepted()) {
-                               if(entry != null) entry.except((Throwable)candidate.getResult());
-                               procedure.exception(graph, (Throwable)candidate.getResult());
+                       IntSet candidateIs = null;
+                       try {
+                               candidateIs = QueryCache.resultSuperTypes(graph, candidateS, parent, null);
+                       } catch (DatabaseException e) {
+                               procedure.exception(graph, e);
                                return;
                        }
-                       IntSet candidateIs = candidate.getResult();
 
                        for(int i=3;i<map.size();i+=3) {
 
@@ -307,13 +155,13 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
 
                                        } else {
 
-                                               SuperTypes next = SuperTypes.queryEach(graph, nextS, graph.processor, entry, null, NOP);
-                                               if(next.isExcepted()) {
-                                                       if(entry != null) entry.except((Throwable)next.getResult());
-                                                       procedure.exception(graph, (Throwable)next.getResult());
+                                               IntSet nextIs = null;
+                                               try {
+                                                       nextIs = QueryCache.resultSuperTypes(graph, nextS, parent, null);
+                                               } catch (DatabaseException e) {
+                                                       procedure.exception(graph, e);
                                                        return;
                                                }
-                                               IntSet nextIs = next.getResult();
 
                                                if(nextIs.contains(candidateS)) {
 
@@ -327,8 +175,6 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
 
                                                        // candidate and next are unrelated => error
                                                        ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has conflicting assertions " + r1 + ", " + r2 + " " + map , r1);
-
-                                                       if(entry != null) entry.except(exception);
                                                        procedure.exception(graph, exception);
                                                        return;                                         
 
@@ -340,13 +186,8 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
 
                        }
 
-                       if(entry != null) {
-                               entry.addOrSetFunctional(candidateO);
-                               entry.finish(graph, procedure);
-                       } else {
-                               procedure.execute(graph, candidateO);
-                               procedure.finished(graph);
-                       }
+                       procedure.execute(graph, candidateO);
+                       procedure.finished(graph);
 
                }
 
@@ -382,12 +223,12 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
        };
 
        // Search for one statement
-       final public void computeFunctionalIndex(ReadGraphImpl graph, final QueryProcessor provider, final RelationInfo ri, final IntProcedure procedure) {
+       final public void computeFunctionalIndex(ReadGraphImpl graph, final QueryProcessor provider, final RelationInfo ri, final IntProcedure procedure) throws DatabaseException {
                computeFunctionalIndex(graph, r1(), r2(), this, ri, procedure);
        }
 
        // Search for one statement
-       final static public void computeFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Objects entry, final RelationInfo ri, final IntProcedure procedure) {
+       final static public void computeFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, final RelationInfo ri, final IntProcedure procedure) throws DatabaseException {
 
                if(ri.isFinal) {
 
@@ -396,16 +237,15 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                        if(result == 0) {
 
                                // Check for assertions
-                               forSingleAssertion(graph, r1, r2, entry, procedure);
+                               forSingleAssertion(graph, r1, r2, parent, procedure);
 
                        } else if (result == -1) {
 
                                graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() {
 
                                        @Override
-                                       public void execute(ReadGraphImpl graph, int i) {
-                                               if(entry != null) entry.addOrSetFunctional(i);
-                                               else procedure.execute(graph, i);
+                                       public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                                           procedure.execute(graph, i);
                                        }
 
                                        @Override
@@ -420,18 +260,13 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                                });
 
                                // Check for assertions
-                               forSingleAssertion(graph, r1, r2, entry, procedure);
+                               forSingleAssertion(graph, r1, r2, parent, procedure);
 
                        } else {
 
                                // If functional relation was found there is no need to check assertions
-                               if(entry != null) {
-                                       entry.addOrSetFunctional(result);
-                                       entry.finish(graph, procedure);
-                               } else {
-                                       procedure.execute(graph, result);
-                                       procedure.finished(graph);
-                               }
+                procedure.execute(graph, result);
+                procedure.finished(graph);
 
                                
                        }
@@ -439,49 +274,46 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                } else {
 
                        // Note! The dependency is intentionally cut!
-                       DirectPredicates.queryEach(graph, r1, graph.processor, null, null, new SyncIntProcedure() {
+            IntSet direct = QueryCache.resultDirectPredicates(graph, r1, null, null);
+            direct.forEach(graph, new SyncIntProcedure() {
 
                                boolean found = false;
 
                                @Override
-                               public void run(ReadGraphImpl graph) {
+                               public void run(ReadGraphImpl graph) throws DatabaseException {
 
                                        if(found) {
-                                               if(entry != null) entry.finish(graph, procedure);
-                                               else procedure.finished(graph);
+                                               procedure.finished(graph);
                                        } else {
 
                                                // Check for assertions
-                                               forSingleAssertion(graph, r1, r2, entry, procedure);
+                                               forSingleAssertion(graph, r1, r2, parent, procedure);
 
                                        }
 
                                }
 
                                @Override
-                               public void execute(ReadGraphImpl graph, final int pred) {
+                               public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException {
 
                                        if(found) return;
 
                                        if(pred == r2) {
 
                                                // Note! The dependency is intentionally cut!
-                                               DirectObjects.queryEach(graph, r1, pred, graph.processor, null, null, new IntProcedure() {
+                                               QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() {
 
                                                        @Override
-                                                       public void execute(ReadGraphImpl graph, int i) {
+                                                       public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
 
                                                                if(!found) {
 
-                                                                       if(entry != null) entry.addOrSetFunctional(i);
-                                                                       else procedure.execute(graph, i);
-
+                                                                       procedure.execute(graph, i);
                                                                        found = true;
 
                                                                } else {
 
                                                                        ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement (r1=" + r1 + ", r2=" + r2 + ").", r1);
-                                                                       if(entry != null) entry.except(exception);
                                                                        procedure.exception(graph, exception);
 
                                                                }
@@ -493,7 +325,7 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                                                        }
 
                                                        @Override
-                                                       public void exception(ReadGraphImpl graph, Throwable t) {
+                                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                                procedure.exception(graph, t);
                                                        }
 
@@ -501,32 +333,29 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
 
                                        } else {
 
-                                               SuperRelations.queryEach(graph, pred, graph.processor, entry, null, new InternalProcedure<IntSet>() {
+                                               QueryCache.runnerSuperRelations(graph, pred, parent, null, new InternalProcedure<IntSet>() {
 
                                                        @Override
-                                                       public void execute(ReadGraphImpl graph, IntSet result) {
+                                                       public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
 
                                                                if(found) return;
 
                                                                if(result.contains(r2)) {
 
                                                                        // Note! The dependency is intentionally cut!
-                                                                       DirectObjects.queryEach(graph, r1, pred, graph.processor, null, null, new IntProcedure() {
+                                                                       QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() {
 
                                                                                @Override
-                                                                               public void execute(ReadGraphImpl graph, int i) {
+                                                                               public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
 
                                                                                        if(!found) {
 
-                                                                                               if(entry != null) entry.addOrSetFunctional(i);
-                                                                                               else procedure.execute(graph, i);
-
+                                                                                               procedure.execute(graph, i);
                                                                                                found = true;
 
                                                                                        } else {
 
                                                                                                ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement (r1=" + r1 + ", r2=" + r2 + ").", r1);
-                                                                                               if(entry != null) entry.except(exception);
                                                                                                procedure.exception(graph, exception);
 
                                                                                        }
@@ -538,7 +367,7 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                                                                                }
 
                                                                                @Override
-                                                                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                                                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                                                        procedure.exception(graph, t);
                                                                                }
 
@@ -549,7 +378,7 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                                                        }
 
                                                        @Override
-                                                       public void exception(ReadGraphImpl graph, Throwable t) {
+                                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                                procedure.exception(graph, t);
                                                        }
 
@@ -560,7 +389,7 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                                }
 
                                @Override
-                               public void finished(ReadGraphImpl graph) {
+                               public void finished(ReadGraphImpl graph) throws DatabaseException {
 
                                        dec(graph);
 
@@ -573,34 +402,30 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
 
        }
 
-       final static private void forAssertions(ReadGraphImpl graph, final int r1, final int r2, final Objects entry, final IntProcedure procedure) {
+       final static private void forAssertions(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, final IntProcedure procedure) throws DatabaseException {
 
                // Note! The dependency is intentionally cut!
-               PrincipalTypes.queryEach(graph, r1, graph.processor, null, null, new SyncIntProcedure() {
+               QueryCache.runnerPrincipalTypes(graph, r1, null, null, new SyncIntProcedure() {
 
                        @Override
-                       public void run(ReadGraphImpl graph) {
-
-                               if(entry != null) entry.finish(graph, procedure);
-                               else procedure.finished(graph);
-
+                       public void run(ReadGraphImpl graph) throws DatabaseException {
+                               procedure.finished(graph);
                        }
 
                        TripleIntProcedure proc = new TripleIntProcedure() {
 
                                @Override
-                               public void execute(ReadGraphImpl graph, int s, int p, int o) {
-                                       if(entry != null) entry.addOrSet(o);
-                                       else procedure.execute(graph, o);
+                               public void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException {
+                                       procedure.execute(graph, o);
                                }
 
                                @Override
-                               public void finished(ReadGraphImpl graph) {
+                               public void finished(ReadGraphImpl graph) throws DatabaseException {
                                        dec(graph);
                                }
 
                                @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
+                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                        if(DebugException.DEBUG) new DebugException(t).printStackTrace();
                                        procedure.exception(graph, t);
                                        dec(graph);
@@ -609,16 +434,15 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                        };
 
                        @Override
-                       public void execute(ReadGraphImpl graph, int type) {
+                       public void execute(ReadGraphImpl graph, int type) throws DatabaseException {
 
                                inc();
-
-                               AssertedStatements.queryEach(graph, type, r2, graph.processor, entry, null, proc);
+                               QueryCache.runnerAssertedStatements(graph, type, r2, parent, null, proc);
 
                        }
 
                        @Override
-                       public void finished(ReadGraphImpl graph) {
+                       public void finished(ReadGraphImpl graph) throws DatabaseException {
                                dec(graph);
                        }
 
@@ -628,29 +452,26 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
        }
 
        final public static void computeNotFunctionalFinalIndex(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, RelationInfo ri, AsyncMultiProcedure<Resource> procedure) {
-
                throw new Error();
-
        }
 
-       final public void computeNotFunctionalIndex(ReadGraphImpl graph, RelationInfo ri, final IntProcedure procedure) {
+       final public void computeNotFunctionalIndex(ReadGraphImpl graph, RelationInfo ri, final IntProcedure procedure) throws DatabaseException {
                computeNotFunctionalIndex(graph, r1(), r2(), this, ri, procedure);
        }
 
-       final static public void computeNotFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Objects entry, RelationInfo ri, final IntProcedure procedure) {
+       final static public void computeNotFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, RelationInfo ri, final IntProcedure procedure) throws DatabaseException {
 
                if(ri.isFinal) {
 
                        graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() {
 
                                @Override
-                               public void execute(ReadGraphImpl graph, int i) {
-                                       if(entry != null) entry.addOrSet(i);
-                                       else procedure.execute(graph, i);
+                               public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                                       procedure.execute(graph, i);
                                }
 
                                @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
+                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                        if(DebugException.DEBUG) new DebugException(t).printStackTrace();
                                        procedure.exception(graph, t);
                                }
@@ -662,47 +483,44 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                        });
 
                        if(ri.isAsserted) {
-                               forAssertions(graph, r1, r2, entry, procedure);
+                               forAssertions(graph, r1, r2, parent, procedure);
                        } else {
-                               if(entry != null) entry.finish(graph, procedure);
-                               else procedure.finished(graph);
+                               procedure.finished(graph);
                        }
 
                } else {
 
                        // Note! The dependency is intentionally cut!
-                       DirectPredicates.queryEach(graph, r1, graph.processor, null, null, new SyncIntProcedure() {
+                       IntSet direct = QueryCache.resultDirectPredicates(graph, r1, null, null);
+                       direct.forEach(graph, new SyncIntProcedure() {
 
                                @Override
-                               public void run(ReadGraphImpl graph) {
-
-                                       forAssertions(graph, r1, r2, entry, procedure);
-
+                               public void run(ReadGraphImpl graph) throws DatabaseException {
+                                       forAssertions(graph, r1, r2, parent, procedure);
                                }
 
                                @Override
-                               public void execute(ReadGraphImpl graph, final int pred) {
+                               public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException {
 
                                        if(pred == r2) {
 
                                                inc();
 
                                                // Note! The dependency is intentionally cut!
-                                               DirectObjects.queryEach(graph, r1, pred, graph.processor, null, null, new IntProcedure() {
+                                               QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() {
 
                                                        @Override
-                                                       public void execute(ReadGraphImpl graph, int i) {
-                                                               if(entry != null) entry.addOrSet(i);
-                                                               else procedure.execute(graph, i);
+                                                       public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                                                               procedure.execute(graph, i);
                                                        }
 
                                                        @Override
-                                                       public void finished(ReadGraphImpl graph) {
+                                                       public void finished(ReadGraphImpl graph) throws DatabaseException {
                                                                dec(graph);
                                                        }
 
                                                        @Override
-                                                       public void exception(ReadGraphImpl graph, Throwable t) {
+                                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                                procedure.exception(graph, t);
                                                                dec(graph);
                                                        }
@@ -713,31 +531,30 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
 
                                                inc();
 
-                                               SuperRelations.queryEach(graph, pred, graph.processor, entry, null, new InternalProcedure<IntSet>() {
+                                               QueryCache.runnerSuperRelations(graph, pred, parent, null, new InternalProcedure<IntSet>() {
 
                                                        @Override
-                                                       public void execute(ReadGraphImpl graph, IntSet result) {
+                                                       public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
 
                                                                if(result.contains(r2)) {
 
                                                                        inc();
 
                                                                        // Note! The dependency is intentionally cut!
-                                                                       DirectObjects.queryEach(graph, r1, pred, graph.processor, null, null, new IntProcedure() {
+                                                                       QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() {
 
                                                                                @Override
-                                                                               public void execute(ReadGraphImpl graph, int i) {
-                                                                                       if(entry != null) entry.addOrSet(i);
-                                                                                       else procedure.execute(graph, i);
+                                                                               public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                                                                                       procedure.execute(graph, i);
                                                                                }
 
                                                                                @Override
-                                                                               public void finished(ReadGraphImpl graph) {
+                                                                               public void finished(ReadGraphImpl graph) throws DatabaseException {
                                                                                        dec(graph);
                                                                                }
 
                                                                                @Override
-                                                                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                                                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                                                        if(DebugException.DEBUG) new DebugException(t).printStackTrace();
                                                                                        procedure.exception(graph, t);
                                                                                        dec(graph);
@@ -752,7 +569,7 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                                                        }
 
                                                        @Override
-                                                       public void exception(ReadGraphImpl graph, Throwable t) {
+                                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                                procedure.exception(graph, t);
                                                                dec(graph);
                                                        }
@@ -764,7 +581,7 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                                }
 
                                @Override
-                               public void finished(ReadGraphImpl graph) {
+                               public void finished(ReadGraphImpl graph) throws DatabaseException {
                                        dec(graph);
                                }
 
@@ -774,90 +591,38 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
 
        }
 
-       @Override
-       public void computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final IntProcedure procedure, final boolean store) {
+       public Object compute(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException {
                computeForEach(graph, r1(), r2(), this, procedure);
+               return getResult();
        }
 
-       public static void computeForEach(ReadGraphImpl graph, final int r1, final int r2, final Objects entry, final IntProcedure procedure) {
+       public static void computeForEach(ReadGraphImpl graph, final int r1, final int r2, final Objects entry, final IntProcedure procedure_) throws DatabaseException {
 
-               RelationInfo ri = RelationInfoQuery.queryEach(graph, r2, graph.processor, entry, null, ip);
-               graph.ensureLoaded(r1, r2);       
-               if(ri.isFunctional) {
-                       computeFunctionalIndex(graph, r1, r2, entry, ri, procedure);
-               } else {
-                       computeNotFunctionalIndex(graph, r1, r2, entry, ri, procedure);
-               }
+           IntProcedure procedure = entry != null ? entry : procedure_;
+           
+        RelationInfo ri = QueryCache.resultRelationInfoQuery(graph, r2, entry, null);
+        graph.ensureLoaded(r1, r2);
+        if(ri.isFunctional) {
+            computeFunctionalIndex(graph, r1, r2, entry, ri, procedure);
+        } else {
+            computeNotFunctionalIndex(graph, r1, r2, entry, ri, procedure);
+        }
+               
+               if(entry != null) entry.performFromCache(graph, procedure_);
 
        }
 
-       final static InternalProcedure<RelationInfo> ip = new InternalProcedure<RelationInfo>() {
-
-               @Override
-               public void execute(ReadGraphImpl graph, RelationInfo result) {
-               }
-
-               @Override
-               public void exception(ReadGraphImpl graph, Throwable throwable) {
-               }
-
-       };
-
        @Override
        public String toString() {
                return "Objects[" + r1() + " - " + r2() + "]";
        }
 
-       final private void finish(ReadGraphImpl graph, IntProcedure procedure) {
-
-               assert(assertPending());
-
-               synchronized(this) {
-                       setReady();
-               }
-
-               IntArray v = (IntArray)getResult();
-
-               if(v.data == null) {
-                       if(v.sizeOrData != IntArray.NO_DATA) {
-                               procedure.execute(graph, v.sizeOrData);
-                       }
-               } else {
-                       for(int i = 0;i < v.sizeOrData ; i++) {
-                               procedure.execute(graph, v.data[i]);
-                       }
-               }
-
-               procedure.finished(graph);
-
-       }
-
-       final public void addOrSet(int add) {
-
-               assert(assertPending());
-
-               IntArray value = (IntArray)getResult();
-               synchronized(value) {
-                       value.add(add);
-               }
-
-       }
-
-       final public void addOrSetFunctional(int add) {
-
-               assert(isPending());
-
-               IntArray value = (IntArray)getResult();
-               value.add(add);
-
-       }
-
        @Override
-       public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, final IntProcedure procedure) {
+       public Object performFromCache(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException {
 
                assert(isReady());
 
-               if(handleException(graph, procedure)) return;
+               if(handleException(graph, procedure)) return getResult();
 
                final IntArray value = (IntArray)getResult();
                if(value.data == null) {
@@ -867,32 +632,26 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                }
 
                procedure.finished(graph);
+               
+               return value;
 
        }
 
        @Override
-       public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-
-               final Semaphore s = new Semaphore(0);
+       public void recompute(ReadGraphImpl graph) throws DatabaseException {
 
-               computeForEach(graph, provider, new IntProcedureAdapter() {
+               compute(graph, new IntProcedureAdapter() {
 
                        @Override
                        public void finished(ReadGraphImpl graph) {
-                               s.release();
                        }
 
                        @Override
                        public void exception(ReadGraphImpl graph, Throwable t) {
-                               s.release();
                                new Error("Error in recompute.", t).printStackTrace();
                        }
 
-               }, true);
-
-               while(!s.tryAcquire()) {
-                       provider.resume(graph);
-               }
+               });
 
        }
 
@@ -906,4 +665,22 @@ final public class Objects extends CollectionBinaryQuery<IntProcedure> {
                return graph.processor.isImmutable(r1());
        }
 
+    @Override
+    public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+        IntArray value = (IntArray)getResult();
+        synchronized(value) {
+            value.add(i);
+        }
+    }
+
+    @Override
+    public void finished(ReadGraphImpl graph) throws DatabaseException {
+        setReady();
+    }
+
+    @Override
+    public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+        except(throwable);
+    }
+
 }
index 65cfb007ce4e040f8014696dec1694ad58c678df..e850e96f1bf6b94745b5946c5bcf578312715d42 100644 (file)
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.impl.procedure.IntProcedureAdapter;
-import org.simantics.db.procedure.ListenerBase;
 
-final public class OrderedSet extends CollectionUnaryQuery<IntProcedure> {
+final public class OrderedSet extends CollectionUnaryQuery {
        
-//     public ArrayList<IntProcedure> procs = null;
-
        public OrderedSet(final int r) {
         super(r);
     }
 
-    final static OrderedSet entry(final QueryProcessor provider, final int r) {
-        
-        return (OrderedSet)provider.orderedSetMap.get(r);
-
-    }
-       
-    final static void runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, OrderedSet cached, final CacheEntry parent, ListenerBase listener, final IntProcedure procedure) {
-        
-       OrderedSet entry = cached != null ? cached : (OrderedSet)provider.orderedSetMap.get(r); 
-        if(entry == null) {
-               
-               entry = new OrderedSet(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-            provider.performForEach(graph, entry, parent, listener, procedure);
-            
-        } else {
-
-            if(entry.isPending()) {
-               synchronized(entry) {
-                    if(entry.isPending()) {
-                        throw new IllegalStateException();
-//                     if(entry.procs == null) entry.procs = new ArrayList<IntProcedure>();
-//                     entry.procs.add(procedure);
-//                        provider.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                     return;
-                    }
-               }
-            }
-            provider.performForEach(graph, entry, parent, listener, procedure);
-        }
-
-    }
-    
-    final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-        
-       assert(r != 0);
-       
-       final OrderedSet entry = (OrderedSet)provider.orderedSetMap.get(r);
-       
-       if(parent == null && !(listener != null)) {
-               if(entry != null && entry.isReady()) { 
-                       entry.performFromCache(graph, provider, procedure);
-                       return;
-               }
-        }
-
-        runner(graph, r, provider, entry, parent, listener, procedure);
-         
-    }
-
-    @Override
-    public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
-        return provider.orderedSetMap.get(id);
-    }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-           provider.orderedSetMap.put(id, this);
-       }
-
        @Override
        final public void removeEntry(QueryProcessor provider) {
-        provider.orderedSetMap.remove(id);
+        provider.cache.remove(this);
        }
-    
-       private int current = 0;
 
-       private boolean nextElement(ReadGraphImpl graph, final QueryProcessor provider, final IntProcedure procedure, final boolean store) {
+       private static int nextElement(ReadGraphImpl graph, int current, int orderedSet, OrderedSet parent, final IntProcedure procedure) throws DatabaseException {
            
-               provider.querySupport.ensureLoaded(graph, current);             
+               QueryProcessor processor = graph.processor;
+               
+               processor.querySupport.ensureLoaded(graph, current);
                
-               boolean found = provider.querySupport.getObjects(graph, current, id, new IntProcedure() {
+               AtomicInteger res = new AtomicInteger(0);
+               
+               processor.querySupport.getObjects(graph, current, orderedSet, new IntProcedure() {
 
                        @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-                               if(i != id) {
-                                       addOrSet(i);
+                       public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                               if(i != orderedSet) {
                                        procedure.execute(graph, i);
                                }
-                               current = i;
+                               res.set(i);
                        }
 
                        @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
+                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                if(DebugException.DEBUG) new DebugException(t).printStackTrace();
                                procedure.exception(graph, t);
                        }
@@ -124,120 +58,35 @@ final public class OrderedSet extends CollectionUnaryQuery<IntProcedure> {
 
                });
 
-               if(!found) current = id;
-
-               if(current == id) {
-                       finish(graph, provider);
+               if(res.get() == orderedSet) {
                        procedure.finished(graph);
-                       return false;
-               } else {
-                       return true;
                }
+               
+               return res.get();
 
        }
        
     @Override
-    public void clearResult(QuerySupport support) {
-        current = id;
-        setResult(new IntArray());
+    public void compute(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException {
+        computeForEach(graph, id, this, procedure);
     }
-       
-    @Override
-    public Object computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final IntProcedure procedure, final boolean store) {
 
-        while(nextElement(graph, provider, procedure, store));
-        
-        return getResult();
+    static void computeForEach(ReadGraphImpl graph, int orderedSet, final OrderedSet entry, final IntProcedure procedure_) throws DatabaseException {
         
-    }
-    
-    @Override
-    public String toString() {
-       return "OrderedSet[" + id + "]";
-    }
-
-    final private void finish(ReadGraphImpl graph, QueryProcessor provider) {
-        
-       assert(isPending());
-
-//        ArrayList<IntProcedure> p = null;
-
-        synchronized(this) {
+        IntProcedure procedure = entry != null ? entry : procedure_;
 
-               setReady();
-//            p = procs;
-//            procs = null; 
-        
-        }
-        
-//        if(p != null) {
-//             IntArray v = (IntArray)getResult();
-//             if(v.data == null) {
-//                 if(v.sizeOrData != IntArray.NO_DATA) {
-//                     for(IntProcedure proc : p) proc.execute(graph, v.sizeOrData);
-//                 }
-//             } else {
-//                 for(IntProcedure proc : p) {
-//                     for(int i = 0;i < v.sizeOrData ; i++) proc.execute(graph, v.data[i]);
-//                 }
-//             }
-//             for(IntProcedure proc : p) proc.finished(graph);
-//        }
-
-    }
+       int current = nextElement(graph, orderedSet, orderedSet, entry, procedure);
+       while(current != orderedSet) {
+               current = nextElement(graph, current, orderedSet, entry, procedure);
+       }
 
-    final public void addOrSet(int add) {
-        
-        assert(isPending());
-        
-        IntArray value = (IntArray)getResult();
-        value.add(add);
-        
-    }
-
-    @Override
-    public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, final IntProcedure procedure) {
-       
-       assert(isReady());
-
-       if(handleException(graph, procedure)) return EXCEPTED;
+       if(entry != null) entry.performFromCache(graph, procedure_);
        
-        final IntArray value = (IntArray)getResult();
-        if(value.data == null) {
-            if(value.sizeOrData != IntArray.NO_DATA) procedure.execute(graph, value.sizeOrData);
-        } else {
-            for(int i = 0;i < value.sizeOrData ; i++) procedure.execute(graph, value.data[i]);
-        }
-
-        procedure.finished(graph);
-        
-        return value;
-        
     }
     
     @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-        
-        final Semaphore s = new Semaphore(0);
-        
-        computeForEach(graph, provider, new IntProcedureAdapter() {
-
-            @Override
-            public void finished(ReadGraphImpl graph) {
-                s.release();
-            }
-                       
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               throw new Error("Error in recompute.", t);
-            }
-
-        }, true);
-        
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
-        
+    public String toString() {
+       return "OrderedSet[" + id + "]";
     }
     
 }
index 51c6c68d3da238342828090d5a93cca1a0cb2548..d391cec9c9fc44fe4890fd8acc395d249872b37f 100644 (file)
@@ -15,6 +15,8 @@ import gnu.trove.procedure.TIntProcedure;
 import gnu.trove.set.hash.TIntHashSet;
 
 import org.simantics.db.Resource;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.procedure.ListenerBase;
@@ -36,15 +38,6 @@ final public class PossibleSuperRelation extends UnaryQuery<IntProcedure> {
 
        }
 
-       @Override
-       public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
-               return null;
-       }
-
-       @Override
-       public void putEntry(QueryProcessor provider) {
-       }
-
        @Override
        final public void removeEntry(QueryProcessor provider) {
        }
@@ -65,22 +58,11 @@ final public class PossibleSuperRelation extends UnaryQuery<IntProcedure> {
                }
 
                public int size() {
-
                        if(single == 0) return 0;
                        if(set == null) return 1;
                        return set.size() + 1;
-
                }
 
-               //        public int[] toArray() {
-                       //            
-                       //            int[] result = Arrays.copyOf(set.toArray(), set.size() + 1);
-                       //            result[set.size()] = single;
-                       //            return result;
-                       //            
-                       //        }
-               //        
-
                public void forEach(TIntProcedure proc) {
                        if(single > 0) proc.execute(single);
                        if(set != null) set.forEach(proc);
@@ -88,20 +70,22 @@ final public class PossibleSuperRelation extends UnaryQuery<IntProcedure> {
 
        }
 
-       @Override
-       public Object computeForEach(final ReadGraphImpl graph, final QueryProcessor provider, final IntProcedure procedure, final boolean store) {
+       //@Override
+       public Object compute(final ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException {
 
-               provider.querySupport.ensureLoaded(graph, id);
-               int single = provider.querySupport.getSingleSuperrelation(id);
+               QueryProcessor processor = graph.processor;
+               
+               processor.querySupport.ensureLoaded(graph, id);
+               int single = processor.querySupport.getSingleSuperrelation(id);
                if(single > 0) {
                        procedure.execute(graph, single);
                        procedure.finished(graph);
                        return single;
                }
 
-               final int subrelationOf = provider.getSubrelationOf();
+               final int subrelationOf = processor.getSubrelationOf();
 
-               final IntSet result = new IntSet(provider.querySupport);
+               final IntSet result = new IntSet(processor.querySupport);
 
                final class DirectProcedure extends Koss implements IntProcedure, TIntProcedure {
                        @Override
@@ -129,7 +113,7 @@ final public class PossibleSuperRelation extends UnaryQuery<IntProcedure> {
 
                final DirectProcedure directProc = new DirectProcedure();
 
-               provider.querySupport.getObjects(graph, id, subrelationOf, directProc);
+               processor.querySupport.getObjects(graph, id, subrelationOf, directProc);
 
                int size = directProc.size();
 
@@ -149,7 +133,11 @@ final public class PossibleSuperRelation extends UnaryQuery<IntProcedure> {
                                @Override
                                public boolean execute(int arg0) {
 
-                                       procedure.execute(graph, arg0);
+                                       try {
+                                               procedure.execute(graph, arg0);
+                                       } catch (DatabaseException e) {
+                                               Logger.defaultLogError(e);
+                                       }
                                        return true;
 
                                }
@@ -166,17 +154,16 @@ final public class PossibleSuperRelation extends UnaryQuery<IntProcedure> {
 
        @Override
        public String toString() {
-               return "SuperRelations2[" + id + "]";
+               return "PossibleSuperRelation[" + id + "]";
        }
 
        @Override
-       public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, IntProcedure procedure) {
+       public Object performFromCache(ReadGraphImpl graph, IntProcedure procedure) {
                throw new UnsupportedOperationException();
        }
 
        @Override
-       public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-
+       public void recompute(ReadGraphImpl graph) {
        }
 
 }
index 960cdb6c02aba26fe709af0fac79e1c4c28412ae..9445db03b4e048ca1488cb22f45eeaa56da9bdd1 100644 (file)
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import gnu.trove.procedure.TIntProcedure;
-
-import java.util.concurrent.Semaphore;
-
 import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.ListenerBase;
+import org.simantics.db.impl.procedure.InternalProcedure;
 import org.simantics.db.request.RequestFlags;
 
-final public class Predicates extends UnaryQuery<IntProcedure> {
-       
-//     public ArrayList<IntProcedure> procs;
-
-       public Predicates(final int r) {
-        super(r);
-    }
-
-    public static Predicates newInstance(final int r) {
-        return new Predicates(r);
-    }
-    
-    final static Predicates entry(final QueryProcessor provider, final int r) {
-        
-        return (Predicates)provider.predicatesMap.get(r);
-
-    }
-    
-    final static void runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, Predicates cached, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-
-       Predicates entry = cached != null ? cached : (Predicates)provider.predicatesMap.get(r); 
-        if(entry == null) {
-               
-               entry = new Predicates(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-            provider.performForEach(graph, entry, parent, listener, procedure);
-            
-        } else {
-               
-            if(entry.isPending()) {
-               synchronized(entry) {
-                    if(entry.isPending()) {
-                        throw new IllegalStateException();
-                    }
-               }
-            }
-            provider.performForEach(graph, entry, parent, listener, procedure);
-        }
-
-    }
-
-    final static IntSet runner2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
-
-       Predicates entry = (Predicates)provider.predicatesMap.get(r); 
-        if(entry == null) {
-               
-               entry = new Predicates(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-            return (IntSet)provider.performForEach2(graph, entry, parent, null, null);
-            
-        } else {
-               
-            if(entry.isPending()) {
-               synchronized(entry) {
-                    if(entry.isPending()) {
-                        throw new IllegalStateException();
-                    }
-               }
-            }
-            return (IntSet)provider.performForEach(graph, entry, parent, null, null);
-            
-        }
-
-    }
-    
-    final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-        
-       assert(r != 0);
-       
-       final Predicates entry = (Predicates)provider.predicatesMap.get(r);
-       
-       if(parent == null && listener == null) {
-               if(entry != null && entry.isReady()) { 
-                       entry.performFromCache(graph, provider, procedure);
-                       return;
-               }
-        }
-
-        runner(graph, r, provider, entry, parent, listener, procedure);
-         
-    }
+import gnu.trove.procedure.TIntProcedure;
 
-    final public static IntSet queryEach2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
-        
-       if(parent == null) {
-               final Predicates entry = (Predicates)provider.predicatesMap.get(r);
-               if(entry != null && entry.isReady()) {
-                       return (IntSet)entry.get(graph, provider, null);
-               }
-        }
+final public class Predicates extends UnaryQueryP<IntSet> {
 
-        return runner2(graph, r, provider, parent);
-         
-    }
-    
-    @Override
-    public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
-        return provider.predicatesMap.get(id);
+       Predicates(final int r) {
+        super(r);
     }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-           provider.predicatesMap.put(id, this);
-       }
 
        @Override
        final public void removeEntry(QueryProcessor provider) {
-        provider.predicatesMap.remove(id);
+        provider.cache.remove(this);
        }
     
-    final private void forAssertions(ReadGraphImpl graph, final QueryProcessor queryProvider, final IntProcedure procedure, final boolean store) {
+    final static private void forAssertions(ReadGraphImpl graph, int r, Predicates parent, final IntSet set) throws DatabaseException {
 
-        PrincipalTypes.queryEach(graph, id, queryProvider, store ? Predicates.this : null, null, new SyncIntProcedure() {
+       QueryCache.runnerPrincipalTypes(graph, r, parent, null, new SyncIntProcedure() {
             
             @Override
-            public void run(ReadGraphImpl graph) {
-                
-                finish(graph, queryProvider);
-                procedure.finished(graph);
-                
+            public void run(ReadGraphImpl graph) throws DatabaseException {
             }
             
             IntProcedure proc = new IntProcedure() {
 
                 @Override
-                public void execute(ReadGraphImpl graph, int i) {
-                    if(addOrSet(queryProvider, i))
-                       procedure.execute(graph, i);
+                public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                       set.add(i);
                 }
 
                 @Override
-                public void finished(ReadGraphImpl graph) {
+                public void finished(ReadGraphImpl graph) throws DatabaseException {
                     dec(graph);
                 }
                                
                                @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
+                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                     if(DebugException.DEBUG) new DebugException(t).printStackTrace();
-                                       procedure.exception(graph, t);
                    }
 
             }; 
 
             @Override
-            public void execute(ReadGraphImpl graph, int type) {
+            public void execute(ReadGraphImpl graph, int type) throws DatabaseException {
 
                inc();
-                
-                AssertedPredicates.queryEach(graph, type, queryProvider, store ? Predicates.this : null, null, proc);
+                QueryCache.runnerAssertedPredicates(graph, type, parent, null, proc);
                 
             }
             
             @Override
-            public void finished(ReadGraphImpl graph) {
+            public void finished(ReadGraphImpl graph) throws DatabaseException {
                 dec(graph);       
             }
             
@@ -188,153 +75,50 @@ final public class Predicates extends UnaryQuery<IntProcedure> {
 
     }
 
-    @Override
-    public Object computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final IntProcedure procedure, final boolean store) {
-
-               DirectPredicates.queryEach(graph, id, provider, store ? Predicates.this : null, null, new IntProcedure() {
-
-                       @Override
-                       public void execute(ReadGraphImpl graph, final int pred) {
-
-                               if(addOrSet(provider, pred))
-                                       procedure.execute(graph, pred);
-
-                       }
-
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-
-                               forAssertions(graph, provider, procedure, store);
-
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               procedure.exception(graph, t);
-                       }
+       @Override
+       public void compute(ReadGraphImpl graph, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+               computeForEach(graph, id, this, procedure);
+       }
 
-               });
-               
-               return getResult();
-        
-    }
-    
-    @Override
-    public String toString() {
-       return "Predicates2[" + id + "]";
-    }
-
-    final public void finish(final ReadGraphImpl graph, QueryProcessor provider) {
-        
-//        ArrayList<IntProcedure> p = null;
-
-        synchronized(this) {
-
-               setReady();
-//            p = procs;
-//            procs = null; 
-        
-        }
-        
-//        if(p != null) {
-//        
-//             final ArrayList<IntProcedure> finalP = p;
-//
-//             IntSet v = (IntSet)getResult();
-//             v.forEach(new TIntProcedure() {
-//
-//                     @Override
-//                     public boolean execute(int arg0) {
-//                             for(IntProcedure proc : finalP) proc.execute(graph, arg0);
-//                             return true;
-//                     }
-//
-//             });
-//
-//             for(IntProcedure proc : p) proc.finished(graph);
-//        
-//        }
-
-    }
-
-    synchronized private boolean addOrSet(QueryProcessor processor, int add) {
-
-       if(!isPending()) {
-               setResult(new IntSet(null));
-       }
-       
-       IntSet value = (IntSet)getResult();
-        return value.add(add);
-        
-    }
-
-    @Override
-    public void clearResult(QuerySupport support) {
-       setResult(new IntSet(support));
-    }
-    
-    @Override
-    public Object performFromCache(final ReadGraphImpl graph, QueryProcessor provider, final IntProcedure procedure) {
+       public static void computeForEach(ReadGraphImpl graph, final int r, final Predicates entry, final InternalProcedure<IntSet> procedure_) throws DatabaseException {
+           
+           InternalProcedure<IntSet> procedure = entry != null ? entry : procedure_;
        
-       assert(isReady());
-
-       if(handleException(graph, procedure)) return EXCEPTED;
+       IntSet direct = QueryCache.resultDirectPredicates(graph, r, entry, null);
+               
+               IntSet result = new IntSet(graph.processor.querySupport);
+       forAssertions(graph, r, entry, result);
        
-        IntSet v = getResult();
-        if(procedure != null) {
-               v.forEach(new TIntProcedure() {
-
+       if(result.isEmpty()) {
+               procedure.execute(graph, direct);
+       } else {
+               direct.forEach(new TIntProcedure() {
                        @Override
-                       public boolean execute(int arg0) {
-                               procedure.execute(graph, arg0);                                         
+                       public boolean execute(int value) {
+                               result.add(value);
                                return true;
                        }
-               });
-            procedure.finished(graph);
-        }
-        
-        return v;
+               });
+               procedure.execute(graph, result);
+       }
+       
+       if(entry != null) entry.performFromCache(graph, procedure_);
         
     }
     
     @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-        
-        final Semaphore s = new Semaphore(0);
-        
-        computeForEach(graph, provider, new IntProcedure() {
-
-            @Override
-            public void finished(ReadGraphImpl graph) {
-                s.release();
-            }
-                       
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               throw new Error("Error in recompute.", t);
-            }
-
-                       @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-                       }
+    public String toString() {
+       return "Predicates[" + id + "]";
+    }
 
-        }, true);
-        
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
-        
+    @Override
+    public void clearResult(QuerySupport support) {
+       setResult(new IntSet(support));
     }
     
     @Override
     public int type() {
         return RequestFlags.IMMEDIATE_UPDATE;
     }
-
-
-    @Override
-    boolean isImmutable(ReadGraphImpl graph) {
-       return graph.processor.isImmutable(id);
-    }
     
 }
index 25e2b6fe3d317e682d41ebf42f60c2f6a628a83d..298fcfd841f5df17c3ed68dd868040581093b342 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import gnu.trove.procedure.TIntProcedure;
-import gnu.trove.set.hash.TIntHashSet;
-
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.concurrent.Semaphore;
 
+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.IntProcedureAdapter;
 import org.simantics.db.impl.procedure.InternalProcedure;
-import org.simantics.db.procedure.ListenerBase;
 
-final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.set.hash.TIntHashSet;
 
-//     public ArrayList<IntProcedure> procs = null;
+public final class PrincipalTypes extends CollectionUnaryQuery {
 
-       private PrincipalTypes(final int resource) {
+       PrincipalTypes(final int resource) {
                super(resource);
        }
 
-       final static PrincipalTypes entry(final QueryProcessor provider, final int r) {
-               return (PrincipalTypes)provider.principalTypesMap.get(r);
-       }
-
-       final static void runner(ReadGraphImpl graph, final int r, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-
-       QueryProcessor processor = graph.processor;
-               
-               PrincipalTypes entry = (PrincipalTypes)processor.principalTypesMap.get(r); 
-               if(entry == null) {
-
-                       entry = new PrincipalTypes(r);
-               entry.setPending();
-               entry.clearResult(processor.querySupport);
-               entry.putEntry(processor);
-                       
-               processor.performForEach(graph, entry, parent, listener, procedure);
-                       
-               } else {
-                       
-            if(entry.isPending()) {
-                synchronized(entry) {
-                    if(entry.isPending()) {
-                        throw new IllegalStateException();
-//                                             if(entry.procs == null) entry.procs = new ArrayList<IntProcedure>(1);
-//                                             entry.procs.add(procedure);
-//                                             processor.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                                             return;
-                                       }
-                               }
-                       }
-            processor.performForEach(graph, entry, parent, listener, procedure);
-               }
-
-       }
-
-       final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-
-               assert(r != 0);
-
-        if(parent == null && listener == null) {
-               PrincipalTypes.computeForEach(graph, r, null, graph.processor, procedure);
-        } else {
-               runner(graph, r, parent, listener, procedure);
-        }
-
-       }
-
-       @Override
-       public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
-               return provider.principalTypesMap.get(id);
-       }
-
-       @Override
-       public void putEntry(QueryProcessor provider) {
-               provider.principalTypesMap.put(id, this);
-       }
-
        @Override
        final public void removeEntry(QueryProcessor provider) {
-               provider.principalTypesMap.remove(id);
+               provider.cache.remove(this);
        }
 
-       static class Koss {
+       static class Ints {
 
                private TIntHashSet set = null;
                public int single = 0;
@@ -134,25 +73,33 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
        }
 
        @Override
-       public Object computeForEach(final ReadGraphImpl procedureGraph, final QueryProcessor provider, final IntProcedure proc, final boolean store) {
-
-               return computeForEach(procedureGraph, id, this, provider, proc);
-               
+       public void compute(final ReadGraphImpl graph, final IntProcedure proc) throws DatabaseException {
+               computeForEach(graph, id, this, proc);
        }
        
-       public static Object computeForEach(final ReadGraphImpl graph, final int id, final PrincipalTypes entry, final QueryProcessor provider, final IntProcedure proc) {
+       public static Object computeForEach(final ReadGraphImpl graph, final int id, final PrincipalTypes entry, final IntProcedure procedure_) throws DatabaseException {
+
+           IntProcedure procedure = entry != null ? entry : procedure_;
+           
+           Object result = computeForEach2(graph, id, entry, procedure);
+           
+           if(entry != null) entry.performFromCache(graph, procedure_);
+           
+           return result;
+           
+       }
+           
+       public static Object computeForEach2(final ReadGraphImpl graph, final int id, final PrincipalTypes parent, final IntProcedure procedure) throws DatabaseException {
+
+           QueryProcessor provider = graph.processor;
                
                provider.querySupport.ensureLoaded(graph, id);
                assert(id != 0);
 
                int ret = provider.querySupport.getSingleInstance(id);
                if(ret > 0) {
-                       if(entry != null) {
-                               entry.add(ret);
-                               entry.finish(graph, provider);
-                       }
-                       proc.execute(graph, ret);
-                       proc.finished(graph);
+                       procedure.execute(graph, ret);
+                       procedure.finished(graph);
                        return ret;
                }
 
@@ -160,8 +107,8 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                final int inherits = provider.getInherits();
                final int subrelationOf = provider.getSubrelationOf();
 
-               final Koss indirect = new Koss();
-               final Koss material = new Koss();
+               final Ints indirect = new Ints();
+               final Ints material = new Ints();
 
                IntProcedure directProc = new IntProcedure() {
 
@@ -171,8 +118,8 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                        }
 
                        @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               proc.exception(graph, t);
+                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                               procedure.exception(graph, t);
                        }
 
                        @Override
@@ -189,8 +136,8 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                        }
 
                        @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               proc.exception(graph, t);
+                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                               procedure.exception(graph, t);
                        }
 
                        @Override
@@ -206,32 +153,34 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                if(indirect.size() == 0) {
                        int size = material.size(); 
                        if(size == 0) {
-                               if(entry != null) entry.finish(graph, provider);
-                               proc.finished(graph);
+                               procedure.finished(graph);
                                return null;
                        } else if(size == 1) {
                                int single = material.single; 
-                               if(entry != null) {
-                                       entry.add(single);
-                                       entry.finish(graph, provider);
-                               }
-                               proc.execute(graph, single);
-                               proc.finished(graph);
+                               procedure.execute(graph, single);
+                               procedure.finished(graph);
                                return single;
                        } else {
-                               addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, entry, proc);
+                               addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, parent, procedure);
                                return null;
                        }
                }
 
-//             final AtomicInteger finishes = new AtomicInteger(0);
-
                indirect.forEach(new TIntProcedure() {
 
                        int finishes = 0;
                        
                        @Override
                        public boolean execute(final int arg0) {
+                               try {
+                                       return execute0(arg0);
+                               } catch (DatabaseException e) {
+                                       Logger.defaultLogError(e);
+                               }
+                               return false;
+                       }
+                       
+                       public boolean execute0(final int arg0) throws DatabaseException {
 
                                // No self-loops!
                                if(arg0 == id) {
@@ -239,27 +188,22 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                                        if(current == indirect.size()) {
                                                int size = material.size(); 
                                                if(size == 0) {
-                                                       if(entry != null) entry.finish(graph, provider);
-                                                       proc.finished(graph);
+                                                       procedure.finished(graph);
                                                        return true;
                                                } else if(size == 1) {
                                                        int single = material.single; 
-                                                       if(entry != null) {
-                                                               entry.add(single);
-                                                               entry.finish(graph, provider);
-                                                       }
-                                                       proc.execute(graph, single);
-                                                       proc.finished(graph);
+                                                       procedure.execute(graph, single);
+                                                       procedure.finished(graph);
                                                        return true;
                                                } else {
-                                                       addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, entry, proc);
+                                                       addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, parent, procedure);
                                                        return true;
                                                }
                                        }
                                        return true;
                                }
 
-                               PrincipalTypes.queryEach(graph, arg0, provider, entry, null, new IntProcedure() {
+                               QueryCache.runnerPrincipalTypes(graph, arg0, parent, null, new IntProcedure() {
 
                                        @Override
                                        public void execute(ReadGraphImpl graph, int i) {
@@ -269,26 +213,21 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                                        }
 
                                        @Override
-                                       public void finished(ReadGraphImpl graph) {
+                                       public void finished(ReadGraphImpl graph) throws DatabaseException {
 
                                                int current = (++finishes);
                                                if(current == indirect.size()) {
                                                        int size = material.size(); 
                                                        if(size == 0) {
-                                                               if(entry != null) entry.finish(graph, provider);
-                                                               proc.finished(graph);
+                                                               procedure.finished(graph);
                                                                return;
                                                        } else if(size == 1) {
                                                                int single = material.single; 
-                                                               if(entry != null) {
-                                                                       entry.add(single);
-                                                                       entry.finish(graph, provider);
-                                                               }
-                                                               proc.execute(graph, single);
-                                                               proc.finished(graph);
+                                                               procedure.execute(graph, single);
+                                                               procedure.finished(graph);
                                                                return;
                                                        } else {
-                                                               addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, entry, proc);
+                                                               addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, parent, procedure);
                                                                return;
                                                        }
                                                }
@@ -296,8 +235,8 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                                        }
 
                                        @Override
-                                       public void exception(ReadGraphImpl graph, Throwable t) {
-                                               proc.exception(graph, t);
+                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                                               procedure.exception(graph, t);
                                        }
 
                                });
@@ -312,16 +251,7 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
 
        }
 
-       private static void finish(ReadGraphImpl graph, final TIntHashSet rejects, final int[] material, final PrincipalTypes entry, final QueryProcessor provider, final IntProcedure proc) {
-
-               if(entry != null) {
-                       for(int i : material) {
-                               if(!rejects.contains(i)) {
-                                       entry.add(i);
-                               }
-                       }
-                       entry.finish(graph, provider);
-               }
+       private static void finish(ReadGraphImpl graph, final TIntHashSet rejects, final int[] material, final IntProcedure proc) throws DatabaseException {
 
                for(int i : material) {
                        if(!rejects.contains(i)) {
@@ -335,29 +265,28 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
 
        }
 
-       private static void addPrincipalType(final ReadGraphImpl graph, final TIntHashSet rejects, final int[] material, int index, final QueryProcessor provider, final PrincipalTypes entry, final IntProcedure proc) {
-
-               //        if((counter++ % 500) == 0) System.out.println("PT " + counter + " mat = " + material.length);
+       private static void addPrincipalType(final ReadGraphImpl graph, final TIntHashSet rejects, final int[] material, int index, final QueryProcessor provider, final PrincipalTypes parent, final IntProcedure proc) throws DatabaseException {
 
                if(index == material.length) { 
-                       finish(graph, rejects, material, entry, provider, proc);
+                       finish(graph, rejects, material, proc);
                        return;
                }
 
                int type = material[index++];
                while(rejects.contains(type)) {
                        if(index == material.length) { 
-                               finish(graph, rejects, material, entry, provider, proc);
+                               finish(graph, rejects, material, proc);
                                return;
                        }
                        type = material[index++];
                }
+               
                final int nextIndex = index;
 
-               SuperTypes.queryEach(graph, type, provider, entry, null, new InternalProcedure<IntSet>() {
+               QueryCache.runnerSuperTypes(graph, type, parent, null, new InternalProcedure<IntSet>() {
 
                        @Override
-                       public void execute(ReadGraphImpl graph, IntSet supers) {
+                       public void execute(ReadGraphImpl graph, IntSet supers) throws DatabaseException {
 
                                synchronized(rejects) {
 
@@ -373,12 +302,12 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
 
                                }
 
-                               addPrincipalType(graph, rejects, material, nextIndex, provider, entry, proc);
+                               addPrincipalType(graph, rejects, material, nextIndex, provider, parent, proc);
 
                        }
 
                        @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
+                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                proc.exception(graph, t);
                        }
 
@@ -390,104 +319,9 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
        public String toString() {
                return "PrincipalTypes[" + id + "]";
        }
-
-       final private void add(int val) {
-               assert(isPending());
-               IntArray v = (IntArray)getResult();
-               v.add(val);
-       }
-
-       final private void finish(ReadGraphImpl graph, QueryProcessor provider) {
-
-               assert(isPending());
-
-//             ArrayList<IntProcedure> p = null;
-
-               synchronized(this) {
-
-                       setReady();
-//                     p = procs;
-//                     procs = null;
-
-               }
-
-//             if(p != null) {
-//
-//                     IntArray v = (IntArray)getResult();
-//                     if(v != null) {
-//                             if(v.data == null) {
-//                                     if(v.sizeOrData != IntArray.NO_DATA) {
-//                                             for(IntProcedure proc : p) proc.execute(graph, v.sizeOrData);
-//                                     }
-//                             } else {
-//                                     for(IntProcedure proc : p) {
-//                                             for(int i = 0;i < v.sizeOrData ; i++) proc.execute(graph, v.data[i]);
-//                                     }
-//                             }
-//                     }
-//
-//                     for(IntProcedure proc : p) proc.finished(graph);
-//
-//             }
-
-
-       }
-
-       @Override
-       public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, final IntProcedure procedure) {
-
-               assert(isReady());
-
-       if(handleException(graph, procedure)) return EXCEPTED;
-               
-               final IntArray value = (IntArray)getResult();
-               if(value.data == null) {
-                       if(value.sizeOrData != IntArray.NO_DATA) procedure.execute(graph, value.sizeOrData);
-               } else {
-                       for(int i = 0;i < value.sizeOrData ; i++) procedure.execute(graph, value.data[i]);
-               }
-
-               procedure.finished(graph);
-               
-               return getResult();
-
-       }
-
-       @Override
-       public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-
-               final Semaphore s = new Semaphore(0);
-
-               computeForEach(graph, provider, new IntProcedureAdapter() {
-
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               s.release();
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               s.release();
-                               new Error("Error in recompute.", t).printStackTrace();
-                       }
-
-               }, true);
-
-       while(!s.tryAcquire()) {
-               provider.resume(graph);
-       }
-
-       }
-
-
-    @Override
-    boolean isImmutable(ReadGraphImpl graph) {
-       return graph.processor.isImmutable(id);
-    }
     
     @Override
-    protected void fillImpliedParents(QueryProcessor processor, ArrayList<CacheEntry> result) {
-//             for(Objects o : Objects.entries(processor, id)) result.add(o);
+    protected void fillImpliedParents(QueryProcessor processor, ArrayList<CacheEntry<?>> result) {
     }
 
 }
index 29ba90e11cd250fc0aa2b02376faa804e208669a..22c970f31c326f202bc98b0dfe2171d5f1b4a676 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 
-
-
 /*
  * The following methods need to be properly implemented
  * - equals()
- * - hashCode()  
+ * - hashCode()
  */
 public interface Query {
 
-       
-       void recompute(ReadGraphImpl graph, Object provider, CacheEntry entry);
+    void recompute(ReadGraphImpl graph) throws DatabaseException;
     void removeEntry(QueryProcessor processor);
     int type(); 
-    
+
 }
diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java
new file mode 100644 (file)
index 0000000..7b591ab
--- /dev/null
@@ -0,0 +1,1048 @@
+package org.simantics.db.impl.query;
+
+import org.simantics.db.ObjectResourceIdMap;
+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;
+import org.simantics.db.impl.query.QueryProcessor.SessionTask;
+import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.procedure.ListenerBase;
+import org.simantics.db.procedure.SyncMultiProcedure;
+import org.simantics.db.request.AsyncMultiRead;
+import org.simantics.db.request.AsyncRead;
+import org.simantics.db.request.ExternalRead;
+import org.simantics.db.request.MultiRead;
+import org.simantics.db.request.Read;
+
+public class QueryCache extends QueryCacheBase {
+
+    public QueryCache(QuerySupport querySupport, int threads) {
+        super(querySupport, threads);
+    }
+
+    Objects getOrCreateObjects(QueryProcessor processor, int r1, int r2) throws DatabaseException {
+        Objects existing = null;
+        synchronized(objectsMap) {
+            existing = (Objects)objectsMap.get(r1,r2);
+            if(existing == null) {
+                existing = new Objects(r1,r2);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                objectsMap.put(keyR2(r1,r2), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(Objects entry) {
+        synchronized(objectsMap) {
+            objectsMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerObjects(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r1,r2)) {
+            Objects.computeForEach(graph, r1,r2, null, procedure);
+            return;
+        }
+        Objects entry = (Objects)cache.getOrCreateObjects(graph.processor, r1,r2);
+        IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureObjects;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            Objects.computeForEach(graph, r1,r2, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    Statements getOrCreateStatements(QueryProcessor processor, int r1, int r2) throws DatabaseException {
+        Statements existing = null;
+        synchronized(statementsMap) {
+            existing = (Statements)statementsMap.get(r1,r2);
+            if(existing == null) {
+                existing = new Statements(r1,r2);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                statementsMap.put(keyR2(r1,r2), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(Statements entry) {
+        synchronized(statementsMap) {
+            statementsMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, final TripleIntProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r1,r2)) {
+            Statements.computeForEach(graph, r1,r2, null, procedure);
+            return;
+        }
+        Statements entry = (Statements)cache.getOrCreateStatements(graph.processor, r1,r2);
+        TripleIntProcedure procedure_ = procedure != null ? procedure : emptyProcedureStatements;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            Statements.computeForEach(graph, r1,r2, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    DirectObjects getOrCreateDirectObjects(QueryProcessor processor, int r1, int r2) throws DatabaseException {
+        DirectObjects existing = null;
+        synchronized(directObjectsMap) {
+            existing = (DirectObjects)directObjectsMap.get(r1,r2);
+            if(existing == null) {
+                existing = new DirectObjects(r1,r2);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                directObjectsMap.put(keyR2(r1,r2), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(DirectObjects entry) {
+        synchronized(directObjectsMap) {
+            directObjectsMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerDirectObjects(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r1,r2)) {
+            DirectObjects.computeForEach(graph, r1,r2, null, procedure);
+            return;
+        }
+        DirectObjects entry = (DirectObjects)cache.getOrCreateDirectObjects(graph.processor, r1,r2);
+        IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureDirectObjects;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            DirectObjects.computeForEach(graph, r1,r2, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    RelationInfoQuery getOrCreateRelationInfoQuery(QueryProcessor processor, int r) throws DatabaseException {
+        RelationInfoQuery existing = null;
+        synchronized(relationInfoQueryMap) {
+            existing = (RelationInfoQuery)relationInfoQueryMap.get(r);
+            if(existing == null) {
+                existing = new RelationInfoQuery(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                relationInfoQueryMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(RelationInfoQuery entry) {
+        synchronized(relationInfoQueryMap) {
+            relationInfoQueryMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerRelationInfoQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure<RelationInfo> procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            RelationInfoQuery.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        RelationInfoQuery entry = (RelationInfoQuery)cache.getOrCreateRelationInfoQuery(graph.processor, r);
+        InternalProcedure<RelationInfo> procedure_ = procedure != null ? procedure : emptyProcedureRelationInfoQuery;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            RelationInfoQuery.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    URIToResource getOrCreateURIToResource(QueryProcessor processor, String id) throws DatabaseException {
+        URIToResource existing = null;
+        synchronized(uRIToResourceMap) {
+            existing = (URIToResource)uRIToResourceMap.get(id);
+            if(existing == null) {
+                existing = new URIToResource(id);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                uRIToResourceMap.put(keyID(id), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(URIToResource entry) {
+        synchronized(uRIToResourceMap) {
+            uRIToResourceMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerURIToResource(ReadGraphImpl graph, String id, CacheEntry parent, ListenerBase listener, final InternalProcedure<Integer> procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, id)) {
+            URIToResource.computeForEach(graph, id, null, procedure);
+            return;
+        }
+        URIToResource entry = (URIToResource)cache.getOrCreateURIToResource(graph.processor, id);
+        InternalProcedure<Integer> procedure_ = procedure != null ? procedure : emptyProcedureURIToResource;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            URIToResource.computeForEach(graph, id, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    ValueQuery getOrCreateValueQuery(QueryProcessor processor, int r) throws DatabaseException {
+        ValueQuery existing = null;
+        synchronized(valueQueryMap) {
+            existing = (ValueQuery)valueQueryMap.get(r);
+            if(existing == null) {
+                existing = new ValueQuery(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                valueQueryMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(ValueQuery entry) {
+        synchronized(valueQueryMap) {
+            valueQueryMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerValueQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure<byte[]> procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            ValueQuery.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        ValueQuery entry = (ValueQuery)cache.getOrCreateValueQuery(graph.processor, r);
+        InternalProcedure<byte[]> procedure_ = procedure != null ? procedure : emptyProcedureValueQuery;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            ValueQuery.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    OrderedSet getOrCreateOrderedSet(QueryProcessor processor, int r) throws DatabaseException {
+        OrderedSet existing = null;
+        synchronized(orderedSetMap) {
+            existing = (OrderedSet)orderedSetMap.get(r);
+            if(existing == null) {
+                existing = new OrderedSet(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                orderedSetMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(OrderedSet entry) {
+        synchronized(orderedSetMap) {
+            orderedSetMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerOrderedSet(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            OrderedSet.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        OrderedSet entry = (OrderedSet)cache.getOrCreateOrderedSet(graph.processor, r);
+        IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureOrderedSet;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            OrderedSet.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    PrincipalTypes getOrCreatePrincipalTypes(QueryProcessor processor, int r) throws DatabaseException {
+        PrincipalTypes existing = null;
+        synchronized(principalTypesMap) {
+            existing = (PrincipalTypes)principalTypesMap.get(r);
+            if(existing == null) {
+                existing = new PrincipalTypes(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                principalTypesMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(PrincipalTypes entry) {
+        synchronized(principalTypesMap) {
+            principalTypesMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerPrincipalTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            PrincipalTypes.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        PrincipalTypes entry = (PrincipalTypes)cache.getOrCreatePrincipalTypes(graph.processor, r);
+        IntProcedure procedure_ = procedure != null ? procedure : emptyProcedurePrincipalTypes;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            PrincipalTypes.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    DirectPredicates getOrCreateDirectPredicates(QueryProcessor processor, int r) throws DatabaseException {
+        DirectPredicates existing = null;
+        synchronized(directPredicatesMap) {
+            existing = (DirectPredicates)directPredicatesMap.get(r);
+            if(existing == null) {
+                existing = new DirectPredicates(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                directPredicatesMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(DirectPredicates entry) {
+        synchronized(directPredicatesMap) {
+            directPredicatesMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerDirectPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            DirectPredicates.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        DirectPredicates entry = (DirectPredicates)cache.getOrCreateDirectPredicates(graph.processor, r);
+        InternalProcedure<IntSet> procedure_ = procedure != null ? procedure : emptyProcedureDirectPredicates;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            DirectPredicates.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    Predicates getOrCreatePredicates(QueryProcessor processor, int r) throws DatabaseException {
+        Predicates existing = null;
+        synchronized(predicatesMap) {
+            existing = (Predicates)predicatesMap.get(r);
+            if(existing == null) {
+                existing = new Predicates(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                predicatesMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(Predicates entry) {
+        synchronized(predicatesMap) {
+            predicatesMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            Predicates.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        Predicates entry = (Predicates)cache.getOrCreatePredicates(graph.processor, r);
+        InternalProcedure<IntSet> procedure_ = procedure != null ? procedure : emptyProcedurePredicates;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            Predicates.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    ReadEntry getOrCreateReadEntry(QueryProcessor processor, Read<?> r, boolean isSync) throws DatabaseException {
+        ReadEntry existing = null;
+        synchronized(readEntryMap) {
+            existing = (ReadEntry)readEntryMap.get(r);
+            if(existing == null) {
+                existing = new ReadEntry(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                readEntryMap.put(id(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) {
+          if(isSync) waitPending(processor, existing);
+          else return null;
+        }
+        return existing;
+    }
+    
+    void remove(ReadEntry entry) {
+        synchronized(readEntryMap) {
+            readEntryMap.remove(entry.request);
+        }
+    }
+    
+    public static void runnerReadEntry(ReadGraphImpl graph, Read<?> r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure, boolean isSync) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            ReadEntry.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        ReadEntry entry = (ReadEntry)cache.getOrCreateReadEntry(graph.processor, r, isSync);
+        if(entry == null) {
+            graph.processor.schedule(new SessionTask(false) {
+                @Override
+                public void run(int thread) {
+                    try {
+                        assert(!isSync);
+                        runnerReadEntry(graph, r, parent, listener, procedure, isSync);
+                    } catch (DatabaseException e) {
+                        Logger.defaultLogError(e);
+                    }
+                }
+            });
+            return;
+        }
+        AsyncProcedure procedure_ = procedure != null ? procedure : emptyProcedureReadEntry;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            ReadEntry.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    AsyncReadEntry getOrCreateAsyncReadEntry(QueryProcessor processor, AsyncRead<?> r, boolean isSync) throws DatabaseException {
+        AsyncReadEntry existing = null;
+        synchronized(asyncReadEntryMap) {
+            existing = (AsyncReadEntry)asyncReadEntryMap.get(r);
+            if(existing == null) {
+                existing = new AsyncReadEntry(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                asyncReadEntryMap.put(id(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) {
+          if(isSync) waitPending(processor, existing);
+          else return null;
+        }
+        return existing;
+    }
+    
+    void remove(AsyncReadEntry entry) {
+        synchronized(asyncReadEntryMap) {
+            asyncReadEntryMap.remove(entry.request);
+        }
+    }
+    
+    public static void runnerAsyncReadEntry(ReadGraphImpl graph, AsyncRead<?> r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure, boolean isSync) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            AsyncReadEntry.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        AsyncReadEntry entry = (AsyncReadEntry)cache.getOrCreateAsyncReadEntry(graph.processor, r, isSync);
+        if(entry == null) {
+            graph.processor.schedule(new SessionTask(false) {
+                @Override
+                public void run(int thread) {
+                    try {
+                        assert(!isSync);
+                        runnerAsyncReadEntry(graph, r, parent, listener, procedure, isSync);
+                    } catch (DatabaseException e) {
+                        Logger.defaultLogError(e);
+                    }
+                }
+            });
+            return;
+        }
+        AsyncProcedure procedure_ = procedure != null ? procedure : emptyProcedureAsyncReadEntry;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            AsyncReadEntry.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    Types getOrCreateTypes(QueryProcessor processor, int r) throws DatabaseException {
+        Types existing = null;
+        synchronized(typesMap) {
+            existing = (Types)typesMap.get(r);
+            if(existing == null) {
+                existing = new Types(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                typesMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(Types entry) {
+        synchronized(typesMap) {
+            typesMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            Types.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        Types entry = (Types)cache.getOrCreateTypes(graph.processor, r);
+        InternalProcedure<IntSet> procedure_ = procedure != null ? procedure : emptyProcedureTypes;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            Types.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    ChildMap getOrCreateChildMap(QueryProcessor processor, int r) throws DatabaseException {
+        ChildMap existing = null;
+        synchronized(childMapMap) {
+            existing = (ChildMap)childMapMap.get(r);
+            if(existing == null) {
+                existing = new ChildMap(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                childMapMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(ChildMap entry) {
+        synchronized(childMapMap) {
+            childMapMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerChildMap(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure<ObjectResourceIdMap<String>> procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            ChildMap.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        ChildMap entry = (ChildMap)cache.getOrCreateChildMap(graph.processor, r);
+        InternalProcedure<ObjectResourceIdMap<String>> procedure_ = procedure != null ? procedure : emptyProcedureChildMap;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            ChildMap.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    TypeHierarchy getOrCreateTypeHierarchy(QueryProcessor processor, int r) throws DatabaseException {
+        TypeHierarchy existing = null;
+        synchronized(typeHierarchyMap) {
+            existing = (TypeHierarchy)typeHierarchyMap.get(r);
+            if(existing == null) {
+                existing = new TypeHierarchy(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                typeHierarchyMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(TypeHierarchy entry) {
+        synchronized(typeHierarchyMap) {
+            typeHierarchyMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerTypeHierarchy(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            TypeHierarchy.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        TypeHierarchy entry = (TypeHierarchy)cache.getOrCreateTypeHierarchy(graph.processor, r);
+        InternalProcedure<IntSet> procedure_ = procedure != null ? procedure : emptyProcedureTypeHierarchy;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            TypeHierarchy.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    SuperTypes getOrCreateSuperTypes(QueryProcessor processor, int r) throws DatabaseException {
+        SuperTypes existing = null;
+        synchronized(superTypesMap) {
+            existing = (SuperTypes)superTypesMap.get(r);
+            if(existing == null) {
+                existing = new SuperTypes(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                superTypesMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(SuperTypes entry) {
+        synchronized(superTypesMap) {
+            superTypesMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerSuperTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            SuperTypes.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        SuperTypes entry = (SuperTypes)cache.getOrCreateSuperTypes(graph.processor, r);
+        InternalProcedure<IntSet> procedure_ = procedure != null ? procedure : emptyProcedureSuperTypes;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            SuperTypes.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    SuperRelations getOrCreateSuperRelations(QueryProcessor processor, int r) throws DatabaseException {
+        SuperRelations existing = null;
+        synchronized(superRelationsMap) {
+            existing = (SuperRelations)superRelationsMap.get(r);
+            if(existing == null) {
+                existing = new SuperRelations(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                superRelationsMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(SuperRelations entry) {
+        synchronized(superRelationsMap) {
+            superRelationsMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) {
+            SuperRelations.computeForEach(graph, r, null, procedure);
+            return;
+        }
+        SuperRelations entry = (SuperRelations)cache.getOrCreateSuperRelations(graph.processor, r);
+        InternalProcedure<IntSet> procedure_ = procedure != null ? procedure : emptyProcedureSuperRelations;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            SuperRelations.computeForEach(graph, r, entry, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    AssertedPredicates getOrCreateAssertedPredicates(QueryProcessor processor, int r) throws DatabaseException {
+        AssertedPredicates existing = null;
+        synchronized(assertedPredicatesMap) {
+            existing = (AssertedPredicates)assertedPredicatesMap.get(r);
+            if(existing == null) {
+                existing = new AssertedPredicates(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                assertedPredicatesMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(AssertedPredicates entry) {
+        synchronized(assertedPredicatesMap) {
+            assertedPredicatesMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerAssertedPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        AssertedPredicates entry = (AssertedPredicates)cache.getOrCreateAssertedPredicates(graph.processor, r);
+        IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureAssertedPredicates;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            entry.compute(graph, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    AssertedStatements getOrCreateAssertedStatements(QueryProcessor processor, int r1, int r2) throws DatabaseException {
+        AssertedStatements existing = null;
+        synchronized(assertedStatementsMap) {
+            existing = (AssertedStatements)assertedStatementsMap.get(r1,r2);
+            if(existing == null) {
+                existing = new AssertedStatements(r1,r2);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                assertedStatementsMap.put(keyR2(r1,r2), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(AssertedStatements entry) {
+        synchronized(assertedStatementsMap) {
+            assertedStatementsMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerAssertedStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, final TripleIntProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        AssertedStatements entry = (AssertedStatements)cache.getOrCreateAssertedStatements(graph.processor, r1,r2);
+        TripleIntProcedure procedure_ = procedure != null ? procedure : emptyProcedureAssertedStatements;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            entry.compute(graph, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    DirectSuperRelations getOrCreateDirectSuperRelations(QueryProcessor processor, int r) throws DatabaseException {
+        DirectSuperRelations existing = null;
+        synchronized(directSuperRelationsMap) {
+            existing = (DirectSuperRelations)directSuperRelationsMap.get(r);
+            if(existing == null) {
+                existing = new DirectSuperRelations(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                directSuperRelationsMap.put(keyR(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(DirectSuperRelations entry) {
+        synchronized(directSuperRelationsMap) {
+            directSuperRelationsMap.remove(entry.id);
+        }
+    }
+    
+    public static void runnerDirectSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        DirectSuperRelations entry = (DirectSuperRelations)cache.getOrCreateDirectSuperRelations(graph.processor, r);
+        IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureDirectSuperRelations;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            entry.compute(graph, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    MultiReadEntry getOrCreateMultiReadEntry(QueryProcessor processor, MultiRead<?> r) throws DatabaseException {
+        MultiReadEntry existing = null;
+        synchronized(multiReadEntryMap) {
+            existing = (MultiReadEntry)multiReadEntryMap.get(r);
+            if(existing == null) {
+                existing = new MultiReadEntry(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                multiReadEntryMap.put(id(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(MultiReadEntry entry) {
+        synchronized(multiReadEntryMap) {
+            multiReadEntryMap.remove(entry.request);
+        }
+    }
+    
+    public static void runnerMultiReadEntry(ReadGraphImpl graph, MultiRead<?> r, CacheEntry parent, ListenerBase listener, final SyncMultiProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        MultiReadEntry entry = (MultiReadEntry)cache.getOrCreateMultiReadEntry(graph.processor, r);
+        SyncMultiProcedure procedure_ = procedure != null ? procedure : emptyProcedureMultiReadEntry;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            entry.compute(graph, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    AsyncMultiReadEntry getOrCreateAsyncMultiReadEntry(QueryProcessor processor, AsyncMultiRead<?> r) throws DatabaseException {
+        AsyncMultiReadEntry existing = null;
+        synchronized(asyncMultiReadEntryMap) {
+            existing = (AsyncMultiReadEntry)asyncMultiReadEntryMap.get(r);
+            if(existing == null) {
+                existing = new AsyncMultiReadEntry(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                asyncMultiReadEntryMap.put(id(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(AsyncMultiReadEntry entry) {
+        synchronized(asyncMultiReadEntryMap) {
+            asyncMultiReadEntryMap.remove(entry.request);
+        }
+    }
+    
+    public static void runnerAsyncMultiReadEntry(ReadGraphImpl graph, AsyncMultiRead<?> r, CacheEntry parent, ListenerBase listener, final AsyncMultiProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        AsyncMultiReadEntry entry = (AsyncMultiReadEntry)cache.getOrCreateAsyncMultiReadEntry(graph.processor, r);
+        AsyncMultiProcedure procedure_ = procedure != null ? procedure : emptyProcedureAsyncMultiReadEntry;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            entry.compute(graph, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+    ExternalReadEntry getOrCreateExternalReadEntry(QueryProcessor processor, ExternalRead<?> r) throws DatabaseException {
+        ExternalReadEntry existing = null;
+        synchronized(externalReadEntryMap) {
+            existing = (ExternalReadEntry)externalReadEntryMap.get(r);
+            if(existing == null) {
+                existing = new ExternalReadEntry(r);
+                existing.clearResult(querySupport);
+                existing.setPending();
+                externalReadEntryMap.put(id(r), existing);
+                size++;
+                return existing;
+            }
+            if(existing.requiresComputation()) {
+                existing.setPending();
+                return existing;
+            }
+        }
+        if(existing.isPending()) waitPending(processor, existing);
+        return existing;
+    }
+    
+    void remove(ExternalReadEntry entry) {
+        synchronized(externalReadEntryMap) {
+            externalReadEntryMap.remove(entry.request);
+        }
+    }
+    
+    public static void runnerExternalReadEntry(ReadGraphImpl graph, ExternalRead<?> r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure) throws DatabaseException {
+        QueryCache cache  = graph.processor.cache;
+        ExternalReadEntry entry = (ExternalReadEntry)cache.getOrCreateExternalReadEntry(graph.processor, r);
+        AsyncProcedure procedure_ = procedure != null ? procedure : emptyProcedureExternalReadEntry;
+        ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);
+        if(entry.isReady()) entry.performFromCache(graph, procedure_);
+        else {
+          assert(entry.isPending());
+            entry.compute(graph, procedure_);
+            if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());
+        }
+    }
+    
+}
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
new file mode 100644 (file)
index 0000000..b3d1c5f
--- /dev/null
@@ -0,0 +1,1215 @@
+package org.simantics.db.impl.query;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.simantics.db.AsyncReadGraph;
+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.DebugPolicy;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.impl.procedure.InternalProcedure;
+import org.simantics.db.impl.query.QueryProcessor.SessionTask;
+import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.procedure.Listener;
+import org.simantics.db.procedure.ListenerBase;
+import org.simantics.db.procedure.Procedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
+import org.simantics.db.request.AsyncMultiRead;
+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 gnu.trove.map.hash.THashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+
+public class QueryCacheBase {
+
+       // Statistics
+       final int THREADS;
+       public final int THREAD_MASK;
+       int                                             hits                  = 0;
+       int                                             misses                = 0;
+       int                                             updates               = 0;
+       public int                                              size                  = 0;
+
+       public volatile boolean dirty = false;
+       public boolean collecting = false;
+
+       protected final THashMap<String, URIToResource>                           uRIToResourceMap;
+       //protected final THashMap<String, NamespaceIndex>                          namespaceIndexMap;
+       protected final UnaryQueryHashMap<InternalProcedure<ObjectResourceIdMap<String>>> childMapMap;
+       protected final DoubleKeyQueryHashMap<IntProcedure>                       objectsMap;
+       protected final DoubleKeyQueryHashMap<TripleIntProcedure>                 assertedStatementsMap;
+       protected final DoubleKeyQueryHashMap<IntProcedure>                       directObjectsMap;
+       protected final DoubleKeyQueryHashMap<TripleIntProcedure>                 statementsMap;
+       protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              typesMap;
+       protected final UnaryQueryHashMap<IntProcedure>                           principalTypesMap;
+       protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              predicatesMap;
+       protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              superTypesMap;
+       protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              typeHierarchyMap;
+       protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              superRelationsMap;
+
+       protected final UnaryQueryHashMap<IntProcedure>                           orderedSetMap;
+       protected final UnaryQueryHashMap<IntProcedure>                           assertedPredicatesMap;
+       protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              directPredicatesMap;
+       protected final UnaryQueryHashMap<IntProcedure>                           directSuperRelationsMap;
+
+       protected final UnaryQueryHashMap<InternalProcedure<RelationInfo>>        relationInfoQueryMap;
+       protected final UnaryQueryHashMap<InternalProcedure<byte[]>>              valueQueryMap;
+
+       protected final StableHashMap<AsyncRead, AsyncReadEntry>                  asyncReadEntryMap; 
+       protected final StableHashMap<Read, ReadEntry>                            readEntryMap;
+       protected final StableHashMap<MultiRead, MultiReadEntry>                  multiReadEntryMap; 
+       protected final StableHashMap<AsyncMultiRead, AsyncMultiReadEntry>        asyncMultiReadEntryMap; 
+       protected final StableHashMap<ExternalRead, ExternalReadEntry>            externalReadEntryMap; 
+
+       final THashMap<CacheEntry, ArrayList<ListenerEntry>>                      listeners;
+
+       public final QuerySupport                                                 querySupport;
+
+       public QueryCacheBase(QuerySupport querySupport, int threads) {
+
+               THREADS = threads;
+               THREAD_MASK = threads - 1;
+
+               this.querySupport = querySupport;
+               directPredicatesMap = new UnaryQueryHashMap();
+               directSuperRelationsMap = new UnaryQueryHashMap();
+               valueQueryMap = new UnaryQueryHashMap();
+               principalTypesMap = new UnaryQueryHashMap();
+               uRIToResourceMap = new THashMap<String, URIToResource>();
+               //namespaceIndexMap = new THashMap<String, NamespaceIndex>();
+               childMapMap = new UnaryQueryHashMap<InternalProcedure<ObjectResourceIdMap<String>>>();
+               relationInfoQueryMap = new UnaryQueryHashMap();
+               typeHierarchyMap = new UnaryQueryHashMap();
+               superTypesMap = new UnaryQueryHashMap();
+               superRelationsMap = new UnaryQueryHashMap();
+               typesMap = new UnaryQueryHashMap();
+               objectsMap = new DoubleKeyQueryHashMap();
+               orderedSetMap = new UnaryQueryHashMap();
+               predicatesMap = new UnaryQueryHashMap();
+               statementsMap = new DoubleKeyQueryHashMap();
+               directObjectsMap = new DoubleKeyQueryHashMap();
+               assertedPredicatesMap = new UnaryQueryHashMap();
+               assertedStatementsMap = new DoubleKeyQueryHashMap();
+               asyncReadEntryMap = new StableHashMap<AsyncRead, AsyncReadEntry>(); 
+               readEntryMap = new StableHashMap<Read, ReadEntry>();
+               asyncMultiReadEntryMap = new StableHashMap<AsyncMultiRead, AsyncMultiReadEntry>(); 
+               multiReadEntryMap = new StableHashMap<MultiRead, MultiReadEntry>(); 
+               externalReadEntryMap = new StableHashMap<ExternalRead, ExternalReadEntry>(); 
+               listeners = new THashMap<CacheEntry, ArrayList<ListenerEntry>>(10, 0.75f);
+       }
+
+//     public <T> Object performQuery(ReadGraphImpl parentGraph, final AsyncRead<T> query, final CacheEntryBase entry_, AsyncProcedure procedure_) throws DatabaseException {
+//
+//             AsyncReadEntry<T> entry = (AsyncReadEntry<T>)entry_;
+//             AsyncProcedure<T> procedure = (AsyncProcedure<T>)procedure_;
+//
+//             ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
+//
+//             try {
+//                     
+//                     query.perform(queryGraph, new AsyncProcedure<T>() {
+//
+//                             @Override
+//                             public void execute(AsyncReadGraph returnGraph, T result) {
+//                                     ReadGraphImpl impl = (ReadGraphImpl)returnGraph;
+//                                     entry.addOrSet(parentGraph, result);
+//                                     try {
+//                                             procedure.execute(parentGraph, result);
+//                                     } catch (Throwable t) {
+//                                             t.printStackTrace();
+//                                     }
+////                                   parentBarrier.dec(query);
+//                             }
+//
+//                             @Override
+//                             public void exception(AsyncReadGraph returnGraph, Throwable t) {
+//                                     ReadGraphImpl impl = (ReadGraphImpl)returnGraph;
+////                                   AsyncReadGraph resumeGraph = finalParentGraph.newAsync();
+//                                     entry.except(parentGraph, t);
+//                                     try {
+//                                             procedure.exception(parentGraph, t);
+//                                     } catch (Throwable t2) {
+//                                             t2.printStackTrace();
+//                                     }
+////                                   parentBarrier.dec(query);
+//                             }
+//
+//                             @Override
+//                             public String toString() {
+//                                     return procedure.toString();
+//                             }
+//
+//                     });
+//
+//             } catch (Throwable t) {
+//
+//                     entry.except(t);
+//                     try {
+//                             procedure.exception(parentGraph, t);
+//                     } catch (Throwable t2) {
+//                             t2.printStackTrace();
+//                     }
+////                   parentBarrier.dec(query);
+//
+//             }
+//             
+//             return null;
+//             
+//     }
+
+//     public <T> Object performQuery(ReadGraphImpl parentGraph, final Read<T> query, final CacheEntryBase entry_, AsyncProcedure procedure_) throws DatabaseException {
+//
+//             ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
+//
+//             ReadEntry entry = (ReadEntry)entry_;
+//
+//             try {
+//
+//                     T result = (T)query.perform(queryGraph);
+//                     entry.addOrSet(queryGraph, result);
+//
+//                     return (T)entry.get(parentGraph, procedure_);
+//
+//             }  catch (Throwable t) {
+//
+//                     entry.except(t);
+//                     return (T)entry.get(parentGraph, procedure_);
+//
+//             }
+//             
+//     }
+
+       public <T> Object performQuery(ReadGraphImpl parentGraph, final ExternalRead<T> query, final CacheEntryBase entry_, AsyncProcedure procedure_) throws DatabaseException {
+
+               ExternalReadEntry entry = (ExternalReadEntry)entry_;
+               AsyncProcedure<T> procedure = (AsyncProcedure<T>)procedure_;
+               
+               try {
+
+                       query.register(parentGraph, new Listener<T>() {
+
+                               AtomicBoolean used = new AtomicBoolean(false);
+
+                               @Override
+                               public void execute(T result) {
+
+                                       // Just for safety
+                                       if(entry.isDiscarded()) return;
+
+                                       if(used.compareAndSet(false, true)) {
+                                               //entry.setPending();
+                                               entry.addOrSet(parentGraph.processor, result);
+                                               procedure.execute(parentGraph, result);
+                                       } else {
+                                               entry.queue(result);
+                                               parentGraph.processor.updatePrimitive(query);
+                                       }
+
+                               }
+
+                               @Override
+                               public void exception(Throwable t) {
+
+                                       entry.except(t);
+
+                                       if(used.compareAndSet(false, true)) {
+                                               procedure.exception(parentGraph, t);
+                                       } else {
+//                                             entry.queue(result);
+                                               parentGraph.processor.updatePrimitive(query);
+                                       }
+
+                               }
+
+                               @Override
+                               public String toString() {
+                                       return procedure.toString();
+                               }
+
+                               @Override
+                               public boolean isDisposed() {
+                                       return entry.isDiscarded() || !parentGraph.processor.isBound(entry);
+                               }
+
+                       });
+
+                       return entry.getResult();
+
+               } catch (Throwable t) {
+
+                       entry.except(t);
+                       procedure.exception(parentGraph, t);
+                       return entry.getResult();
+
+               }
+
+       }
+
+       public <T> Object performQuery(ReadGraphImpl parentGraph, final AsyncMultiRead<T> query, final CacheEntryBase entry_, Object procedure_) throws DatabaseException {
+
+               ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
+
+               AsyncMultiReadEntry entry = (AsyncMultiReadEntry)entry_;
+               AsyncMultiProcedure<T> procedure = (AsyncMultiProcedure<T>)procedure_;
+
+               try {
+
+                       query.perform(queryGraph, new AsyncMultiProcedure<T>() {
+
+                               @Override
+                               public void execute(AsyncReadGraph graph, T result) {
+                                       ReadGraphImpl impl = (ReadGraphImpl)graph;
+                                       entry.addOrSet(result);
+                                       try {
+                                               procedure.execute(parentGraph, result);
+                                       } catch (Throwable t) {
+                                               t.printStackTrace();
+                                       }
+                               }
+
+                               @Override
+                               public void finished(AsyncReadGraph graph) {
+                                       ReadGraphImpl impl = (ReadGraphImpl)graph;
+                                       entry.finish(parentGraph);
+                                       try {
+                                               procedure.finished(parentGraph);
+                                       } catch (Throwable t) {
+                                               t.printStackTrace();
+                                       }
+                               }
+
+                               @Override
+                               public void exception(AsyncReadGraph graph, Throwable t) {
+                                       ReadGraphImpl impl = (ReadGraphImpl)graph;
+                                       entry.except(parentGraph, t);
+                                       try {
+                                               procedure.exception(parentGraph, t);
+                                       } catch (Throwable t2) {
+                                               t2.printStackTrace();
+                                       }
+                               }
+
+                       });
+
+                       return entry.getResult();
+
+               } catch (Throwable t) {
+
+                       entry.except(t);
+                       try {
+                               procedure.exception(parentGraph, t);
+                       } catch (Throwable t2) {
+                               t2.printStackTrace();
+                       }
+
+                       return entry.getResult();
+
+               }
+
+       }
+
+       public <T> Object performQuery(ReadGraphImpl parentGraph, final MultiRead<T> query, final CacheEntryBase entry_, Object procedure_) throws DatabaseException {
+
+               ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
+
+               MultiReadEntry entry = (MultiReadEntry)entry_;
+               SyncMultiProcedure<T> procedure = (SyncMultiProcedure<T>)procedure_;
+
+               try {
+
+                       query.perform(queryGraph, new SyncMultiProcedure<T>() {
+
+                               @Override
+                               public void execute(ReadGraph graph, T result) {
+                                       ReadGraphImpl impl = (ReadGraphImpl)graph;
+                                       entry.addOrSet(result);
+                                       try {
+                                               procedure.execute(parentGraph, result);
+                                       } catch (Throwable t) {
+                                               t.printStackTrace();
+                                       }
+                               }
+
+                               @Override
+                               public void finished(ReadGraph graph) {
+                                       ReadGraphImpl impl = (ReadGraphImpl)graph;
+                                       entry.finish(parentGraph);
+                                       try {
+                                               procedure.finished(parentGraph);
+                                       } catch (Throwable t) {
+                                               t.printStackTrace();
+                                       }
+                               }
+
+                               @Override
+                               public void exception(ReadGraph graph, Throwable t) {
+                                       ReadGraphImpl impl = (ReadGraphImpl)graph;
+                                       entry.except((DatabaseException)t);
+                                       try {
+                                               procedure.exception(parentGraph, t);
+                                       } catch (Throwable t2) {
+                                               t2.printStackTrace();
+                                       }
+                               }
+
+                       });
+
+                       return entry.getResult();
+
+               } catch (Throwable t) {
+
+                       entry.except(t);
+                       try {
+                               procedure.exception(parentGraph, t);
+                       } catch (Throwable t2) {
+                               t2.printStackTrace();
+                       }
+
+                       return entry.getResult();
+
+               }
+               
+       }
+       
+       public ListenerEntry registerDependencies(ReadGraphImpl graph, CacheEntry child, CacheEntry parent, ListenerBase listener, Object procedure, boolean inferred) {
+
+               if (parent != null && !inferred) {
+                       try {
+                               if(!child.isImmutable(graph)) {
+                                       synchronized(child) {
+                                               child.addParent(parent);
+                                       }
+                               }
+                       } catch (DatabaseException e) {
+                               Logger.defaultLogError(e);
+                       }
+                       if(DebugPolicy.DEPENDENCIES) System.out.println(child + " -> " + parent);
+               }
+
+               if (listener != null) {
+                       return registerListener(child, listener, procedure);
+               } else {
+                       return null;
+               }
+
+       }
+       
+       public synchronized ListenerEntry registerListener(final CacheEntry entry, final ListenerBase base, final Object procedure) {
+
+               assert (entry != null);
+
+               if (base.isDisposed())
+                       return null;
+
+               return addListener(entry, base, procedure);
+
+       }
+
+       protected void primeListenerEntry(final ListenerEntry entry, final Object result) {
+               entry.setLastKnown(result);
+       }
+
+       private ListenerEntry addListener(CacheEntry entry, ListenerBase base, Object procedure) {
+
+               assert (entry != null);
+               assert (procedure != null);
+
+               ArrayList<ListenerEntry> list = listeners.get(entry);
+               if (list == null) {
+                       list = new ArrayList<ListenerEntry>(1);
+                       listeners.put(entry, list);
+               }
+
+               ListenerEntry result = new ListenerEntry(entry, base, procedure);
+               int currentIndex = list.indexOf(result);
+               // There was already a listener
+               if(currentIndex > -1) {
+                       ListenerEntry current = list.get(currentIndex);
+                       if(!current.base.isDisposed()) return null;
+                       list.set(currentIndex, result);
+               } else {
+                       list.add(result);
+               }
+
+               if(DebugPolicy.LISTENER) {
+                       new Exception().printStackTrace();
+                       System.out.println("addListener -> " + list.size() + " " + entry + " " + base + " " + procedure);
+               }
+
+               return result;
+
+       }
+       
+       
+       public Collection<CacheEntry> getRootList() {
+
+               ArrayList<CacheEntry> result = new ArrayList<CacheEntry>();
+
+               for (Object e : valueQueryMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : directPredicatesMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : directSuperRelationsMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : objectsMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : directObjectsMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : principalTypesMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : superRelationsMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : superTypesMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : typesMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : objectsMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : assertedStatementsMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : readEntryMap.values()) {
+                       if(e instanceof CacheEntry) {
+                               result.add((CacheEntry) e);
+                       } else {
+                               System.err.println("e=" + e);
+                       }
+               }
+               for (Object e : asyncReadEntryMap.values()) {
+                       if(e instanceof CacheEntry) {
+                               result.add((CacheEntry) e);
+                       } else {
+                               System.err.println("e=" + e);
+                       }
+               }
+               for (Object e : externalReadEntryMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+               for (Object e : orderedSetMap.values()) {
+                       result.add((CacheEntry) e);
+               }
+
+               return result;
+
+       }
+
+       public int calculateCurrentSize() {
+
+               int realSize = 0;
+
+               realSize += directPredicatesMap.size();
+               realSize += directSuperRelationsMap.size();
+               realSize += principalTypesMap.size();
+               realSize += uRIToResourceMap.size();
+               //realSize += namespaceIndexMap.size();
+               realSize += childMapMap.size();
+
+               realSize += relationInfoQueryMap.size();
+               realSize += superTypesMap.size();
+               realSize += typeHierarchyMap.size();
+               realSize += superRelationsMap.size();
+               realSize += typesMap.size();
+
+               realSize += valueQueryMap.size();
+               realSize += directObjectsMap.size();
+               realSize += objectsMap.size();
+               realSize += orderedSetMap.size();
+               realSize += predicatesMap.size();
+
+               realSize += statementsMap.size();
+               realSize += assertedPredicatesMap.size();
+               realSize += assertedStatementsMap.size();
+               realSize += externalReadEntryMap.size();
+               realSize += asyncReadEntryMap.size();
+
+               realSize += readEntryMap.size();
+               realSize += asyncMultiReadEntryMap.size();
+               realSize += multiReadEntryMap.size();
+
+               return realSize;
+
+       }
+
+       CacheCollectionResult allCaches(CacheCollectionResult result) {
+
+               int level = Integer.MAX_VALUE;
+               directPredicatesMap.values(level, result);
+               directSuperRelationsMap.values(level, result);
+               principalTypesMap.values(level, result);
+               for(CacheEntryBase e : uRIToResourceMap.values())
+                       if(e.getLevel() <= level)
+                               result.add(e);
+//             for(CacheEntryBase e : namespaceIndexMap.values())
+//                     if(e.getLevel() <= level)
+//                             result.add(e);
+
+               childMapMap.values(level, result);
+
+               relationInfoQueryMap.values(level, result);
+               superTypesMap.values(level, result);
+               typeHierarchyMap.values(level, result);
+               superRelationsMap.values(level, result);
+               typesMap.values(level, result);
+
+               valueQueryMap.values(level, result);
+               directObjectsMap.values(level, result);
+               objectsMap.values(level, result);
+               orderedSetMap.values(level, result);
+               predicatesMap.values(level, result);
+
+               statementsMap.values(level, result);
+               assertedPredicatesMap.values(level, result);
+               assertedStatementsMap.values(level, result);
+               externalReadEntryMap.values(level, result);
+               asyncReadEntryMap.values(level, result);
+
+               readEntryMap.values(level, result);
+               asyncMultiReadEntryMap.values(level, result);
+               multiReadEntryMap.values(level, result);
+
+               return result;
+
+       }
+
+       public void scanPending() {
+
+               ArrayList<CacheEntry> entries = new ArrayList<CacheEntry>();
+
+               entries.addAll(directPredicatesMap.values());
+               entries.addAll(directSuperRelationsMap.values());
+               entries.addAll(principalTypesMap.values());
+               entries.addAll(uRIToResourceMap.values());
+               //entries.addAll(namespaceIndexMap.values());
+               entries.addAll(childMapMap.values());
+               entries.addAll(relationInfoQueryMap.values());
+               entries.addAll(superTypesMap.values());
+               entries.addAll(superRelationsMap.values());
+               entries.addAll(typesMap.values());
+               entries.addAll(valueQueryMap.values());
+               entries.addAll(directObjectsMap.values());
+               entries.addAll(objectsMap.values());
+               entries.addAll(orderedSetMap.values());
+               entries.addAll(predicatesMap.values());
+               entries.addAll(orderedSetMap.values());
+               entries.addAll(statementsMap.values());
+               //                      entries.addAll(assertedObjectsMap.values());
+               entries.addAll(assertedPredicatesMap.values());
+               entries.addAll(assertedStatementsMap.values());
+               entries.addAll(externalReadEntryMap.values());
+               entries.addAll(asyncReadEntryMap.values());
+               entries.addAll(externalReadEntryMap.values());
+               entries.addAll(readEntryMap.values());
+               entries.addAll(asyncMultiReadEntryMap.values());
+               entries.addAll(multiReadEntryMap.values());
+               entries.addAll(readEntryMap.values());
+               System.out.println(entries.size() + " entries.");
+               for(Object e : entries) {
+                       if(e instanceof CacheEntry) {
+                               CacheEntry en = (CacheEntry)e;
+                               if(en.isPending()) System.out.println("pending " + e);
+                               if(en.isExcepted()) System.out.println("excepted " + e);
+                               if(en.isDiscarded()) System.out.println("discarded " + e);
+                               if(en.isRefuted()) System.out.println("refuted " + e);
+                               if(en.isFresh()) System.out.println("fresh " + e);
+                       } else {
+                               //System.out.println("Unknown object " + e);
+                       }
+               }
+       }
+
+       public static void waitPending(QueryProcessor processor, CacheEntry entry) throws DatabaseException {
+
+               int counter = 0;
+               while(entry.isPending()) {
+                       try {
+                               SessionTask task = null;//processor.getOwnTask(processor.thread.get());
+                               if(task != null) {
+                                       task.run(processor.thread.get());
+                               } else {
+                                       Thread.sleep(1);
+                                       counter++;
+                                       if(counter > 5000) {
+                                               CacheEntryBase base = ((CacheEntryBase)entry);
+//                                             if(base.created != null) {
+//                                                     System.err.println("created:");
+//                                                     base.created.printStackTrace();
+//                                             }
+//                                             if(base.performed != null) {
+//                                                     System.err.println("performed:");
+//                                                     base.performed.printStackTrace();
+//                                             }
+//                                             if(base.ready != null) {
+//                                                     System.err.println("ready:");
+//                                                     base.ready.printStackTrace();
+//                                             }
+                                               new Exception("Timeout waiting for request to complete: " + entry.getOriginalRequest().toString()).printStackTrace();
+                                               throw new DatabaseException("Timeout waiting for request to complete.");
+                                               //System.err.println("asd");
+                                               //base.getQuery().recompute(null, null, entry);
+                                       }
+                               }
+                       } catch (InterruptedException e) {
+                       }
+               }
+
+       }
+
+       //////////////////////////////////////
+
+       public static Collection<Objects> entriesObjects(QueryProcessor processor, int r1) {
+               synchronized(processor.cache.objectsMap) {
+                       return processor.cache.objectsMap.values(r1);
+               }
+       }
+
+       public static Collection<Objects> entriesObjects(QueryProcessor processor) {
+               synchronized(processor.cache.objectsMap) {
+                       return processor.cache.objectsMap.values();
+               }
+       }
+
+       public static Collection<CacheEntry> entriesDirectPredicates(QueryProcessor processor) {
+               synchronized(processor.cache.directPredicatesMap) {
+                       return processor.cache.directPredicatesMap.values();
+               }
+       }
+
+       static final Collection<DirectObjects> entriesDirectObjects(final QueryProcessor processor, final int r1) {
+               DoubleKeyQueryHashMap<IntProcedure> hash = processor.cache.directObjectsMap;
+               return hash.values(r1);
+       }
+
+       static final Collection<Statements> entriesStatements(final QueryProcessor processor, final int r1) {
+               return processor.cache.statementsMap.values(r1);
+       }
+
+       static final Types entryTypes(final QueryProcessor processor, final int r) {
+               return (Types)processor.cache.typesMap.get(r);
+       }
+
+       static final PrincipalTypes entryPrincipalTypes(final QueryProcessor processor, final int r) {
+               return (PrincipalTypes)processor.cache.principalTypesMap.get(r);
+       }
+
+       static final OrderedSet entryOrderedSet(final QueryProcessor processor, final int r) {
+               return (OrderedSet)processor.cache.orderedSetMap.get(r);
+       }
+
+       static final ValueQuery entryValueQuery(final QueryProcessor processor, final int r) {
+               return (ValueQuery)processor.cache.valueQueryMap.get(r);
+       }
+
+       static final DirectPredicates entryDirectPredicates(final QueryProcessor processor, final int r) {
+               return (DirectPredicates)processor.cache.directPredicatesMap.get(r);
+       }
+
+       public static final ReadEntry entryRead(final QueryProcessor processor, final Read request) {
+               return (ReadEntry)processor.cache.readEntryMap.get(request);
+       }
+
+       public static final MultiReadEntry entryMultiRead(final QueryProcessor processor, final MultiRead request) {
+               return (MultiReadEntry)processor.cache.multiReadEntryMap.get(request);
+       }
+
+       public static final AsyncReadEntry entryAsyncRead(final QueryProcessor processor, final AsyncRead request) {
+               return (AsyncReadEntry)processor.cache.asyncReadEntryMap.get(request);
+       }
+
+       public static final AsyncMultiReadEntry entryAsyncMultiRead(final QueryProcessor processor, final AsyncMultiRead request) {
+               return (AsyncMultiReadEntry)processor.cache.asyncMultiReadEntryMap.get(request);
+       }
+
+       protected static final long keyR2(long r1, long r2) {
+               long result = (r1<<32) | (r2 & 0xffffffffL); 
+               return result;
+       }
+
+       protected static final <T> T id(T o) {
+               return o;
+       }
+
+       protected static final int keyR(int r) {
+               return r;
+       }
+
+       protected static final String keyID(String id) {
+               return id;
+       }
+
+       protected static InternalProcedure<IntSet> emptyIntSetProcedure = new InternalProcedure<IntSet>() {
+
+               @Override
+               public void execute(ReadGraphImpl graph, IntSet result) {
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) {
+               }
+
+       }; 
+
+       protected static InternalProcedure<byte[]> emptyBytesProcedure = new InternalProcedure<byte[]>() {
+
+               @Override
+               public void execute(ReadGraphImpl graph, byte[] bytes) {
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) {
+               }
+
+       }; 
+
+       protected static InternalProcedure<Integer> emptyIntegerProcedure = new InternalProcedure<Integer>() {
+
+               @Override
+               public void execute(ReadGraphImpl graph, Integer i) {
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) {
+               }
+
+       }; 
+
+
+       protected static InternalProcedure<TObjectIntHashMap<String>> emptyNamespaceProcedure = new InternalProcedure<TObjectIntHashMap<String>>() {
+
+               @Override
+               public void execute(ReadGraphImpl graph, TObjectIntHashMap<String> i) {
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) {
+               }
+
+       }; 
+
+
+       protected static InternalProcedure<RelationInfo> emptyRelationInfoProcedure = new InternalProcedure<RelationInfo>() {
+
+               @Override
+               public void execute(ReadGraphImpl graph, RelationInfo i) {
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) {
+               }
+
+       };
+
+       protected static InternalProcedure<ObjectResourceIdMap<String>> emptyChildMapProcedure = new InternalProcedure<ObjectResourceIdMap<String>>() {
+
+               @Override
+               public void execute(ReadGraphImpl graph, ObjectResourceIdMap<String> i) {
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) {
+               }
+
+       };
+
+       protected static IntProcedure emptyIntProcedure = new IntProcedure() {
+
+               @Override
+               public void finished(ReadGraphImpl graph) {
+               }
+
+               @Override
+               public void execute(ReadGraphImpl graph, int i) {
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) {
+               }
+       };
+
+       protected static TripleIntProcedure emptyTripleIntProcedure = new TripleIntProcedure() {
+
+               @Override
+               public void execute(ReadGraphImpl graph, int s, int p, int o) {
+               }
+
+               @Override
+               public void finished(ReadGraphImpl graph) {
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) {
+               }
+
+       }; 
+
+       protected static AsyncProcedure<Object> emptyAsyncProcedure = new AsyncProcedure<Object>() {
+
+               @Override
+               public void execute(AsyncReadGraph graph, Object result) {
+               }
+
+               @Override
+               public void exception(AsyncReadGraph graph, Throwable throwable) {
+               }
+
+       };
+
+       protected static AsyncMultiProcedure<Object> emptyAsyncMultiProcedure = new AsyncMultiProcedure<Object>() {
+
+               @Override
+               public void execute(AsyncReadGraph graph, Object result) {
+               }
+
+               @Override
+               public void finished(AsyncReadGraph graph) {
+               }
+
+               @Override
+               public void exception(AsyncReadGraph graph, Throwable throwable) {
+               }
+
+       }; 
+
+       protected static SyncMultiProcedure<Object> emptySyncMultiProcedure = new SyncMultiProcedure<Object>() {
+
+               @Override
+               public void execute(ReadGraph graph, Object result) {
+               }
+
+               @Override
+               public void finished(ReadGraph graph) {
+               }
+
+               @Override
+               public void exception(ReadGraph graph, Throwable throwable) {
+               }
+
+       };
+
+       protected static InternalProcedure<IntSet> emptyProcedureTypes = emptyIntSetProcedure;
+       protected static InternalProcedure<IntSet> emptyProcedureSuperTypes = emptyIntSetProcedure;
+       protected static InternalProcedure<IntSet> emptyProcedureTypeHierarchy = emptyIntSetProcedure;
+       protected static InternalProcedure<IntSet> emptyProcedureSuperRelations = emptyIntSetProcedure;
+       protected static InternalProcedure<IntSet> emptyProcedurePredicates = emptyIntSetProcedure;
+       protected static InternalProcedure<IntSet> emptyProcedureDirectPredicates = emptyIntSetProcedure;
+
+       protected static IntProcedure emptyProcedureObjects = emptyIntProcedure;
+       protected static IntProcedure emptyProcedureDirectObjects = emptyIntProcedure;
+       protected static IntProcedure emptyProcedurePrincipalTypes = emptyIntProcedure;
+       protected static IntProcedure emptyProcedureDirectSuperRelations = emptyIntProcedure;
+       protected static IntProcedure emptyProcedureAssertedPredicates = emptyIntProcedure;
+       protected static IntProcedure emptyProcedureOrderedSet = emptyIntProcedure;
+
+       protected static TripleIntProcedure emptyProcedureStatements = emptyTripleIntProcedure;
+       protected static TripleIntProcedure emptyProcedureAssertedStatements = emptyTripleIntProcedure;
+
+       protected static InternalProcedure<byte[]> emptyProcedureValueQuery = emptyBytesProcedure;
+
+       protected static InternalProcedure<Integer> emptyProcedureURIToResource = emptyIntegerProcedure;
+       protected static InternalProcedure<TObjectIntHashMap<String>> emptyProcedureNamespaceIndex = emptyNamespaceProcedure;
+       protected static InternalProcedure<ObjectResourceIdMap<String>> emptyProcedureChildMap = emptyChildMapProcedure;
+       protected static InternalProcedure<RelationInfo> emptyProcedureRelationInfoQuery = emptyRelationInfoProcedure;
+
+       protected static AsyncProcedure emptyProcedureReadEntry = emptyAsyncProcedure;
+       protected static AsyncProcedure emptyProcedureAsyncReadEntry = emptyAsyncProcedure;
+       protected static SyncMultiProcedure emptyProcedureMultiReadEntry = emptySyncMultiProcedure;
+       protected static AsyncMultiProcedure emptyProcedureAsyncMultiReadEntry = emptyAsyncMultiProcedure;
+       protected static AsyncProcedure emptyProcedureExternalReadEntry = emptyAsyncProcedure;
+
+       static class AsyncProcedureWrapper<T> implements AsyncProcedure<T> {
+
+               private AsyncProcedure<T> procedure;
+               private T result = null;
+               private Throwable throwable = null;
+               private Semaphore s = new Semaphore(0);
+
+               AsyncProcedureWrapper(AsyncProcedure<T> procedure) {
+                       this.procedure = procedure;
+               }
+
+               @Override
+               public void execute(AsyncReadGraph graph, T result) {
+                       if(procedure != null) procedure.execute(graph, result);
+                       this.result = result;
+                       s.release();
+               }
+
+               @Override
+               public void exception(AsyncReadGraph graph, Throwable throwable) {
+                       if(procedure != null) procedure.exception(graph, throwable);
+                       this.throwable = throwable;
+                       s.release();
+               }
+
+               public T get() throws DatabaseException {
+                       try {
+                               s.acquire();
+                       } catch (InterruptedException e) {
+                               e.printStackTrace();
+                       }
+                       if(throwable != null) {
+                               if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+                               else throw new DatabaseException(throwable);
+                       } else {
+                               return result;
+                       }
+               }
+               
+       }
+
+       static class ExternalProcedureWrapper<T> implements AsyncProcedure<T> {
+
+               private Procedure<T> procedure;
+               private T result = null;
+               private Throwable throwable = null;
+
+               ExternalProcedureWrapper(Procedure<T> procedure) {
+                       this.procedure = procedure;
+               }
+
+               @Override
+               public void execute(AsyncReadGraph graph, T result) {
+                       if(procedure != null) procedure.execute(result);
+                       this.result = result;
+               }
+
+               @Override
+               public void exception(AsyncReadGraph graph, Throwable throwable) {
+                       if(procedure != null) procedure.exception(throwable);
+                       this.throwable = throwable;
+               }
+
+               public T get() throws DatabaseException {
+                       if(throwable != null) {
+                               if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+                               else throw new DatabaseException(throwable);
+                       } else {
+                               return result;
+                       }
+               }
+
+       }
+
+
+       static class InternalProcedureWrapper<T> implements InternalProcedure<T> {
+
+               private InternalProcedure<T> procedure;
+               private T result = null;
+               private Throwable throwable = null;
+
+               InternalProcedureWrapper(InternalProcedure<T> procedure) {
+                       this.procedure = procedure;
+               }
+
+               @Override
+               public void execute(ReadGraphImpl graph, T result) throws DatabaseException {
+                       if(procedure != null) procedure.execute(graph, result);
+                       this.result = result;
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+                       if(procedure != null) procedure.exception(graph, throwable);
+                       this.throwable = throwable;
+               }
+
+               public T get() throws DatabaseException {
+                       if(throwable != null) {
+                               if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+                               else throw new DatabaseException(throwable);
+                       } else {
+                               return result;
+                       }
+               }
+
+       }
+
+       static class IntSetWrapper implements IntProcedure {
+
+               private IntProcedure procedure;
+               private final IntSet result;
+               private Throwable throwable = null;
+
+               IntSetWrapper(ReadGraphImpl graph, IntProcedure procedure) {
+                       this.procedure = procedure;
+                       result = new IntSet(graph.processor.querySupport);
+               }
+
+               @Override
+               public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                       if(procedure != null) procedure.execute(graph, i);
+                       result.add(i);
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+                       if(procedure != null) procedure.exception(graph, throwable);
+                       this.throwable = throwable;
+               }
+
+               @Override
+               public void finished(ReadGraphImpl graph) throws DatabaseException {
+                       if(procedure != null) procedure.finished(graph);
+               }
+
+               public IntSet get() throws DatabaseException {
+                       if(throwable != null) {
+                               if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+                               else throw new DatabaseException(throwable);
+                       } else {
+                               return result;
+                       }
+               }
+
+       }
+
+       static class TripleIntProcedureWrapper implements TripleIntProcedure {
+
+               private TripleIntProcedure procedure;
+               private IntArray result = new IntArray();
+               private Throwable throwable = null;
+
+               TripleIntProcedureWrapper(TripleIntProcedure procedure) {
+                       this.procedure = procedure;
+               }
+
+               @Override
+               public void execute(ReadGraphImpl graph, int i1, int i2, int i3) throws DatabaseException {
+                       if(procedure != null) procedure.execute(graph, i1, i2, i3);
+                       result.add(i1);
+                       result.add(i2);
+                       result.add(i3);
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+                       if(procedure != null) procedure.exception(graph, throwable);
+                       this.throwable = throwable;
+               }
+
+               @Override
+               public void finished(ReadGraphImpl graph) throws DatabaseException {
+                       if(procedure != null) procedure.finished(graph);
+               }
+
+               public IntArray get() throws DatabaseException {
+                       if(throwable != null) {
+                               if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+                               else throw new DatabaseException(throwable);
+                       } else {
+                               return result;
+                       }
+               }
+
+       }
+
+       public static <T> T resultExternalReadEntry(ReadGraphImpl graph, ExternalRead r, CacheEntry parent, ListenerBase listener, Procedure<T> procedure) throws DatabaseException {
+               ExternalProcedureWrapper<T> wrap = new ExternalProcedureWrapper<>(procedure);
+               QueryCache.runnerExternalReadEntry(graph, r, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       public static <T> T resultReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, AsyncProcedure<T> procedure) throws DatabaseException {
+               AsyncProcedureWrapper<T> wrap = new AsyncProcedureWrapper<>(procedure);
+               QueryCache.runnerReadEntry(graph, r, parent, listener, wrap, true);
+               return wrap.get();
+       }
+
+       public static <T> T resultAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, AsyncProcedure<T> procedure) throws DatabaseException {
+               AsyncProcedureWrapper<T> wrap = new AsyncProcedureWrapper<>(procedure);
+               QueryCache.runnerAsyncReadEntry(graph, r, parent, listener, wrap, true);
+               return wrap.get();
+       }
+
+       public static byte[] resultValueQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+               InternalProcedureWrapper<byte[]> wrap = new InternalProcedureWrapper<>(null);
+               QueryCache.runnerValueQuery(graph, r, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       public static RelationInfo resultRelationInfoQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+               InternalProcedureWrapper<RelationInfo> wrap = new InternalProcedureWrapper<>(null);
+               QueryCache.runnerRelationInfoQuery(graph, r, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       public static IntSet resultSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+               InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
+               QueryCache.runnerSuperRelations(graph, r, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       public static IntSet resultSuperTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+               InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
+               QueryCache.runnerSuperTypes(graph, r, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       public static IntSet resultTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+               InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
+               QueryCache.runnerTypes(graph, r, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       public static IntSet resultPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+               InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
+               QueryCache.runnerPredicates(graph, r, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       public static IntSet resultDirectPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+               InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
+               QueryCache.runnerDirectPredicates(graph, r, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       public static IntArray resultAssertedStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+               TripleIntProcedureWrapper wrap = new TripleIntProcedureWrapper(null);
+               QueryCache.runnerAssertedStatements(graph, r1, r2, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       public static Integer resultURIToResource(ReadGraphImpl graph, String id, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+               InternalProcedureWrapper<Integer> wrap = new InternalProcedureWrapper<Integer>(null);
+               QueryCache.runnerURIToResource(graph, id, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       public static ObjectResourceIdMap<String> resultChildMap(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+               InternalProcedureWrapper<ObjectResourceIdMap<String>> wrap = new InternalProcedureWrapper<ObjectResourceIdMap<String>>(null);
+               QueryCache.runnerChildMap(graph, r, parent, listener, wrap);
+               return wrap.get();
+       }
+
+       static boolean shouldCache(QueryProcessor processor, int r) {
+               return processor.isImmutable(r);
+       }
+
+       static boolean shouldCache(QueryProcessor processor, int r, int r2) {
+               return processor.isImmutable(r);
+       }
+
+       static boolean shouldCache(QueryProcessor processor, Object o) {
+               return false;
+       }
+
+}
\ No newline at end of file
index 0c33321731053d96c7f8c5bcf6c47deac66ba809..84273b81d63cf6921be763840b2c0cae172ba934 100644 (file)
@@ -25,7 +25,7 @@ class QueryCollectorImpl2 implements QueryProcessor.QueryCollector {
                this.support = support;
        }
 
-       private boolean findCollectables(CacheEntry entry, Map<CacheEntry, Boolean> collectables, ArrayList<CacheEntry> result) {
+       private boolean findCollectables(CacheEntry<?> entry, Map<CacheEntry, Boolean> collectables, ArrayList<CacheEntry> result) {
 
                if (entry.isDiscarded()) {
                        if(DebugPolicy.COLLECT && DebugPolicy.VERBOSE)
@@ -129,7 +129,7 @@ class QueryCollectorImpl2 implements QueryProcessor.QueryCollector {
 
                // Prune discarded parents
                ArrayList<CacheEntry> removals = new ArrayList<CacheEntry>();
-               for (CacheEntry entry : support.allCaches().toCollection()) {
+               for (CacheEntry<?> entry : support.allCaches().toCollection()) {
                        for(CacheEntry p : entry.getParents(queryProcessor)) {
                                if(p.isDiscarded()) removals.add(p);
                        }
@@ -157,7 +157,7 @@ class QueryCollectorImpl2 implements QueryProcessor.QueryCollector {
                        if(DebugPolicy.COLLECT)
                                new DebugException("checking the need for collecting queries (current=" + current + " , lastKnownFixedSize=" + lastKnownFixedSize + " max free=" + 0 + ")").printStackTrace();
 
-                       QueryProcessor.collecting = true;
+                       queryProcessor.cache.collecting = true;
 
                        long start = System.nanoTime();
 
@@ -175,8 +175,7 @@ class QueryCollectorImpl2 implements QueryProcessor.QueryCollector {
                        t.printStackTrace();
                }
 
-               QueryProcessor.collecting = false;
-
+               queryProcessor.cache.collecting = false;
 
        }
 
index 4842cf5a6ca44f6cbb543fad1cac8c4c5944e115..6db4726ac4de7eb859327b873f17dfdc6cddfaed 100644 (file)
@@ -13,6 +13,7 @@ package org.simantics.db.impl.query;
 
 import gnu.trove.impl.hash.THash;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 
 
@@ -69,12 +70,6 @@ abstract public class QueryIdentityHash extends THash {
             return null;
         }
 
-        @Override
-        public <T> T getResult() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
         @Override
         public boolean hasParents() {
             // TODO Auto-generated method stub
@@ -117,12 +112,6 @@ abstract public class QueryIdentityHash extends THash {
             return false;
         }
 
-        @Override
-        public void performFromCache(ReadGraphImpl graph, Object provider, Object procedure) {
-            // TODO Auto-generated method stub
-            
-        }
-
         @Override
         public void refute() {
             // TODO Auto-generated method stub
@@ -226,6 +215,18 @@ abstract public class QueryIdentityHash extends THash {
                public Object getOriginalRequest() {
                        throw new UnsupportedOperationException();
                }
+
+               @Override
+               Object performFromCache(ReadGraphImpl graph, Object procedure) throws DatabaseException {
+                       // TODO Auto-generated method stub
+                       return null;
+               }
+
+               @Override
+               public Object getResult() {
+                       // TODO Auto-generated method stub
+                       return null;
+               }
         
     };
 
index ff15d301b58214a25d20bb663889d11430008ae2..9c60691fad7a0a850228997e85ffb47168ca1aae 100644 (file)
@@ -31,8 +31,6 @@ import java.util.Set;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.ReentrantLock;
 
 import org.simantics.databoard.Bindings;
 import org.simantics.db.AsyncReadGraph;
@@ -53,7 +51,6 @@ import org.simantics.db.exception.NoInverseException;
 import org.simantics.db.exception.ResourceNotFoundException;
 import org.simantics.db.impl.DebugPolicy;
 import org.simantics.db.impl.ResourceImpl;
-import org.simantics.db.impl.graph.MultiIntProcedure;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.graph.ReadGraphSupport;
 import org.simantics.db.impl.graph.WriteGraphImpl;
@@ -65,18 +62,14 @@ import org.simantics.db.procedure.AsyncMultiListener;
 import org.simantics.db.procedure.AsyncMultiProcedure;
 import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.procedure.AsyncSetListener;
-import org.simantics.db.procedure.Listener;
 import org.simantics.db.procedure.ListenerBase;
 import org.simantics.db.procedure.MultiProcedure;
-import org.simantics.db.procedure.Procedure;
 import org.simantics.db.procedure.StatementProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.request.AsyncMultiRead;
-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.db.request.RequestFlags;
-import org.simantics.db.request.WriteTraits;
 import org.simantics.layer0.Layer0;
 import org.simantics.utils.DataContainer;
 import org.simantics.utils.Development;
@@ -84,7 +77,6 @@ import org.simantics.utils.datastructures.Pair;
 import org.simantics.utils.datastructures.collections.CollectionUtils;
 import org.simantics.utils.datastructures.disposable.AbstractDisposable;
 
-import gnu.trove.map.hash.THashMap;
 import gnu.trove.procedure.TIntProcedure;
 import gnu.trove.procedure.TLongProcedure;
 import gnu.trove.procedure.TObjectProcedure;
@@ -94,47 +86,13 @@ import gnu.trove.set.hash.TIntHashSet;
 @SuppressWarnings({"rawtypes", "unchecked"})
 final public class QueryProcessor extends AbstractDisposable implements ReadGraphSupport {
 
-       final public UnaryQueryHashMap<IntProcedure>                      directPredicatesMap;
-       final public UnaryQueryHashMap<IntProcedure>                      principalTypesMap;
-       final public THashMap<String, URIToResource>                      uriToResourceMap;
-       final public THashMap<String, NamespaceIndex>                     namespaceIndexMap22;
-       final public UnaryQueryHashMap<IntProcedure>                      projectsMap;
-       final public UnaryQueryHashMap<InternalProcedure<RelationInfo>>   relationInfoMap;
-       final public UnaryQueryHashMap<InternalProcedure<IntSet>>         superTypesMap;
-       final public UnaryQueryHashMap<InternalProcedure<IntSet>>         typeHierarchyMap;
-       final public UnaryQueryHashMap<InternalProcedure<IntSet>>         superRelationsMap;
-       final public UnaryQueryHashMap<InternalProcedure<IntSet>>         typesMap;
-       final public UnaryQueryHashMap<InternalProcedure<byte[]>>         valueMap;
-       final public DoubleKeyQueryHashMap<IntProcedure>                     directObjectsMap;
-       final public DoubleKeyQueryHashMap<IntProcedure>                     objectsMap;
-       final public UnaryQueryHashMap<IntProcedure>                      orderedSetMap;
-       final public UnaryQueryHashMap<IntProcedure>                      predicatesMap;
-       final public DoubleKeyQueryHashMap<TripleIntProcedure>               statementsMap;
-       final public UnaryQueryHashMap<IntProcedure>                      assertedPredicatesMap;
-       final public BinaryQueryHashMap<TripleIntProcedure>               assertedStatementsMap;
-       final public StableHashMap<ExternalRead, ExternalReadEntry>            externalReadMap; 
-       final public StableHashMap<AsyncRead, AsyncReadEntry>                  asyncReadMap; 
-       final public StableHashMap<Read, ReadEntry>                            readMap;
-       final public StableHashMap<AsyncMultiRead, AsyncMultiReadEntry>        asyncMultiReadMap; 
-       final public StableHashMap<MultiRead, MultiReadEntry>                  multiReadMap; 
-
-       final private THashMap<CacheEntry, ArrayList<ListenerEntry>>       listeners;
-
        public static int                                       indent                = 0;
 
-       public int                                              size                  = 0;
-       
        
        // Garbage collection
        
        public int                                              boundQueries          = 0;
 
-       // Statistics
-       private int                                             hits                  = 0;
-
-       private int                                             misses                = 0;
-
-       private int                                             updates               = 0;
 
        final private int                                       functionalRelation;
 
@@ -174,10 +132,10 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        private boolean                                         updating              = false;
 
-       static public boolean                                         collecting            = false;
 
        private boolean                                         firingListeners       = false;
 
+       final public QueryCache                                 cache;
        final public QuerySupport                               querySupport;
        final public Session                                    session;
        final public ResourceSupport                            resourceSupport;
@@ -186,7 +144,9 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        QueryThread[]                                   executors;
 
-       public ArrayList<SessionTask>[]                           queues;
+//     public ArrayList<SessionTask>[]                           queues;
+       
+       public LinkedList<SessionTask>                           freeScheduling = new LinkedList<SessionTask>();
 
        enum ThreadState {
 
@@ -195,17 +155,15 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        }
 
        public ThreadState[]                                                                    threadStates;
-       public ReentrantLock[]                                                                  threadLocks;
-       public Condition[]                                                                          threadConditions;
+//     public ReentrantLock[]                                                                  threadLocks;
+//     public Condition[]                                                                          threadConditions;
 
-       public ArrayList<SessionTask>[]                           ownTasks;
+       //public ArrayList<SessionTask>[]                           ownTasks;
 
-       public ArrayList<SessionTask>[]                           ownSyncTasks;
+       //public ArrayList<SessionTask>[]                           ownSyncTasks;
 
-       ArrayList<SessionTask>[]                           delayQueues;
+       //ArrayList<SessionTask>[]                           delayQueues;
        
-       public boolean synch = true;
-
        final Object querySupportLock;
        
        public Long modificationCounter = 0L;
@@ -213,77 +171,119 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        public void close() {
        }
 
-       final public void scheduleOwn(int caller, SessionTask request) {
-               ownTasks[caller].add(request);
+       SessionTask getOwnTask(int thread) {
+               synchronized(querySupportLock) {
+                       int index = 0;
+                       while(index < freeScheduling.size()) {
+                               SessionTask task = freeScheduling.get(index);
+                               if(task.thread == thread && !task.systemCall)
+                                       return freeScheduling.remove(index);
+                               index++;
+                       }
+               }
+               return null;
        }
-
-       final public void scheduleAlways(int caller, SessionTask request) {
-
-               int performer = request.thread;
-               if(caller == performer) {
-                       ownTasks[caller].add(request);
+       
+       public boolean performPending(int thread) {
+               SessionTask task = getOwnTask(thread);
+               if(task != null) {
+                       task.run(thread);
+                       return true;
                } else {
-                       schedule(caller, request);
+                       return false;
                }
-
        }
 
-       final public void schedule(int caller, SessionTask request) {
+//     final public void scheduleOwn(int caller, SessionTask request) {
+//             ownTasks[caller].add(request);
+//     }
+
+       final public void schedule(SessionTask request) {
 
                int performer = request.thread;
 
                if(DebugPolicy.SCHEDULE)
-                       System.out.println("schedule " + request + " " + caller + " -> " + performer);
+                       System.out.println("schedule " + request + " " + " -> " + performer);
 
-               assert(performer >= 0);
+               //assert(performer >= 0);
 
                assert(request != null);
 
-               if(caller == performer) {
-                       request.run(caller);
-               } else {
-                       ReentrantLock queueLock = threadLocks[performer];
-                       queueLock.lock();
-                       queues[performer].add(request);
-                       // This thread could have been sleeping
-                       if(queues[performer].size() == 1) {
-                               if(ThreadState.SLEEP == threadStates[performer]) sleepers.decrementAndGet();
-                               threadConditions[performer].signalAll();
-                       }
-                       queueLock.unlock();
-               }
+//             if(caller == performer) {
+//                     request.run(caller);
+//             } else {
+                       
+//                     if(performer == THREADS) {
+                               
+                               synchronized(querySupportLock) {
+                                       
+                                       //new Exception().printStackTrace();
+                                       
+                                       freeScheduling.add(request);
+                                       
+                                       querySupportLock.notifyAll();
+
+                                       //System.err.println("schedule free task " + request + " => " + freeScheduling.size());
+
+//                                     for(int i=0;i<THREADS;i++) {
+//                                             ReentrantLock queueLock = threadLocks[i];
+//                                             queueLock.lock();
+//                                             //queues[performer].add(request);
+//                                             //if(ThreadState.SLEEP == threadStates[i]) sleepers.decrementAndGet();
+//                                             threadConditions[i].signalAll();
+//                                             queueLock.unlock();
+//                                     }
+
+                               }
+
+                               return;
+                               
+//                     }
+//                     
+//                     ReentrantLock queueLock = threadLocks[performer];
+//                     queueLock.lock();
+//                     queues[performer].add(request);
+//                     // This thread could have been sleeping
+//                     if(queues[performer].size() == 1) {
+//                             //if(ThreadState.SLEEP == threadStates[performer]) sleepers.decrementAndGet();
+//                             threadConditions[performer].signalAll();
+//                     }
+//                     queueLock.unlock();
+//             }
 
        }
 
 
        final int THREADS;
-
        final public int  THREAD_MASK;
+       
        final public static ThreadGroup QueryThreadGroup = new ThreadGroup("Query Thread Group"); 
 
        public static abstract class SessionTask {
 
                final public int thread;
-               final public int syncCaller;
-               final public Object object;
-
-               public SessionTask(WriteTraits object, int thread) {
-                       this.thread = thread;
-                       this.syncCaller = -1;
-                       this.object = object;
+               final public boolean systemCall;
+//             final public int syncCaller;
+               //final public Object object;
+
+               public SessionTask(boolean systemCall) {
+                       this.thread = QueryProcessor.thread.get();
+                       this.systemCall = systemCall;
+//                     this.syncCaller = -1;
+                       //this.object = object;
                }
 
-               public SessionTask(Object object, int thread, int syncCaller) {
-                       this.thread = thread;
-                       this.syncCaller = syncCaller;
-                       this.object = object;
-               }
+//             public SessionTask(Object object, int syncCaller) {
+//                     this.thread = QueryProcessor.thread.get();
+//                     this.syncCaller = syncCaller;
+//                     this.object = object;
+//             }
 
                public abstract void run(int thread);
 
                @Override
                public String toString() {
-                       return "SessionTask[" + object + "]";
+                       return "SessionTask[" + super.toString() + "]";
                }
 
        }
@@ -293,14 +293,8 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                final public Semaphore notify;
                final public DataContainer<Throwable> throwable; 
 
-               public SessionRead(Object object, DataContainer<Throwable> throwable, Semaphore notify, int thread) {
-                       super(object, thread, thread);
-                       this.throwable = throwable;
-                       this.notify = notify;
-               }
-
-               public SessionRead(Object object, DataContainer<Throwable> throwable, Semaphore notify, int thread, int syncThread) {
-                       super(object, thread, syncThread);
+               public SessionRead(DataContainer<Throwable> throwable, Semaphore notify) {
+                       super(true);
                        this.throwable = throwable;
                        this.notify = notify;
                }
@@ -315,41 +309,61 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        public boolean resume(ReadGraphImpl graph) {
                return executors[0].runSynchronized();
        }
+       
+       //private WeakReference<GarbageTracker> garbageTracker;
+       
+       private class GarbageTracker    {
+               
+               @Override
+               protected void finalize() throws Throwable {
+                       
+//                     System.err.println("GarbageTracker");
+//                     
+//                     garbageTracker = new WeakReference<GarbageTracker>(new GarbageTracker());
+                       
+                       super.finalize();
+                       
+               }
+               
+       }
 
        public QueryProcessor(final int threads, QuerySupport core, Set<Thread> threadSet)
                        throws DatabaseException {
 
+               //garbageTracker = new WeakReference<GarbageTracker>(new GarbageTracker());
+               
                THREADS = threads;
                THREAD_MASK = threads - 1;
 
                querySupport = core;
+               cache = new QueryCache(core, threads);
                session = querySupport.getSession();
                resourceSupport = querySupport.getSupport();
                querySupportLock = core.getLock();
 
                executors = new QueryThread[THREADS];
-               queues = new ArrayList[THREADS];
-               threadLocks = new ReentrantLock[THREADS];
-               threadConditions = new Condition[THREADS];
+//             queues = new ArrayList[THREADS];
+//             threadLocks = new ReentrantLock[THREADS];
+//             threadConditions = new Condition[THREADS];
                threadStates = new ThreadState[THREADS];
-               ownTasks = new ArrayList[THREADS];
-               ownSyncTasks = new ArrayList[THREADS];
-               delayQueues = new ArrayList[THREADS * THREADS];
+//             ownTasks = new ArrayList[THREADS];
+//             ownSyncTasks = new ArrayList[THREADS];
+//             delayQueues = new ArrayList[THREADS * THREADS];
 
                //        freeSchedule = new AtomicInteger(0);
 
-               for (int i = 0; i < THREADS * THREADS; i++) {
-                       delayQueues[i] = new ArrayList<SessionTask>();
-               }
+//             for (int i = 0; i < THREADS * THREADS; i++) {
+//                     delayQueues[i] = new ArrayList<SessionTask>();
+//             }
 
                for (int i = 0; i < THREADS; i++) {
 
                        //            tasks[i] = new ArrayList<Runnable>();
-                       ownTasks[i] = new ArrayList<SessionTask>();
-                       ownSyncTasks[i] = new ArrayList<SessionTask>();
-                       queues[i] = new ArrayList<SessionTask>();
-                       threadLocks[i] = new ReentrantLock();
-                       threadConditions[i] = threadLocks[i].newCondition();
+//                     ownTasks[i] = new ArrayList<SessionTask>();
+//                     ownSyncTasks[i] = new ArrayList<SessionTask>();
+//                     queues[i] = new ArrayList<SessionTask>();
+//                     threadLocks[i] = new ReentrantLock();
+//                     threadConditions[i] = threadLocks[i].newCondition();
                        //            limits[i] = false;
                        threadStates[i] = ThreadState.INIT;
 
@@ -365,31 +379,6 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
                }
 
-               directPredicatesMap = new UnaryQueryHashMap();
-               valueMap = new UnaryQueryHashMap();
-               principalTypesMap = new UnaryQueryHashMap();
-               uriToResourceMap = new THashMap<String, URIToResource>();
-               namespaceIndexMap22 = new THashMap<String, NamespaceIndex>();
-               projectsMap = new UnaryQueryHashMap();
-               relationInfoMap = new UnaryQueryHashMap();
-               typeHierarchyMap = new UnaryQueryHashMap();
-               superTypesMap = new UnaryQueryHashMap();
-               superRelationsMap = new UnaryQueryHashMap();
-               typesMap = new UnaryQueryHashMap();
-               objectsMap = new DoubleKeyQueryHashMap();
-               orderedSetMap = new UnaryQueryHashMap();
-               predicatesMap = new UnaryQueryHashMap();
-               statementsMap = new DoubleKeyQueryHashMap();
-               directObjectsMap = new DoubleKeyQueryHashMap();
-               assertedPredicatesMap = new UnaryQueryHashMap();
-               assertedStatementsMap = new BinaryQueryHashMap();
-               asyncReadMap = new StableHashMap<AsyncRead, AsyncReadEntry>(); 
-               readMap = new StableHashMap<Read, ReadEntry>();
-               asyncMultiReadMap = new StableHashMap<AsyncMultiRead, AsyncMultiReadEntry>(); 
-               multiReadMap = new StableHashMap<MultiRead, MultiReadEntry>(); 
-               externalReadMap = new StableHashMap<ExternalRead, ExternalReadEntry>(); 
-               listeners = new THashMap<CacheEntry, ArrayList<ListenerEntry>>(10, 0.75f);
-
                // Now start threads
                for (int i = 0; i < THREADS; i++) {
                        executors[i].start();
@@ -571,48 +560,63 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        public void forResource(ReadGraphImpl graph, final String id, CacheEntry parent, final InternalProcedure<Integer> procedure) {
 
-               URIToResource.queryEach(graph, id, parent, null, new InternalProcedure<Integer>() {
+               try {
+                       
+                       QueryCache.runnerURIToResource(graph, id, parent, null, new InternalProcedure<Integer>() {
 
-                       @Override
-                       public void execute(ReadGraphImpl graph, Integer result) {
+                               @Override
+                               public void execute(ReadGraphImpl graph, Integer result) throws DatabaseException {
 
-                               if (result != null && result != 0) {
-                                       procedure.execute(graph, result);
-                                       return;
-                               }
+                                       if (result != null && result != 0) {
+                                               procedure.execute(graph, result);
+                                               return;
+                                       }
 
-                               // Fall back to using the fixed builtins.
-                               result = querySupport.getBuiltin(id);
-                               if (result != 0) {
-                                       procedure.execute(graph, result);
-                                       return;
-                               } 
+                                       // Fall back to using the fixed builtins.
+//                                     result = querySupport.getBuiltin(id);
+//                                     if (result != 0) {
+//                                             procedure.execute(graph, result);
+//                                             return;
+//                                     } 
 
-                               try {
-                                       result = querySupport.getRandomAccessReference(id);
-                               } catch (ResourceNotFoundException e) {
-                                       procedure.exception(graph, e);
-                                       return;
-                               }
+//                                     try {
+//                                             result = querySupport.getRandomAccessReference(id);
+//                                     } catch (ResourceNotFoundException e) {
+//                                             procedure.exception(graph, e);
+//                                             return;
+//                                     }
 
-                               if (result != 0) {
-                                       procedure.execute(graph, result);
-                               } else {
-                                       procedure.exception(graph, new ResourceNotFoundException(id));
-                               }
+                                       if (result != 0) {
+                                               procedure.execute(graph, result);
+                                       } else {
+                                               procedure.exception(graph, new ResourceNotFoundException(id));
+                                       }
 
-                       }
+                               }
 
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               procedure.exception(graph, t);
-                       }
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                                       procedure.exception(graph, t);
+                               }
 
-               });
+                       });
+               } catch (DatabaseException e) {
+                   
+                   try {
+                       
+                procedure.exception(graph, e);
+                
+            } catch (DatabaseException e1) {
+                
+                Logger.defaultLogError(e1);
+                
+            }
+                   
+               }
 
        }
 
-       public void forBuiltin(ReadGraphImpl graph, final String id, CacheEntry parent, final InternalProcedure<Integer> procedure) {
+       public void forBuiltin(ReadGraphImpl graph, final String id, CacheEntry parent, final InternalProcedure<Integer> procedure) throws DatabaseException {
 
                Integer result = querySupport.getBuiltin(id);
                if (result != 0) {
@@ -623,986 +627,162 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        }
 
-       public final <T> void runAsyncRead(final ReadGraphImpl graph, final AsyncRead<T> query, final CacheEntry parent, final ListenerBase listener, final AsyncProcedure<T> procedure) {
-
-               int hash = requestHash(query);
+       final <T> void runMultiRead(final ReadGraphImpl graph, MultiReadEntry cached, final MultiRead<T> query, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final SyncMultiProcedure<T> procedure) {
 
-               AsyncReadEntry<T> entry = asyncReadMap.get(query, hash); 
-
-               if(parent == null && listener == null) {
-                       if(entry != null && (entry.isReady() || entry.isExcepted())) {
-                               System.out.println("ready " + query);
-                               entry.performFromCache(graph, this, procedure);
-//                             graph.state.barrier.dec(query);
-                               return;
-                       } else {
-                               query.perform(graph, procedure);
-//                             graph.state.barrier.dec(query);
-                               return;
-                       }
+               try {
+                       QueryCache.runnerMultiReadEntry(graph, query, parent, listener, procedure);
+               } catch (DatabaseException e) {
+                       throw new IllegalStateException(e);
                }
 
-               if(entry == null) {
-
-                       entry = new AsyncReadEntry<T>(query);
-                       entry.setPending();
-                       entry.clearResult(querySupport);
-                       asyncReadMap.put(query, entry, hash);
-
-                       performForEach(graph, query, entry, parent, listener, procedure, false);
-
-               } else {
-
-                       if(entry.isPending()) {
-                               synchronized(entry) {
-                                       if(entry.isPending()) {
-                                           throw new IllegalStateException();
-                                               //                      final AsyncBarrierImpl parentBarrier = graph.state.barrier;
-                                               //                      if(entry.procs == null) entry.procs = new ArrayList<AsyncProcedure<T>>();
-                                               //                        entry.procs.add(new AsyncProcedure<T>() {
-                                               //
-                                               //                                                      @Override
-                                               //                                                      public void execute(AsyncReadGraph graph, T result) {
-                                               //                                                              procedure.execute(graph, result);
-                                               //                                                              parentBarrier.dec(query);
-                                               //                                                      }
-                                               //
-                                               //                                                      @Override
-                                               //                                                      public void exception(AsyncReadGraph graph, Throwable throwable) {
-                                               //                                                              procedure.exception(graph, throwable);
-                                               //                                                              parentBarrier.dec(query);
-                                               //                                                      }
-                                               //                              
-                                               //                        });
-//                                             if(graph.parent != null || listener != null) {
-//                                                     registerDependencies(graph, entry, parent, listener, procedure, false);
-//                                             }
-//
-//                                             query.perform(graph, procedure);
-//
-//                                             return;
-
-                                       }
-                               }
-                       }
+       }
 
-                       if(entry.isReady()) { 
-                               entry.performFromCache(graph, this, procedure);
-                               registerDependencies(graph, entry, parent, listener, procedure, false);
-                       } else {
-                               performForEach(graph, query, entry, parent, listener, procedure, false);
-                       }
+       public final <T> void runAsyncMultiRead(final ReadGraphImpl graph, final AsyncMultiRead<T> query, final CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure<T> procedure) {
 
+               
+               try {
+                       QueryCache.runnerAsyncMultiReadEntry(graph, query, parent, listener, procedure);
+               } catch (DatabaseException e) {
+                       throw new IllegalStateException(e);
                }
 
        }
 
+       final <T> void runPrimitiveRead(ReadGraphImpl graph, ExternalReadEntry cached, final ExternalRead<T> query, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final AsyncProcedure<T> procedure) throws DatabaseException {
+               QueryCache.runnerExternalReadEntry(graph, query, parent, listener, procedure);
+       }
 
-       final static <T> void runMultiRead(final ReadGraphImpl graph, MultiReadEntry cached, final MultiRead<T> query, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final AsyncMultiProcedure<T> procedure) {
-
-               MultiReadEntry entry = cached != null ? cached : provider.multiReadMap.get(query); 
-               if(entry == null) {
-
-                       entry = new MultiReadEntry(query);
-                       entry.setPending();
-                       entry.clearResult(provider.querySupport);
-
-                       provider.multiReadMap.put(query, entry);
-
-                       provider.performForEach(graph, query, entry, parent, listener, procedure, false);
-
-               } else {
-
-                       if(entry.isPending()) {
-
-                               synchronized(entry) {
-
-                                       if(entry.isPending()) {
-                                           throw new IllegalStateException();
-
-//                                             if(entry.procs == null) entry.procs = new ArrayList<Pair<AsyncMultiProcedure<T>, AsyncBarrier>>();
-//                                             entry.procs.add(new Pair(procedure, parentBarrier));
-//                                             if(graph.parent != null || listener != null) {
-//                                                     provider.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                                             }
-
-                                               // If this was synchronized we must wait here until completion
-                                               //                        if(graph.state.synchronizedExecution) {
-                                               //                            while(entry.isPending()) {
-                                               //                              graph.resumeTasks(graph.callerThread, null, null);
-                                               //                            }
-                                               //                        }
+//    @Override
+//     public <T> T query(final ReadGraphImpl graph, final Read<T> query, final CacheEntry parent, final AsyncProcedure<T> procedure, final ListenerBase listener) throws DatabaseException {
+//     
+//     return QueryCache.resultReadEntry(graph, query, parent, listener, procedure);
 //
-//                                             return;
-
-                                       }
-                               }
+//     }
 
-                               entry.performFromCache(graph, provider, procedure);
-//                             graph.state.barrier.dec(query);
-                               return;
+       public <T> void queryMultiRead(final ReadGraphImpl graph, final MultiRead<T> query, final CacheEntry parent, final ListenerBase listener, final SyncMultiProcedure<T> procedure) throws DatabaseException {
 
-                       } else {
+               QueryCache.runnerMultiReadEntry(graph, query, parent, listener, procedure);
 
-                               provider.performForEach(graph, query, entry, parent, listener, procedure, false);
+       }
 
-                       }
+       public <T> void queryPrimitiveRead(final ReadGraphImpl graph, final ExternalRead<T> query, final CacheEntry parent, final ListenerBase listener, final AsyncProcedure<T> procedure) throws DatabaseException {
 
-               }
+               QueryCache.runnerExternalReadEntry(graph, query, parent, listener, procedure);
 
        }
 
-       public final <T> void runAsyncMultiRead(final ReadGraphImpl graph, final AsyncMultiRead<T> query, final CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure<T> procedure) {
-
-               int hash = requestHash(query);
+       boolean isBound(ExternalReadEntry<?> entry) {
+               if(entry.hasParents()) return true;
+               else if(hasListener(entry)) return true;
+               else return false;
+       }
 
-               AsyncMultiReadEntry entry = asyncMultiReadMap.get(query, hash);
+       synchronized public ListenerEntry registerDependencies(ReadGraphImpl graph, CacheEntry child, CacheEntry parent, ListenerBase listener, Object procedure, boolean inferred) {
 
-               if(parent == null && listener == null) {
-                       if(entry != null && (entry.isReady() || entry.isExcepted())) {
-                               System.out.println("ready " + query);
-                               entry.performFromCache(graph, this, procedure);
-                               return;
-                       } else {
-                               query.perform(graph, procedure);
-                               return;
+               if (parent != null && !inferred) {
+                       try {
+                               if(!child.isImmutable(graph))
+                                       child.addParent(parent);
+                       } catch (DatabaseException e) {
+                               Logger.defaultLogError(e);
                        }
+                       if(DebugPolicy.DEPENDENCIES) System.out.println(child + " -> " + parent);
                }
 
-               if(entry == null) {
-
-                       entry = new AsyncMultiReadEntry<T>(query); 
-                       entry.setPending();
-                       entry.clearResult(querySupport);
-
-                       asyncMultiReadMap.put(query, entry, hash);
-
-                       performForEach(graph, query, entry, parent, listener, procedure, false);
-
+               if (listener != null) {
+                       return registerListener(child, listener, procedure);
                } else {
-
-                       if(entry.isPending()) {
-                           
-                               synchronized(entry) {
-                                       if(entry.isPending()) {
-                                           throw new IllegalStateException();
-//                                             if(entry.procs == null) entry.procs = new ArrayList<AsyncMultiProcedure<T>>();
-//                                             entry.procs.add(procedure);
-//                                             if(graph.parent != null || listener != null) {
-//                                                     registerDependencies(graph, entry, parent, listener, procedure, false);
-//                                             }
-//                                             return;
-                                       }
-                               }
-                       }
-
-                       performForEach(graph, query, entry, parent, listener, procedure, false);
-
+                       return null;
                }
 
        }
 
-       final static <T> void runPrimitiveRead(ReadGraphImpl graph, ExternalReadEntry cached, final ExternalRead<T> query, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final Procedure<T> procedure) {
+       
+       static class Dummy implements InternalProcedure<Object>, IntProcedure {
 
-               final ExternalReadEntry<T> entry = cached != null ? cached : provider.externalReadMap.get(query); 
-               if(entry == null) {
-                       provider.performForEach(graph, query, new ExternalReadEntry<T>(query), parent, listener, procedure, false);
-               } else {
-                       if(entry.isPending()) {
-                               synchronized(entry) {
-                                       if(entry.isPending()) {
-                                           throw new IllegalStateException();
-//                                             if(entry.procs == null) entry.procs = new ArrayList<Procedure<T>>();
-//                                             entry.procs.add(procedure);
-//                                             return;
-                                       }
-                               }
-                       }
-                       provider.performForEach(graph, query, entry, parent, listener, procedure, false);
+               @Override
+               public void execute(ReadGraphImpl graph, int i) {
                }
 
-       }
-
-       public int requestHash(Object object) {
-               try {
-                       return object.hashCode();
-               } catch (Throwable t) {
-                       Logger.defaultLogError(t);
-                       return 0;
+               @Override
+               public void finished(ReadGraphImpl graph) {
                }
-       }
-       
-    @Override
-       public <T> T queryRead(final ReadGraphImpl graph, final Read<T> query, final CacheEntry parent, final AsyncProcedure<T> procedure, final ListenerBase listener) throws Throwable {
-
-               assert(query != null);
 
-               ReadEntry entry = readMap.get(query);
-
-               if(entry != null) {
-                       if(parent == null && (listener == null || listener.isDisposed()) && entry.isReady()) {
-                               return (T)entry.get(graph, this, procedure);
-                       } else if (entry.isPending()) {
-                           throw new IllegalStateException();
-                       }
+               @Override
+               public void execute(ReadGraphImpl graph, Object result) {
                }
 
-               if(entry == null) {
-
-                       entry = new ReadEntry(query);
-                       entry.setPending();
-                       entry.clearResult(querySupport);
-
-                       readMap.put(query, entry);
-
-                       return (T)performForEach(graph, query, entry, parent, listener, procedure, false);
-
-               } else {
-
-                       if(entry.isPending()) {
-                throw new IllegalStateException();
-                       } else {
-                               return (T)performForEach(graph, query, entry, parent, listener, procedure, false);
-                       }
-
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) {
                }
-
+               
        }
+       
+       private static final Dummy dummy = new Dummy();
 
-       public <T> void queryMultiRead(final ReadGraphImpl graph, final MultiRead<T> query, final CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure<T> procedure) {
+       /*
+    public <Procedure> Object performForEach2(ReadGraphImpl graph, UnaryQuery<Procedure> query, CacheEntry parent, ListenerBase listener, Procedure procedure) throws Throwable {
 
-               assert(query != null);
-               assert(procedure != null);
+        if (DebugPolicy.PERFORM)
+            System.out.println("PE[ " + (query.hashCode() &  THREAD_MASK) + "] " + query);
 
-               final MultiReadEntry entry = multiReadMap.get(query);
+        assert (!dirty);
+        assert (!collecting);
 
-               if(parent == null && !(listener != null)) {
-                       if(entry != null && entry.isReady()) { 
-                               entry.performFromCache(graph, this, procedure);
-                               return;
-                       }
-               }
+        assert(query.assertNotDiscarded());
 
-               runMultiRead(graph, entry, query, parent, this, listener, procedure);
+        registerDependencies(graph, query, parent, listener, procedure, false);
 
-       }
+        // FRESH, REFUTED, EXCEPTED go here 
+        if (!query.isReady()) {
 
-       public <T> void queryPrimitiveRead(final ReadGraphImpl graph, final ExternalRead<T> query, final CacheEntry parent, final ListenerBase listener, final Procedure<T> procedure) {
+            size++;
+            misses++;
 
-               assert(query != null);
-               assert(procedure != null);
+            query.computeForEach(graph, this, (Procedure)dummy, true);
+            return query.get(graph, this, null);
 
-               final ExternalReadEntry entry = externalReadMap.get(query);
+        } else {
 
-               if(parent == null && !(listener != null)) {
-                       if(entry != null && entry.isReady()) { 
-                               entry.performFromCache(procedure);
-                               return;
-                       }
-               }
+            hits++;
 
-               runPrimitiveRead(graph, entry, query, parent, this, listener, procedure);
+            return query.get(graph, this, procedure);
 
-       }
+        }
 
-       public <T> void performForEach(ReadGraphImpl parentGraph, final AsyncRead<T> query, final AsyncReadEntry<T> entry, final CacheEntry parent, final ListenerBase base, final AsyncProcedure<T> procedure,
-                       boolean inferredDependency) {
+    }
+       */
+       
 
-               if (DebugPolicy.PERFORM)
-                       System.out.println("PE[ " + (query.hashCode() & THREAD_MASK) + "] " + query);
+       interface QueryCollectorSupport {
+               public CacheCollectionResult allCaches();
+               public Collection<CacheEntry> getRootList();
+               public int getCurrentSize();
+               public int calculateCurrentSize();
+               public CacheEntryBase iterate(int level);
+               public void remove();
+               public void setLevel(CacheEntryBase entry, int level);
+               public boolean start(boolean flush);
+       }
 
-               assert (!dirty);
-               assert (!collecting);
+       interface QueryCollector {
 
-               assert(!entry.isDiscarded());
+               public void collect(int youngTarget, int allowedTimeInMs);
 
-               final ListenerEntry listenerEntry = registerDependencies(parentGraph, entry, parent, base, procedure, inferredDependency);
+       }
 
-               // FRESH, REFUTED, EXCEPTED go here 
-               if (!entry.isReady()) {
+       class QueryCollectorSupportImpl implements QueryCollectorSupport {
 
-                       entry.setPending();
-
-                       size++;
-
-                       try {
-
-                               final ReadGraphImpl finalParentGraph = parentGraph;
-
-                               query.perform(parentGraph.withParent(entry), new AsyncProcedure<T>() {
-
-                                       @Override
-                                       public void execute(AsyncReadGraph returnGraph, T result) {
-                                               ReadGraphImpl impl = (ReadGraphImpl)returnGraph;
-                                               //AsyncReadGraph resumeGraph = finalParentGraph.newAsync();
-                                               entry.addOrSet(finalParentGraph, result);
-                                               if(listenerEntry != null) {
-                                                       primeListenerEntry(listenerEntry, result);
-                                               }
-                                               try {
-                                                       procedure.execute(finalParentGraph, result);
-                                               } catch (Throwable t) {
-                                                       t.printStackTrace();
-                                               }
-//                                             parentBarrier.dec(query);
-                                       }
-
-                                       @Override
-                                       public void exception(AsyncReadGraph returnGraph, Throwable t) {
-                                               ReadGraphImpl impl = (ReadGraphImpl)returnGraph;
-//                                             AsyncReadGraph resumeGraph = finalParentGraph.newAsync();
-                                               entry.except(finalParentGraph, t);
-                                               try {
-                                                       procedure.exception(finalParentGraph, t);
-                                               } catch (Throwable t2) {
-                                                       t2.printStackTrace();
-                                               }
-//                                             parentBarrier.dec(query);
-                                       }
-
-                                       @Override
-                                       public String toString() {
-                                               return procedure.toString();
-                                       }
-
-                               });
-
-                       } catch (Throwable t) {
-
-                               entry.except(t);
-                               try {
-                                       procedure.exception(parentGraph, t);
-                               } catch (Throwable t2) {
-                                       t2.printStackTrace();
-                               }
-//                             parentBarrier.dec(query);
-
-                       }
-
-                       misses++;
-
-               } else {
-
-                       entry.performFromCache(parentGraph, this, new AsyncProcedure<T>() {
-
-                               @Override
-                               public void exception(AsyncReadGraph graph, Throwable throwable) {
-                                       procedure.exception(graph, throwable);
-                               }
-
-                               @Override
-                               public void execute(AsyncReadGraph graph, T result) {
-                                       procedure.execute(graph, result);
-                                       if(listenerEntry != null) {
-                                               primeListenerEntry(listenerEntry, result);
-                                       }
-                               }
-
-                       });
-
-//                     parentBarrier.dec(query);
-
-                       hits++;
-
-               }
-
-               assert (!entry.isDiscarded());
-
-       }
-
-       public <T> T performForEach(final ReadGraphImpl graph, final Read<T> query, final ReadEntry<T> entry, final CacheEntry parent, final ListenerBase listener, final AsyncProcedure<T> procedure,
-                       boolean inferredDependency) throws Throwable {
-
-               if (DebugPolicy.PERFORM)
-                       System.out.println("PE[ " + (query.hashCode() & THREAD_MASK) + "] " + query);
-
-               assert (!dirty);
-               assert (!collecting);
-
-               entry.assertNotDiscarded();
-
-               if(entry.isReady()) {
-
-                       // EXCEPTED goes here
-
-//                     if(procedure != null) entry.performFromCache(graph, this, procedure);
-//                     parentBarrier.dec(query);
-                       hits++;
-
-                       ListenerEntry listenerEntry = registerDependencies(graph, entry, parent, listener, procedure, inferredDependency);
-                       
-                       T result = (T)entry.get(graph, this, procedure); 
-
-                       if(listenerEntry != null) primeListenerEntry(listenerEntry, result);
-
-                       return result;
-
-               } else {
-
-                       // FRESH, REFUTED, PENDING go here
-
-                       entry.setPending();
-
-                       size++;
-                       misses++;
-
-               ListenerEntry listenerEntry = registerDependencies(graph, entry, parent, listener, procedure, inferredDependency);
-
-                       final ReadGraphImpl performGraph = graph.newSync(entry);
-
-                       try {
-
-                               if(Development.DEVELOPMENT)
-                                       Development.recordHistogram("run " + query);
-
-                               T result = query.perform(performGraph);
-                               entry.addOrSet(performGraph, result);
-                               
-                               if(listenerEntry != null) primeListenerEntry(listenerEntry, result);
-
-                               return (T)entry.get(graph, this, procedure);
-
-                       }  catch (Throwable t) {
-
-                               entry.except(t);
-                               return (T)entry.get(graph, this, procedure);
-
-                       }
-
-               } 
-
-       }
-
-       public <T> void performForEach(final ReadGraphImpl graph, final MultiRead<T> query, final MultiReadEntry<T> entry, CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure<T> procedure,
-                       boolean inferredDependency) {
-
-               if (DebugPolicy.PERFORM)
-                       System.out.println("PE[ " + (query.hashCode() & THREAD_MASK) + "] " + query);
-
-               assert (!dirty);
-               assert (!collecting);
-
-               assert(!entry.isPending());
-               assert(!entry.isDiscarded());
-
-               // FRESH, REFUTED, EXCEPTED go here 
-               if (!entry.isReady()) {
-
-                       entry.setPending();
-                       entry.clearResult(querySupport);
-
-                       multiReadMap.put(query, entry);
-                       size++;
-
-                       final ReadGraphImpl newGraph = graph.newSync(entry);
-//                     newGraph.state.barrier.inc();
-
-                       try {
-
-                               query.perform(newGraph, new AsyncMultiProcedure<T>() {
-
-                                       @Override
-                                       public void execute(AsyncReadGraph graph, T result) {
-                                               entry.addOrSet(result);
-                                               try {
-                                                       procedure.execute(graph, result);
-                                               } catch (Throwable t) {
-                                                       t.printStackTrace();
-                                               }
-                                       }
-
-                                       @Override
-                                       public void finished(AsyncReadGraph graph) {
-                                               entry.finish(graph);
-                                               try {
-                                                       procedure.finished(graph);
-                                               } catch (Throwable t) {
-                                                       t.printStackTrace();
-                                               }
-//                                             newGraph.state.barrier.dec();
-//                                             parentBarrier.dec();
-                                       }
-
-                                       @Override
-                                       public void exception(AsyncReadGraph graph, Throwable t) {
-                                               entry.except(t);
-                                               try {
-                                                       procedure.exception(graph, t);
-                                               } catch (Throwable t2) {
-                                                       t2.printStackTrace();
-                                               }
-//                                             newGraph.state.barrier.dec();
-//                                             parentBarrier.dec();
-                                       }
-
-                               });
-
-                       } catch (DatabaseException e) {
-
-                               entry.except(e);
-                               try {
-                                       procedure.exception(graph, e);
-                               } catch (Throwable t2) {
-                                       t2.printStackTrace();
-                               }
-//                             newGraph.state.barrier.dec();
-//                             parentBarrier.dec();
-
-                       } catch (Throwable t) {
-
-                               DatabaseException e = new DatabaseException(t);
-
-                               entry.except(e);
-                               try {
-                                       procedure.exception(graph, e);
-                               } catch (Throwable t2) {
-                                       t2.printStackTrace();
-                               }
-//                             newGraph.state.barrier.dec();
-//                             parentBarrier.dec();
-
-                       }
-
-                       misses++;
-
-               } else {
-
-                       entry.performFromCache(graph, this, procedure);
-                       hits++;
-
-
-               }
-
-               assert (!entry.isDiscarded());
-
-               registerDependencies(graph, entry, parent, listener, procedure, inferredDependency);
-
-       }
-
-
-       public <T> void performForEach(final ReadGraphImpl callerGraph, AsyncMultiRead<T> query, final AsyncMultiReadEntry<T> entry, final CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure<T> procedure,
-                       boolean inferredDependency) {
-
-               if (DebugPolicy.PERFORM)
-                       System.out.println("PE[ " + (query.hashCode() & THREAD_MASK) + "] " + query);
-
-               assert (!dirty);
-               assert (!collecting);
-
-               try {
-
-                       assert(!entry.isDiscarded());
-
-                       // FRESH, REFUTED, EXCEPTED go here 
-                       if (!entry.isReady()) {
-
-                               size++;
-
-                               try {
-
-                                       ReadGraphImpl performGraph = callerGraph.withAsyncParent(entry);
-
-                                       query.perform(performGraph, new AsyncMultiProcedure<T>() {
-
-                                               @Override
-                                               public void execute(AsyncReadGraph graph, T result) {
-                                                       ReadGraphImpl impl = (ReadGraphImpl)graph;
-//                                                     ReadGraphImpl executeGraph = callerGraph.newAsync();
-                                                       entry.addOrSet(result);
-                                                       try {
-                                                               procedure.execute(callerGraph, result);
-                                                       } catch (Throwable t) {
-                                                               t.printStackTrace();
-                                                       }
-                                               }
-
-                                               @Override
-                                               public void finished(AsyncReadGraph graph) {
-                                                       ReadGraphImpl impl = (ReadGraphImpl)graph;
-//                                                     ReadGraphImpl executeGraph = callerGraph.newAsync();
-                                                       entry.finish(callerGraph);
-                                                       try {
-                                                               procedure.finished(callerGraph);
-                                                       } catch (Throwable t) {
-                                                               t.printStackTrace();
-                                                       }
-                                               }
-
-                                               @Override
-                                               public void exception(AsyncReadGraph graph, Throwable t) {
-                                                       ReadGraphImpl impl = (ReadGraphImpl)graph;
-//                                                     ReadGraphImpl executeGraph = callerGraph.newAsync();
-                                                       entry.except(callerGraph, t);
-                                                       try {
-                                                               procedure.exception(callerGraph, t);
-                                                       } catch (Throwable t2) {
-                                                               t2.printStackTrace();
-                                                       }
-                                               }
-
-                                       });
-
-                               } catch (Throwable t) {
-
-                                       entry.except(t);
-                                       try {
-                                               procedure.exception(callerGraph, t);
-                                       } catch (Throwable t2) {
-                                               t2.printStackTrace();
-                                       }
-
-                               }
-
-
-                               misses++;
-
-                       } else {
-
-                               entry.performFromCache(callerGraph, this, procedure);
-
-                               hits++;
-
-                       }
-
-                       assert (!entry.isDiscarded());
-
-                       registerDependencies(callerGraph, entry, parent, listener, procedure, inferredDependency);
-
-               } catch (Throwable t) {
-
-                       Logger.defaultLogError(t);
-
-               } finally {
-
-               }
-
-       }
-
-       public <T> void performForEach(ReadGraphImpl graph, final ExternalRead<T> query, final ExternalReadEntry<T> entry, final CacheEntry parent, final ListenerBase base, final Procedure<T> procedure,
-                       boolean inferredDependency) {
-
-               if (DebugPolicy.PERFORM)
-                       System.out.println("PE[ " + (query.hashCode() & THREAD_MASK) + "] " + query);
-
-               assert (!dirty);
-               assert (!collecting);
-
-               assert(!entry.isPending());
-               assert(!entry.isDiscarded());
-
-               registerDependencies(graph, entry, parent, base, procedure, inferredDependency);
-
-               // FRESH, REFUTED, EXCEPTED go here 
-               if (!entry.isReady()) {
-
-                       entry.setPending();
-                       entry.clearResult(querySupport);
-
-                       externalReadMap.put(query, entry);
-                       size++;
-
-                       try {
-
-                               query.register(graph, new Listener<T>() {
-
-                                       AtomicBoolean used = new AtomicBoolean(false);
-
-                                       @Override
-                                       public void execute(T result) {
-                                               
-                                               // Just for safety
-                                               if(entry.isDiscarded()) return;
-                                               if(entry.isExcepted()) entry.setPending();
-                                               
-                                               if(used.compareAndSet(false, true)) {
-                                                       entry.addOrSet(QueryProcessor.this, result);
-                                                       procedure.execute(result);
-                                               } else {
-                                                       entry.queue(result);
-                                                       updatePrimitive(query);
-                                               }
-                                               
-                                       }
-
-                                       @Override
-                                       public void exception(Throwable t) {
-                                               
-                                               entry.except(t);
-
-                                               if(used.compareAndSet(false, true)) {
-                                                       procedure.exception(t);
-                                               } else {
-//                                                     entry.queue(result);
-                                                       updatePrimitive(query);
-                                               }
-                                               
-                                       }
-
-                                       @Override
-                                       public String toString() {
-                                               return procedure.toString();
-                                       }
-
-                                       @Override
-                                       public boolean isDisposed() {
-                                               return entry.isDiscarded() || !isBound(entry);
-                                       }
-
-                               });
-
-                       } catch (Throwable t) {
-
-                               entry.except(t);
-                               procedure.exception(t);
-
-                       }
-
-                       misses++;
-
-               } else {
-
-                       entry.performFromCache(procedure);
-
-                       hits++;
-
-               }
-
-               assert (!entry.isDiscarded());
-
-       }
-
-       private boolean isBound(ExternalReadEntry<?> entry) {
-               if(entry.hasParents()) return true;
-               else if(hasListener(entry)) return true;
-               else return false;
-       }
-
-       synchronized public ListenerEntry registerDependencies(ReadGraphImpl graph, CacheEntry child, CacheEntry parent, ListenerBase listener, Object procedure, boolean inferred) {
-
-               if (parent != null && !inferred) {
-                       try {
-                               if(!child.isImmutable(graph))
-                                       child.addParent(parent);
-                       } catch (DatabaseException e) {
-                               Logger.defaultLogError(e);
-                       }
-                       if(DebugPolicy.DEPENDENCIES) System.out.println(child + " -> " + parent);
-               }
-
-               if (listener != null) {
-                       return registerListener(child, listener, procedure);
-               } else {
-                       return null;
-               }
-
-       }
-
-       public <Procedure> void performForEach(ReadGraphImpl graph, BinaryQuery<Procedure> query, CacheEntry parent, ListenerBase listener, Procedure procedure) {
-
-               if (DebugPolicy.PERFORM)
-                       System.out.println("PE[ " + (query.hashCode() & THREAD_MASK) + "] " + query);
-
-               assert (!dirty);
-               assert (!collecting);
-
-               try {
-
-                       registerDependencies(graph, query, parent, listener, procedure, false);
-
-                       // FRESH, REFUTED, EXCEPTED go here 
-                       if (!query.isReady()) {
-
-                               boolean fresh = query.isFresh();
-
-                               if(fresh) {
-                                       size++;
-                               }
-
-                               query.computeForEach(graph, this, procedure, true);
-
-                               misses++;
-
-                       } else {
-
-                               query.performFromCache(graph, this, procedure);
-
-                               hits++;
-
-                       }
-
-               } catch (Throwable t) {
-
-                       Logger.defaultLogError(t);
-
-               }
-       }
-
-       public <Procedure> Object performForEach(ReadGraphImpl graph, UnaryQuery<Procedure> query, CacheEntry parent, ListenerBase listener, Procedure procedure) {
-
-               if (DebugPolicy.PERFORM)
-                       System.out.println("PE[ " + (query.hashCode() &  THREAD_MASK) + "] " + query);
-
-               assert (!dirty);
-               assert (!collecting);
-
-               try {
-
-                       assert(query.assertNotDiscarded());
-
-                       registerDependencies(graph, query, parent, listener, procedure, false);
-
-                       // FRESH, REFUTED, EXCEPTED go here 
-                       if (!query.isReady()) {
-
-                               size++;
-                               misses++;
-
-                               return query.computeForEach(graph, this, procedure, true);
-
-
-                       } else {
-
-                               hits++;
-
-                               return query.performFromCache(graph, this, procedure);
-
-                       }
-
-               } catch (Throwable t) {
-
-                       Logger.defaultLogError(t);
-                       return null;
-
-               } 
-
-       }
-       
-       static class Dummy implements InternalProcedure<Object>, IntProcedure {
-
-               @Override
-               public void execute(ReadGraphImpl graph, int i) {
-               }
-
-               @Override
-               public void finished(ReadGraphImpl graph) {
-               }
-
-               @Override
-               public void execute(ReadGraphImpl graph, Object result) {
-               }
-
-               @Override
-               public void exception(ReadGraphImpl graph, Throwable throwable) {
-               }
-               
-       }
-       
-       private static final Dummy dummy = new Dummy();
-
-    public <Procedure> Object performForEach2(ReadGraphImpl graph, UnaryQuery<Procedure> query, CacheEntry parent, ListenerBase listener, Procedure procedure) throws Throwable {
-
-        if (DebugPolicy.PERFORM)
-            System.out.println("PE[ " + (query.hashCode() &  THREAD_MASK) + "] " + query);
-
-        assert (!dirty);
-        assert (!collecting);
-
-        assert(query.assertNotDiscarded());
-
-        registerDependencies(graph, query, parent, listener, procedure, false);
-
-        // FRESH, REFUTED, EXCEPTED go here 
-        if (!query.isReady()) {
-
-            size++;
-            misses++;
-
-            query.computeForEach(graph, this, (Procedure)dummy, true);
-            return query.get(graph, this, null);
-
-        } else {
-
-            hits++;
-
-            return query.get(graph, this, procedure);
-
-        }
-
-    }
-       
-       public <Procedure> void performForEach(ReadGraphImpl graph, StringQuery<Procedure> query, CacheEntry parent, final ListenerBase listener, Procedure procedure) {
-
-               if (DebugPolicy.PERFORM)
-                       System.out.println("PE[ " + (query.hashCode() & THREAD_MASK) + "] " + query);
-
-               assert (!dirty);
-               assert (!collecting);
-
-               try {
-
-                       if(query.isDiscarded()) {
-                               System.err.println("aff");
-                       }
-                       assert(!query.isDiscarded());
-
-                       // FRESH, REFUTED, EXCEPTED go here 
-                       if (!query.isReady()) {
-
-                               query.computeForEach(graph.withAsyncParent(query), this, procedure);
-
-                               size++;
-                               misses++;
-
-                       } else {
-
-                               query.performFromCache(graph, this, procedure);
-
-                               hits++;
-
-                       }
-
-                       assert (!query.isDiscarded());
-
-                       registerDependencies(graph, query, parent, listener, procedure, false);
-
-               } catch (Throwable t) {
-
-                       t.printStackTrace();
-                       Logger.defaultLogError(t);
-
-               }
-
-       }
-
-       interface QueryCollectorSupport {
-               public CacheCollectionResult allCaches();
-               public Collection<CacheEntry> getRootList();
-               public int getCurrentSize();
-               public int calculateCurrentSize();
-               public CacheEntryBase iterate(int level);
-               public void remove();
-               public void setLevel(CacheEntryBase entry, int level);
-               public boolean start(boolean flush);
-       }
-
-       interface QueryCollector {
-
-               public void collect(int youngTarget, int allowedTimeInMs);
-
-       }
-
-       class QueryCollectorSupportImpl implements QueryCollectorSupport {
-
-               private static final boolean DEBUG = false;
-               private static final double ITERATION_RATIO = 0.2;
-               
-               private CacheCollectionResult iteration = new CacheCollectionResult();
-               private boolean fresh = true;
-               private boolean needDataInStart = true;
-               
-               QueryCollectorSupportImpl() {
-                       iteration.restart();
-               }
+               private static final boolean DEBUG = false;
+               private static final double ITERATION_RATIO = 0.2;
+               
+               private CacheCollectionResult iteration = new CacheCollectionResult();
+               private boolean fresh = true;
+               private boolean needDataInStart = true;
+               
+               QueryCollectorSupportImpl() {
+                       iteration.restart();
+               }
 
                public CacheCollectionResult allCaches() {
                        CacheCollectionResult result = new CacheCollectionResult();
@@ -1690,106 +870,17 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                }
 
                public Collection<CacheEntry> getRootList() {
-
-                       ArrayList<CacheEntry> result = new ArrayList<CacheEntry>();
-
-                       for (Object e : valueMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : directPredicatesMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : objectsMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : directObjectsMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : principalTypesMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : superRelationsMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : superTypesMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : typesMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : objectsMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : assertedStatementsMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : readMap.values()) {
-                               if(e instanceof CacheEntry) {
-                                       result.add((CacheEntry) e);
-                               } else {
-                                       System.err.println("e=" + e);
-                               }
-                       }
-                       for (Object e : asyncReadMap.values()) {
-                               if(e instanceof CacheEntry) {
-                                       result.add((CacheEntry) e);
-                               } else {
-                                       System.err.println("e=" + e);
-                               }
-                       }
-                       for (Object e : externalReadMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-                       for (Object e : orderedSetMap.values()) {
-                               result.add((CacheEntry) e);
-                       }
-
-                       return result;
-
+                       return cache.getRootList();
                }
 
                @Override
                public int calculateCurrentSize() {
-                       
-                       int realSize = 0;
-                       
-                       realSize += directPredicatesMap.size();
-                       realSize += principalTypesMap.size();
-                       realSize += uriToResourceMap.size();
-                       realSize += namespaceIndexMap22.size();
-                       realSize += projectsMap.size();
-                       
-                       realSize += relationInfoMap.size();
-                       realSize += superTypesMap.size();
-                       realSize += typeHierarchyMap.size();
-                       realSize += superRelationsMap.size();
-                       realSize += typesMap.size();
-                       
-                       realSize += valueMap.size();
-                       realSize += directObjectsMap.size();
-                       realSize += objectsMap.size();
-                       realSize += orderedSetMap.size();
-                       realSize += predicatesMap.size();
-                       
-                       realSize += statementsMap.size();
-                       realSize += assertedPredicatesMap.size();
-                       realSize += assertedStatementsMap.size();
-                       realSize += externalReadMap.size();
-                       realSize += asyncReadMap.size();
-                       
-                       realSize += readMap.size();
-                       realSize += asyncMultiReadMap.size();
-                       realSize += multiReadMap.size();
-                       
-                       size = realSize;
-                       
-                       return realSize;
-                       
+                       return cache.calculateCurrentSize();
                }
 
                @Override
                public int getCurrentSize() {
-                       return size;
+                       return cache.size;
                }
 
        }
@@ -1799,7 +890,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        private QueryCollector collector = new QueryCollectorImpl(this, collectorSupport);
 
     public int querySize() {
-        return size;
+        return cache.size;
     }
 
        public void gc(int youngTarget, int allowedTimeInMs) {
@@ -1828,10 +919,10 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                assert (entry != null);
                assert (procedure != null);
 
-               ArrayList<ListenerEntry> list = listeners.get(entry);
+               ArrayList<ListenerEntry> list = cache.listeners.get(entry);
                if (list == null) {
                        list = new ArrayList<ListenerEntry>(1);
-                       listeners.put(entry, list);
+                       cache.listeners.put(entry, list);
                }
 
                ListenerEntry result = new ListenerEntry(entry, base, procedure);
@@ -1862,22 +953,22 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        private void removeListener(ListenerEntry entry) {
                assert (entry != null);
-               ArrayList<ListenerEntry> list = listeners.get(entry.entry);
+               ArrayList<ListenerEntry> list = cache.listeners.get(entry.entry);
                if(list == null) return;
                boolean success = list.remove(entry);
                assert (success);
                if (list.isEmpty())
-                       listeners.remove(entry.entry);
+                       cache.listeners.remove(entry.entry);
        }
 
        private boolean hasListener(CacheEntry entry) {
-               if(listeners.get(entry) != null) return true;
+               if(cache.listeners.get(entry) != null) return true;
                return false;
        }
 
        boolean hasListenerAfterDisposing(CacheEntry entry) {
-               if(listeners.get(entry) != null) {
-                       ArrayList<ListenerEntry> entries = listeners.get(entry);
+               if(cache.listeners.get(entry) != null) {
+                       ArrayList<ListenerEntry> entries = cache.listeners.get(entry);
                        ArrayList<ListenerEntry> list = null;
                        for (ListenerEntry e : entries) {
                                if (e.base.isDisposed()) {
@@ -1891,7 +982,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                                }
                        }
                        if (entries.isEmpty()) {
-                               listeners.remove(entry);
+                               cache.listeners.remove(entry);
                                return false;
                        }
                        return true;
@@ -1901,13 +992,13 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        List<ListenerEntry> getListenerEntries(CacheEntry entry) {
                hasListenerAfterDisposing(entry);
-               if(listeners.get(entry) != null)
-                       return listeners.get(entry);
+               if(cache.listeners.get(entry) != null)
+                       return cache.listeners.get(entry);
                else 
                        return Collections.emptyList();
        }
 
-       void processListenerReport(CacheEntry entry, Map<CacheEntry, Set<ListenerBase>> workarea) {
+       void processListenerReport(CacheEntry<?> entry, Map<CacheEntry, Set<ListenerBase>> workarea) {
 
                if(!workarea.containsKey(entry)) {
 
@@ -2078,7 +1169,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        int unboundCounter = 0;
                        int unknownCounter = 0;
 
-                       for(CacheEntry entry : workarea.keySet()) {
+                       for(CacheEntry<?> entry : workarea.keySet()) {
 
                                //System.err.println("process " + entry);
 
@@ -2286,8 +1377,8 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
                query.removeEntry(this);
 
-               updates++;
-               size--;
+               cache.updates++;
+               cache.size--;
 
                if((entry.getGCStatus() & CacheEntry.HAS_BEEN_BOUND) != 0)
                        boundQueries--;
@@ -2308,7 +1399,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
                CacheEntry entry = e.entry;
 
-//             System.err.println("updateQuery " + entry);
+               //System.err.println("updateQuery " + entry);
                
                /*
                 * If the dependency graph forms a DAG, some entries are inserted in the
@@ -2355,7 +1446,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        }
                }
 
-               updates++;
+               cache.updates++;
 
                if (Development.DEVELOPMENT) {
                        if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
@@ -2420,7 +1511,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //             System.err.println(" => FOO " + type);
 
                if (hasListener) {
-                       ArrayList<ListenerEntry> entries = listeners.get(entry);
+                       ArrayList<ListenerEntry> entries = cache.listeners.get(entry);
                        if(entries != null) {
                                for (ListenerEntry le : entries) {
                                        scheduleListener(le);
@@ -2504,7 +1595,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        
                        ReadGraphImpl parentGraph = graph.withParent(entry);
 
-                       query.recompute(parentGraph, this, entry);
+                       query.recompute(parentGraph);
 
                        if(entry.isExcepted()) return ListenerEntry.NO_VALUE;
 
@@ -2555,7 +1646,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        public void performScheduledUpdates(WriteGraphImpl graph) {
 
                assert (!updating);
-               assert (!collecting);
+               assert (!cache.collecting);
                assert (!firingListeners);
 
                firingListeners = true;
@@ -2603,7 +1694,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                                        try {
                                                if(DebugPolicy.LISTENER)
                                                        System.out.println("Firing " + listenerEntry.procedure + " for " + listenerEntry.entry);
-                                               entry.performFromCache(graph, this, listenerEntry.procedure);
+                                               entry.performFromCache(graph, listenerEntry.procedure);
                                        } catch (Throwable t) {
                                                t.printStackTrace();
                                        }
@@ -2627,7 +1718,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
         */
        public boolean update(final ReadGraphImpl graph, final CacheEntry entry) {
 
-               assert (!collecting);
+               assert (!cache.collecting);
                assert (!updating);
                updating = true;
 
@@ -2695,8 +1786,6 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        }
 
-       volatile public boolean dirty = false;
-
        private ObjectUpdateSet scheduledObjectUpdates = new ObjectUpdateSet();
        private ValueUpdateSet scheduledValueUpdates = new ValueUpdateSet();
        private ValueUpdateSet scheduledInvalidates = new ValueUpdateSet();
@@ -2706,7 +1795,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        public void performDirtyUpdates(final ReadGraphImpl graph) {
 
-               dirty = false;
+               cache.dirty = false;
                lastInvalidate = 0;
 
                if (Development.DEVELOPMENT) {
@@ -2723,14 +1812,14 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        final int subject = (int)(arg0 >>> 32);
                        final int predicate = (int)(arg0 & 0xffffffff);
 
-                       for(Objects o : Objects.entries(QueryProcessor.this, subject)) update(graph, o);
-                       for(DirectObjects o : DirectObjects.entries(QueryProcessor.this, subject)) update(graph, o);
-                       for(Statements o : Statements.entries(QueryProcessor.this, subject)) update(graph, o);
+                       for(Objects o : QueryCache.entriesObjects(QueryProcessor.this, subject)) update(graph, o);
+                       for(DirectObjects o : QueryCache.entriesDirectObjects(QueryProcessor.this, subject)) update(graph, o);
+                       for(Statements o : QueryCache.entriesStatements(QueryProcessor.this, subject)) update(graph, o);
 
                        if(predicate == instanceOf || predicate == inherits || predicate == subrelationOf) {
-                               PrincipalTypes principalTypes = PrincipalTypes.entry(QueryProcessor.this, subject);
+                               PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, subject);
                                if(principalTypes != null) update(graph, principalTypes);
-                               Types types = Types.entry(QueryProcessor.this, subject);
+                               Types types = QueryCache.entryTypes(QueryProcessor.this, subject);
                                if(types != null) update(graph, types);
                        }
 
@@ -2739,9 +1828,9 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                                if(superRelations != null) update(graph, superRelations);
                        }
 
-                       DirectPredicates dp = DirectPredicates.entry(QueryProcessor.this, subject);
+                       DirectPredicates dp = QueryCache.entryDirectPredicates(QueryProcessor.this, subject);
                        if(dp != null) update(graph, dp);
-                       OrderedSet os = OrderedSet.entry(QueryProcessor.this, predicate);
+                       OrderedSet os = QueryCache.entryOrderedSet(QueryProcessor.this, predicate);
                        if(os != null) update(graph, os);
 
                        scheduledObjectUpdates.clear();
@@ -2754,7 +1843,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
                        int arg0 = scheduledValueUpdates.getFirst();
 
-                       ValueQuery valueQuery = ValueQuery.entry(QueryProcessor.this, arg0);
+                       ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, arg0);
                        if(valueQuery != null) update(graph, valueQuery);
 
                        scheduledValueUpdates.clear();
@@ -2776,11 +1865,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        @Override
                        public boolean execute(Object arg0) {
 
-                               ExternalReadEntry query = (ExternalReadEntry)externalReadMap.get(arg0);
+                               ExternalReadEntry query = (ExternalReadEntry)cache.externalReadEntryMap.get(arg0);
                                if (query != null) {
                                        boolean listening = update(graph, query);
                                        if (!listening && !query.hasParents()) {
-                                               externalReadMap.remove(arg0);
+                                               cache.externalReadEntryMap.remove(arg0);
                                                query.discard();
                                        }
                                }
@@ -2793,7 +1882,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
                        @Override
                        public boolean execute(int arg0) {
-                               ValueQuery valueQuery = ValueQuery.entry(QueryProcessor.this, arg0);
+                               ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, arg0);
                                if(valueQuery != null) update(graph, valueQuery);
                                return true;
                        }
@@ -2805,12 +1894,12 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        @Override
                        public boolean execute(int resource) {
                                
-                               ValueQuery valueQuery = ValueQuery.entry(QueryProcessor.this, resource);
+                               ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, resource);
                                if(valueQuery != null) update(graph, valueQuery);
                                
-                               PrincipalTypes principalTypes = PrincipalTypes.entry(QueryProcessor.this, resource);
+                               PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, resource);
                                if(principalTypes != null) update(graph, principalTypes);
-                               Types types = Types.entry(QueryProcessor.this, resource);
+                               Types types = QueryCache.entryTypes(QueryProcessor.this, resource);
                                if(types != null) update(graph, types);
 
                                SuperRelations superRelations = SuperRelations.entry(QueryProcessor.this, resource);
@@ -2832,9 +1921,9 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                                final int predicate = (int)(arg0 & 0xffffffff);
 
                                if(predicate == instanceOf || predicate == inherits || predicate == subrelationOf) {
-                                       PrincipalTypes principalTypes = PrincipalTypes.entry(QueryProcessor.this, subject);
+                                       PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, subject);
                                        if(principalTypes != null) update(graph, principalTypes);
-                                       Types types = Types.entry(QueryProcessor.this, subject);
+                                       Types types = QueryCache.entryTypes(QueryProcessor.this, subject);
                                        if(types != null) update(graph, types);
                                }
 
@@ -2857,11 +1946,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        @Override
                        public boolean execute(final int subject) {
 
-                               for(Objects o : Objects.entries(QueryProcessor.this, subject)) update(graph, o);
-                               for(DirectObjects o : DirectObjects.entries(QueryProcessor.this, subject)) update(graph, o);
-                               for(Statements o : Statements.entries(QueryProcessor.this, subject)) update(graph, o);
+                               for(Objects o : QueryCache.entriesObjects(QueryProcessor.this, subject)) update(graph, o);
+                               for(DirectObjects o : QueryCache.entriesDirectObjects(QueryProcessor.this, subject)) update(graph, o);
+                               for(Statements o : QueryCache.entriesStatements(QueryProcessor.this, subject)) update(graph, o);
 
-                               DirectPredicates entry = DirectPredicates.entry(QueryProcessor.this, subject);
+                               DirectPredicates entry = QueryCache.entryDirectPredicates(QueryProcessor.this, subject);
                                if(entry != null) update(graph, entry);
 
                                return true;
@@ -2875,7 +1964,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        @Override
                        public boolean execute(int orderedSet) {
 
-                               OrderedSet entry = OrderedSet.entry(QueryProcessor.this, orderedSet);
+                               OrderedSet entry = QueryCache.entryOrderedSet(QueryProcessor.this, orderedSet);
                                if(entry != null) update(graph, entry);
 
                                return true;
@@ -2904,12 +1993,12 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        public void updateValue(final int resource) {
                scheduledValueUpdates.add(resource);
-               dirty = true;
+               cache.dirty = true;
        }
 
        public void updateStatements(final int resource, final int predicate) {
                scheduledObjectUpdates.add((((long)resource) << 32) + predicate);
-               dirty = true;
+               cache.dirty = true;
        }
        
        private int lastInvalidate = 0;
@@ -2918,7 +2007,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                if(lastInvalidate == resource) return;
                scheduledValueUpdates.add(resource);
                lastInvalidate = resource;
-               dirty = true;
+               cache.dirty = true;
        }
 
        public void updatePrimitive(final ExternalRead primitive) {
@@ -2934,7 +2023,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        @Override
        public synchronized String toString() {
-               return "QueryProvider [size = " + size + ", hits = " + hits + " misses = " + misses + ", updates = " + updates + "]";
+               return "QueryProvider [size = " + cache.size + ", hits = " + cache.hits + " misses = " + cache.misses + ", updates = " + cache.updates + "]";
        }
 
        @Override
@@ -2990,28 +2079,28 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        }
 
        public int getHits() {
-               return hits;
+               return cache.hits;
        }
 
        public int getMisses() {
-               return misses;
+               return cache.misses;
        }
 
        public int getSize() {
-               return size;
+               return cache.size;
        }
 
        public Set<Long> getReferencedClusters() {
                HashSet<Long> result = new HashSet<Long>();
-               for (CacheEntry entry : objectsMap.values()) {
+               for (CacheEntry entry : QueryCache.entriesObjects(this)) {
                        Objects query = (Objects) entry.getQuery();
                        result.add(querySupport.getClusterId(query.r1()));
                }
-               for (CacheEntry entry : directPredicatesMap.values()) {
+               for (CacheEntry entry : QueryCache.entriesDirectPredicates(this)) {
                        DirectPredicates query = (DirectPredicates) entry.getQuery();
                        result.add(querySupport.getClusterId(query.id));
                }
-               for (CacheEntry entry : valueMap.values()) {
+               for (CacheEntry entry : cache.valueQueryMap.values()) {
                        ValueQuery query = (ValueQuery) entry.getQuery();
                        result.add(querySupport.getClusterId(query.id));
                }
@@ -3022,41 +2111,8 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        }
 
        CacheCollectionResult allCaches(CacheCollectionResult result) {
-
-               int level = Integer.MAX_VALUE;
-               directPredicatesMap.values(level, result);
-               principalTypesMap.values(level, result);
-               for(CacheEntryBase e : uriToResourceMap.values())
-                       if(e.getLevel() <= level)
-                               result.add(e);
-               for(CacheEntryBase e : namespaceIndexMap22.values())
-                       if(e.getLevel() <= level)
-                               result.add(e);
-               projectsMap.values(level, result);
-               
-               relationInfoMap.values(level, result);
-               superTypesMap.values(level, result);
-               typeHierarchyMap.values(level, result);
-               superRelationsMap.values(level, result);
-               typesMap.values(level, result);
-
-               valueMap.values(level, result);
-               directObjectsMap.values(level, result);
-               objectsMap.values(level, result);
-               orderedSetMap.values(level, result);
-               predicatesMap.values(level, result);
-
-               statementsMap.values(level, result);
-               assertedPredicatesMap.values(level, result);
-               assertedStatementsMap.values(level, result);
-               externalReadMap.values(level, result);
-               asyncReadMap.values(level, result);
                
-               readMap.values(level, result);
-               asyncMultiReadMap.values(level, result);
-               multiReadMap.values(level, result);
-
-               return result;
+               return cache.allCaches(result);
 
        }
 
@@ -3069,7 +2125,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        public int clean() {
                collector.collect(0, Integer.MAX_VALUE);
-               return size;
+               return cache.size;
        }
 
        public void clean(final Collection<ExternalRead<?>> requests) {
@@ -3083,7 +2139,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        public CacheEntryBase iterate(int level) {
                                if(iterator.hasNext()) {
                                        ExternalRead<?> request = iterator.next();
-                                       ExternalReadEntry entry = externalReadMap.get(request);
+                                       ExternalReadEntry entry = cache.externalReadEntryMap.get(request);
                                        if (entry != null) return entry;
                                        else return iterate(level);
                                } else {
@@ -3103,7 +2159,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        public Collection<CacheEntry> getRootList() {
                                ArrayList<CacheEntry> result = new ArrayList<CacheEntry>(requests.size());
                                for (ExternalRead<?> request : requests) {
-                                       ExternalReadEntry entry = externalReadMap.get(request);
+                                       ExternalReadEntry entry = cache.externalReadEntryMap.get(request);
                                        if (entry != null)
                                                result.add(entry);
                                }
@@ -3111,7 +2167,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                        }
                        @Override
                        public int getCurrentSize() {
-                               return size;
+                               return cache.size;
                        }
                        @Override
                        public int calculateCurrentSize() {
@@ -3127,48 +2183,8 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        }
 
        public void scanPending() {
-
-               ArrayList<CacheEntry> entries = new ArrayList<CacheEntry>();
-
-               entries.addAll(directPredicatesMap.values());
-               entries.addAll(principalTypesMap.values());
-               entries.addAll(uriToResourceMap.values());
-               entries.addAll(namespaceIndexMap22.values());
-               entries.addAll(projectsMap.values());
-               entries.addAll(relationInfoMap.values());
-               entries.addAll(superTypesMap.values());
-               entries.addAll(superRelationsMap.values());
-               entries.addAll(typesMap.values());
-               entries.addAll(valueMap.values());
-               entries.addAll(directObjectsMap.values());
-               entries.addAll(objectsMap.values());
-               entries.addAll(orderedSetMap.values());
-               entries.addAll(predicatesMap.values());
-               entries.addAll(orderedSetMap.values());
-               entries.addAll(statementsMap.values());
-               //                      entries.addAll(assertedObjectsMap.values());
-               entries.addAll(assertedPredicatesMap.values());
-               entries.addAll(assertedStatementsMap.values());
-               entries.addAll(externalReadMap.values());
-               entries.addAll(asyncReadMap.values());
-               entries.addAll(externalReadMap.values());
-               entries.addAll(readMap.values());
-               entries.addAll(asyncMultiReadMap.values());
-               entries.addAll(multiReadMap.values());
-               entries.addAll(readMap.values());
-               System.out.println(entries.size() + " entries.");
-               for(Object e : entries) {
-                       if(e instanceof CacheEntry) {
-                               CacheEntry en = (CacheEntry)e;
-                               if(en.isPending()) System.out.println("pending " + e);
-                               if(en.isExcepted()) System.out.println("excepted " + e);
-                               if(en.isDiscarded()) System.out.println("discarded " + e);
-                               if(en.isRefuted()) System.out.println("refuted " + e);
-                               if(en.isFresh()) System.out.println("fresh " + e);
-                       } else {
-                               //System.out.println("Unknown object " + e);
-                       }
-               }
+               
+               cache.scanPending();
 
        }
 
@@ -3252,122 +2268,123 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        @Override
        final public void forEachPredicate(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
 
-               assert(subject != null);
-               assert(procedure != null);
-
-               final ListenerBase listener = getListenerBase(procedure);
-
-               IntProcedure ip = new IntProcedure() {
-
-                       AtomicBoolean first = new AtomicBoolean(true);
-
-                       @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-                               try {
-                                       if(first.get()) {
-                                               procedure.execute(graph, querySupport.getResource(i));
-                                       } else {
-                                               procedure.execute(impl.newRestart(graph), querySupport.getResource(i));
-                                       }
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-                       }
-
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               try {
-                                       if(first.compareAndSet(true, false)) {
-                                               procedure.finished(graph);
-//                                             impl.state.barrier.dec(this);
-                                       } else {
-                                               procedure.finished(impl.newRestart(graph));
-                                       }
+               throw new UnsupportedOperationException();
 
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       if(first.compareAndSet(true, false)) {
-                                               procedure.exception(graph, t);
-//                                             impl.state.barrier.dec(this);
-                                       } else {
-                                               procedure.exception(impl.newRestart(graph), t);
-                                       }
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-                       }
-
-               };
-
-               int sId = querySupport.getId(subject);
-
-//             if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#Predicates#" + sId);
-//             else impl.state.barrier.inc(null, null);
-
-               Predicates.queryEach(impl, sId, this, impl.parent, listener, ip);
+//             assert(subject != null);
+//             assert(procedure != null);
+//
+//             final ListenerBase listener = getListenerBase(procedure);
+//
+//             IntProcedure ip = new IntProcedure() {
+//
+//                     AtomicBoolean first = new AtomicBoolean(true);
+//
+//                     @Override
+//                     public void execute(ReadGraphImpl graph, int i) {
+//                             try {
+//                                     if(first.get()) {
+//                                             procedure.execute(graph, querySupport.getResource(i));
+//                                     } else {
+//                                             procedure.execute(impl.newRestart(graph), querySupport.getResource(i));
+//                                     }
+//                             } catch (Throwable t2) {
+//                                     Logger.defaultLogError(t2);
+//                             }
+//                     }
+//
+//                     @Override
+//                     public void finished(ReadGraphImpl graph) {
+//                             try {
+//                                     if(first.compareAndSet(true, false)) {
+//                                             procedure.finished(graph);
+////                                           impl.state.barrier.dec(this);
+//                                     } else {
+//                                             procedure.finished(impl.newRestart(graph));
+//                                     }
+//
+//                             } catch (Throwable t2) {
+//                                     Logger.defaultLogError(t2);
+//                             }
+//                     }
+//
+//                     @Override
+//                     public void exception(ReadGraphImpl graph, Throwable t) {
+//                             try {
+//                                     if(first.compareAndSet(true, false)) {
+//                                             procedure.exception(graph, t);
+//                                     } else {
+//                                             procedure.exception(impl.newRestart(graph), t);
+//                                     }
+//                             } catch (Throwable t2) {
+//                                     Logger.defaultLogError(t2);
+//                             }
+//                     }
+//
+//             };
+//
+//             int sId = querySupport.getId(subject);
+//
+//             try {
+//                     QueryCache.runnerPredicates(impl, sId, impl.parent, listener, ip);
+//             } catch (DatabaseException e) {
+//                     Logger.defaultLogError(e);
+//             }
 
        }
 
        @Override
        final public void forEachPredicate(final ReadGraphImpl impl, final Resource subject, final MultiProcedure<Resource> procedure) {
+               
+               throw new UnsupportedOperationException();
 
-               assert(subject != null);
-               assert(procedure != null);
-
-               final ListenerBase listener = getListenerBase(procedure);
-
-//             impl.state.barrier.inc();
-
-               Predicates.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, new IntProcedure() {
-
-                       @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-                               try {
-                                       procedure.execute(querySupport.getResource(i));
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-                       }
-
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               try {
-                                       procedure.finished();
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-//                             impl.state.barrier.dec();
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       procedure.exception(t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-//                             impl.state.barrier.dec();
-                       }
-
-               });
+//             assert(subject != null);
+//             assert(procedure != null);
+//
+//             final ListenerBase listener = getListenerBase(procedure);
+//
+//             try {
+//                     QueryCache.runnerPredicates(impl, querySupport.getId(subject), impl.parent, listener, new IntProcedure() {
+//
+//                             @Override
+//                             public void execute(ReadGraphImpl graph, int i) {
+//                                     try {
+//                                             procedure.execute(querySupport.getResource(i));
+//                                     } catch (Throwable t2) {
+//                                             Logger.defaultLogError(t2);
+//                                     }
+//                             }
+//
+//                             @Override
+//                             public void finished(ReadGraphImpl graph) {
+//                                     try {
+//                                             procedure.finished();
+//                                     } catch (Throwable t2) {
+//                                             Logger.defaultLogError(t2);
+//                                     }
+////                           impl.state.barrier.dec();
+//                             }
+//
+//                             @Override
+//                             public void exception(ReadGraphImpl graph, Throwable t) {
+//                                     try {
+//                                             procedure.exception(t);
+//                                     } catch (Throwable t2) {
+//                                             Logger.defaultLogError(t2);
+//                                     }
+////                           impl.state.barrier.dec();
+//                             }
+//
+//                     });
+//             } catch (DatabaseException e) {
+//                     Logger.defaultLogError(e);
+//             }
 
        }
        
        @Override
        final public IntSet getPredicates(final ReadGraphImpl impl, final Resource subject) throws Throwable {
-
-               assert(subject != null);
-               
-               return Predicates.queryEach2(impl, querySupport.getId(subject), this, impl.parent);
-
+               return QueryCacheBase.resultPredicates(impl, querySupport.getId(subject), impl.parent, null); 
        }
-       
 
        @Override
        final public void forEachStatement(final ReadGraphImpl impl, final Resource subject,
@@ -3381,38 +2398,42 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
 //             impl.state.barrier.inc();
 
-               Statements.queryEach(impl, querySupport.getId(subject), querySupport.getId(predicate), this, impl.parent, listener, new TripleIntProcedureAdapter() {
+               try {
+                       Statements.queryEach(impl, querySupport.getId(subject), querySupport.getId(predicate), this, impl.parent, listener, new TripleIntProcedureAdapter() {
 
-                       @Override
-                       public void execute(ReadGraphImpl graph, int s, int p, int o) {
-                               try {
-                                       procedure.execute(querySupport.getStatement(s, p, o));
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
+                               @Override
+                               public void execute(ReadGraphImpl graph, int s, int p, int o) {
+                                       try {
+                                               procedure.execute(querySupport.getStatement(s, p, o));
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
                                }
-                       }
 
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               try {
-                                       procedure.finished();
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
+                               @Override
+                               public void finished(ReadGraphImpl graph) {
+                                       try {
+                                               procedure.finished();
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       procedure.exception(t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
                                }
+
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                       try {
+                                               procedure.exception(t);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
+                               }
 
-               });
+                       });
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
@@ -3485,7 +2506,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //             if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(proc, "#Statements" + sId + "#" + pId);
 //             else impl.state.barrier.inc(null, null);
 
-               Statements.queryEach(impl, sId, pId, this, impl.parent, listener, proc);
+               try {
+                       Statements.queryEach(impl, sId, pId, this, impl.parent, listener, proc);
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
@@ -3558,7 +2583,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //             if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(proc, "#Statements" + sId + "#" + pId);
 //             else impl.state.barrier.inc(null, null);
 
-               Statements.queryEach(impl, sId, pId, this, impl.parent, listener, proc);
+               try {
+                       Statements.queryEach(impl, sId, pId, this, impl.parent, listener, proc);
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
        
@@ -3630,38 +2659,42 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
 //             impl.state.barrier.inc();
 
-               AssertedStatements.queryEach(impl, querySupport.getId(subject), querySupport.getId(predicate), this, impl.parent, listener, new TripleIntProcedureAdapter() {
+               try {
+                       QueryCache.runnerAssertedStatements(impl, querySupport.getId(subject), querySupport.getId(predicate), impl.parent, listener, new TripleIntProcedureAdapter() {
 
-                       @Override
-                       public void execute(ReadGraphImpl graph, int s, int p, int o) {
-                               try {
-                                       procedure.execute(graph, querySupport.getStatement(s, p, o));
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
+                               @Override
+                               public void execute(ReadGraphImpl graph, int s, int p, int o) {
+                                       try {
+                                               procedure.execute(graph, querySupport.getStatement(s, p, o));
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
                                }
-                       }
 
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               try {
-                                       procedure.finished(graph);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
+                               @Override
+                               public void finished(ReadGraphImpl graph) {
+                                       try {
+                                               procedure.finished(graph);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       procedure.exception(graph, t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
                                }
+
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                       try {
+                                               procedure.exception(graph, t);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
+                               }
 
-               });
+                       });
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
@@ -3681,111 +2714,101 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
 //             impl.state.barrier.inc();
 
-               Objects.runner(impl, querySupport.getId(subject), querySupport.getId(predicate), impl.parent, listener, new IntProcedure() {
+               try {
+                       QueryCache.runnerObjects(impl, querySupport.getId(subject), querySupport.getId(predicate), impl.parent, listener, new IntProcedure() {
 
-                       @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-                               try {
-                                       procedure.execute(querySupport.getResource(i));
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
+                               @Override
+                               public void execute(ReadGraphImpl graph, int i) {
+                                       try {
+                                               procedure.execute(querySupport.getResource(i));
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
                                }
-                       }
 
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               try {
-                                       procedure.finished();
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
+                               @Override
+                               public void finished(ReadGraphImpl graph) {
+                                       try {
+                                               procedure.finished();
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               System.out.println("forEachObject exception " + t);
-                               try {
-                                       procedure.exception(t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
                                }
+
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                       System.out.println("forEachObject exception " + t);
+                                       try {
+                                               procedure.exception(t);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
+                               }
 
-               });
+                       });
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
-
-//     @Override
-//     final public void forEachDirectObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncMultiProcedure<Resource> procedure) {
-//
-//             assert(subject != null);
-//             assert(predicate != null);
-//             assert(procedure != null);
-//
-//             final ListenerBase listener = getListenerBase(procedure);
-//
-//             int sId = querySupport.getId(subject);
-//             int pId = querySupport.getId(predicate);
-//
-//             MultiIntProcedure proc = new MultiIntProcedure(procedure, impl, support);
-//
-//             if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(proc, "#DirectObjects" + sId + "#" + pId);
-//             else impl.state.barrier.inc(null, null);
-//
-//             //        final Exception caller = new Exception();
-//
-//             //        final Pair<Exception, Exception> exceptions = Pair.make(callerException, new Exception());
-//
-//             DirectObjects.queryEach(impl, sId, pId, processor, impl.parent, listener, proc);
-//
-//     }
-
        @Override
-       final public void forEachDirectPredicate(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
+       final public void forEachDirectPredicate(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
 
                assert(subject != null);
                assert(procedure != null);
 
                final ListenerBase listener = getListenerBase(procedure);
 
-               MultiIntProcedure proc = new MultiIntProcedure(procedure, impl, querySupport);
-
                int sId = querySupport.getId(subject);
 
-//             if(AsyncBarrierImpl.BOOKKEEPING)  impl.state.barrier.inc(proc, "#DirectPredicates" + sId);
-//             else impl.state.barrier.inc(null, null);
-
-               DirectPredicates.queryEach(impl, sId, this, impl.parent, listener, proc);
-
-       }
-
-       @Override
-       final public void forEachDirectStatement(final ReadGraphImpl impl, final Resource subject, final Procedure<DirectStatements> procedure) {
-
-               assert(subject != null);
-               assert(procedure != null);
+               try {
+                       QueryCache.runnerDirectPredicates(impl, sId, impl.parent, listener, new InternalProcedure<IntSet>() {
 
-               final ListenerBase listener = getListenerBase(procedure);
+                               @Override
+                               public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
+                                       procedure.execute(graph, result);
+                               }
 
-               org.simantics.db.impl.query.DirectStatements.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, procedure);
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+                                       procedure.exception(graph, throwable);
+                               }
+                               
+                       });
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
-       @Override
-       final public void forEachDirectStatement(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<DirectStatements> procedure, boolean ignoreVirtual) {
-
-               assert(subject != null);
-               assert(procedure != null);
-
-               final ListenerBase listener = getListenerBase(procedure);
+       final public DirectStatements getDirectStatements(final ReadGraphImpl impl, final Resource subject, final boolean ignoreVirtual) {
 
-               org.simantics.db.impl.query.DirectStatements.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, procedure, ignoreVirtual);
+//             assert(subject != null);
+//             assert(procedure != null);
+//
+//             final ListenerBase listener = getListenerBase(procedure);
+//
+//             org.simantics.db.impl.query.DirectStatements.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, procedure);
+               
+               return querySupport.getStatements(impl, querySupport.getId(subject), this, ignoreVirtual);
 
        }
 
+//     @Override
+//     final public void forEachDirectStatement(final ReadGraphImpl impl, final Resource subject, final SyncProcedure<DirectStatements> procedure, boolean ignoreVirtual) {
+//
+//             assert(subject != null);
+//             assert(procedure != null);
+//
+//             final ListenerBase listener = getListenerBase(procedure);
+//
+//             org.simantics.db.impl.query.DirectStatements.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, procedure, ignoreVirtual);
+//
+//     }
+       
        private static final Resource INVALID_RESOURCE = new ResourceImpl(null, Integer.MIN_VALUE);
 
        @Override
@@ -3824,16 +2847,59 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                final int sId = querySupport.getId(subject);
                final int pId = querySupport.getId(predicate);
 
-               Objects.runner(impl, sId, pId, impl.parent, listener, procedure);
+               try {
+                       QueryCache.runnerObjects(impl, sId, pId, impl.parent, listener, procedure);
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
                
        }
        
-       final public int getSingleObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate) throws DatabaseException {
+       static class Runner2Procedure implements IntProcedure {
+           
+           public int single = 0;
+           public Throwable t = null;
+
+           public void clear() {
+               single = 0;
+               t = null;
+           }
+           
+        @Override
+        public void execute(ReadGraphImpl graph, int i) {
+            if(single == 0) single = i;
+            else single = -1;
+        }
+
+        @Override
+        public void finished(ReadGraphImpl graph) {
+            if(single == -1) single = 0;
+        }
 
-        final int sId = querySupport.getId(subject);
-        final int pId = querySupport.getId(predicate);
+        @Override
+        public void exception(ReadGraphImpl graph, Throwable throwable) {
+            single = 0;
+            this.t = throwable;
+        }
+        
+        public int get() throws DatabaseException {
+            if(t != null) {
+                if(t instanceof DatabaseException) throw (DatabaseException)t;
+                else throw new DatabaseException(t);
+            }
+            return single;
+        }
+           
+       }
+       
+       final public int getSingleObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate) throws DatabaseException {
+               
+               final int sId = querySupport.getId(subject);
+               final int pId = querySupport.getId(predicate);
 
-        return Objects.runner2(impl, sId, pId, impl.parent);
+               Runner2Procedure proc = new Runner2Procedure();
+               QueryCache.runnerObjects(impl, sId, pId, impl.parent, null, proc);
+               return proc.get();
            
        }
 
@@ -4245,40 +3311,42 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
                final ListenerBase listener = getListenerBase(procedure);
 
-//             impl.state.barrier.inc();
-
-               AssertedStatements.queryEach(impl, querySupport.getId(subject), querySupport.getId(predicate), this, impl.parent, listener, new TripleIntProcedure() {
+               try {
+                       QueryCache.runnerAssertedStatements(impl, querySupport.getId(subject), querySupport.getId(predicate), impl.parent, listener, new TripleIntProcedure() {
 
-                       @Override
-                       public void execute(ReadGraphImpl graph, int s, int p, int o) {
-                               try {
-                                       procedure.execute(graph, querySupport.getResource(o));
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
+                               @Override
+                               public void execute(ReadGraphImpl graph, int s, int p, int o) {
+                                       try {
+                                               procedure.execute(graph, querySupport.getResource(o));
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
                                }
-                       }
 
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               try {               
-                                       procedure.finished(graph);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
+                               @Override
+                               public void finished(ReadGraphImpl graph) {
+                                       try {               
+                                               procedure.finished(graph);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       procedure.exception(graph, t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
                                }
+
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                       try {
+                                               procedure.exception(graph, t);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
+                               }
 
-               });
+                       });
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
@@ -4328,7 +3396,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //             if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#PrincipalTypes#" + sId);
 //             else impl.state.barrier.inc(null, null);
 
-               PrincipalTypes.queryEach(impl, sId, this, impl.parent, listener, ip);
+               try {
+                       QueryCache.runnerPrincipalTypes(impl, sId, impl.parent, listener, ip);
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
@@ -4342,39 +3414,42 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
 //             impl.state.barrier.inc();
 
-               PrincipalTypes.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, new IntProcedure() {
+               try {
+                       QueryCache.runnerPrincipalTypes(impl, querySupport.getId(subject), impl.parent, listener, new IntProcedure() {
 
-                       @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-                               try {
-                                       procedure.execute(querySupport.getResource(i));
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
+                               @Override
+                               public void execute(ReadGraphImpl graph, int i) {
+                                       try {
+                                               procedure.execute(querySupport.getResource(i));
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
                                }
-                       }
 
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               try {
-                                       procedure.finished();
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
+                               @Override
+                               public void finished(ReadGraphImpl graph) {
+                                       try {
+                                               procedure.finished();
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       procedure.exception(t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
                                }
-//                             impl.state.barrier.dec();
-                       }
 
-               });
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                       try {
+                                               procedure.exception(t);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
+//                             impl.state.barrier.dec();
+                               }
 
+                       });
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
        }
 
     final public void forTypes(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
@@ -4383,47 +3458,29 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
         assert(procedure != null);
 
         final ListenerBase listener = getListenerBase(procedure);
+        assert(listener == null);
 
         InternalProcedure<IntSet> ip = new InternalProcedure<IntSet>() {
 
-            AtomicBoolean first = new AtomicBoolean(true);
-
             @Override
             public void execute(final ReadGraphImpl graph, IntSet set) {
-                try {
-                    if(first.compareAndSet(true, false)) {
-                        procedure.execute(graph, set);
-//                      impl.state.barrier.dec(this);
-                    } else {
-                        procedure.execute(impl.newRestart(graph), set);
-                    }
-                } catch (Throwable t2) {
-                    Logger.defaultLogError(t2);
-                }
+               procedure.execute(graph, set);
             }
 
             @Override
             public void exception(ReadGraphImpl graph, Throwable t) {
-                try {
-                    if(first.compareAndSet(true, false)) {
-                        procedure.exception(graph, t);
-//                      impl.state.barrier.dec(this);
-                    } else {
-                        procedure.exception(impl.newRestart(graph), t);
-                    }
-                } catch (Throwable t2) {
-                    Logger.defaultLogError(t2);
-                }
+               procedure.exception(graph, t);
             }
 
         };
 
         int sId = querySupport.getId(subject);
 
-//      if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#Types" + sId);
-//      else impl.state.barrier.inc(null, null);
-
-        Types.queryEach(impl, sId, this, impl.parent, listener, ip);
+        try {
+                       QueryCache.runnerTypes(impl, sId, impl.parent, listener, ip);
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
     }
     
@@ -4432,53 +3489,16 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
                assert(subject != null);
                
-               return Types.queryEach2(impl, querySupport.getId(subject), this, impl.parent);
+               return QueryCacheBase.resultTypes(impl, querySupport.getId(subject), impl.parent, null);
 
        }
 
        @Override
-       final public void forRelationInfo(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<RelationInfo> procedure) {
-
+       final public RelationInfo getRelationInfo(final ReadGraphImpl impl, final Resource subject) throws DatabaseException {
+               
                assert(subject != null);
-               assert(procedure != null);
-
-               final ListenerBase listener = getListenerBase(procedure);
-
-//             impl.state.barrier.inc();
-
-               RelationInfoQuery.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, new InternalProcedure<RelationInfo>() {
-
-                       AtomicBoolean first = new AtomicBoolean(true);
-
-                       @Override
-                       public void execute(final ReadGraphImpl graph, RelationInfo set) {
-                               try {
-                                       if(first.compareAndSet(true, false)) {
-                                               procedure.execute(graph, set);
-//                                             impl.state.barrier.dec();
-                                       } else {
-                                               procedure.execute(impl.newRestart(graph), set);
-                                       }
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       if(first.compareAndSet(true, false)) {
-                                               procedure.exception(graph, t);
-//                                             impl.state.barrier.dec("ReadGraphSupportImpl.1353");
-                                       } else {
-                                               procedure.exception(impl.newRestart(graph), t);
-                                       }
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-                       }
 
-               });
+               return QueryCache.resultRelationInfoQuery(impl, querySupport.getId(subject), impl.parent, null);
 
        }
 
@@ -4490,14 +3510,13 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
                final ListenerBase listener = getListenerBase(procedure);
 
-//             impl.state.barrier.inc();
-
-               SuperTypes.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, new InternalProcedure<IntSet>() {
+               try {
+                       QueryCache.runnerSuperTypes(impl, querySupport.getId(subject), impl.parent, listener, new InternalProcedure<IntSet>() {
 
-                       AtomicBoolean first = new AtomicBoolean(true);
+                               AtomicBoolean first = new AtomicBoolean(true);
 
-                       @Override
-                       public void execute(final ReadGraphImpl graph, IntSet set) {
+                               @Override
+                               public void execute(final ReadGraphImpl graph, IntSet set) {
 //                             final HashSet<Resource> result = new HashSet<Resource>();
 //                             set.forEach(new TIntProcedure() {
 //
@@ -4508,33 +3527,36 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //                                     }
 //
 //                             });
-                               try {
-                                       if(first.compareAndSet(true, false)) {
-                                               procedure.execute(graph, set);
+                                       try {
+                                               if(first.compareAndSet(true, false)) {
+                                                       procedure.execute(graph, set);
 //                                             impl.state.barrier.dec();
-                                       } else {
-                                               procedure.execute(impl.newRestart(graph), set);
+                                               } else {
+                                                       procedure.execute(impl.newRestart(graph), set);
+                                               }
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
                                        }
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
                                }
-                       }
 
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       if(first.compareAndSet(true, false)) {
-                                               procedure.exception(graph, t);
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                       try {
+                                               if(first.compareAndSet(true, false)) {
+                                                       procedure.exception(graph, t);
 //                                             impl.state.barrier.dec();
-                                       } else {
-                                               procedure.exception(impl.newRestart(graph), t);
+                                               } else {
+                                                       procedure.exception(impl.newRestart(graph), t);
+                                               }
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
                                        }
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
                                }
-                       }
 
-               });
+                       });
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
@@ -4585,7 +3607,13 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //             if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#DirectSuperRelations#" + sId);
 //             else impl.state.barrier.inc(null, null);
 
-               DirectSuperRelations.queryEach(impl, sId, this, impl.parent, listener, ip);
+               try {
+                       QueryCache.runnerDirectSuperRelations(impl, sId, impl.parent, listener, ip);
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
+               
+//             DirectSuperRelations.queryEach(impl, sId, this, impl.parent, listener, ip);
 
        }
 
@@ -4650,31 +3678,31 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //             if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#SuperRelations#" + sId);
 //             else impl.state.barrier.inc(null, null);
 
-               SuperRelations.queryEach(impl, sId, this, impl.parent, listener, ip);
+               try {
+                       QueryCache.runnerSuperRelations(impl, sId, impl.parent, listener, ip);
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
        final public byte[] getValue(final ReadGraphImpl impl, final Resource subject) throws DatabaseException {
-
-         int sId = querySupport.getId(subject);
-      return ValueQuery.queryEach(impl, sId, impl.parent);
-
+         return getValue(impl, querySupport.getId(subject));
        }
 
        final public byte[] getValue(final ReadGraphImpl impl, final int subject) throws DatabaseException {
-
-           return ValueQuery.queryEach(impl, subject, impl.parent);
-
+               return QueryCache.resultValueQuery(impl, subject, impl.parent, null); 
        }
 
        @Override
-       final public byte[] forValue(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<byte[]> procedure) {
+       final public void forValue(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<byte[]> procedure) {
 
                assert(subject != null);
+               assert(procedure != null);
 
                int sId = querySupport.getId(subject);
 
-               if(procedure != null) {
+//             if(procedure != null) {
                
                        final ListenerBase listener = getListenerBase(procedure);
 
@@ -4715,13 +3743,19 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //                     if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#Value" + sId);
 //                     else impl.state.barrier.inc(null, null);
 
-                       return ValueQuery.queryEach(impl, sId, impl.parent, listener, ip);
-
-               } else {
+                       try {
+                               QueryCache.runnerValueQuery(impl, sId, impl.parent, listener, ip);
+                       } catch (DatabaseException e) {
+                               throw new IllegalStateException("Internal error");
+                       }
 
-                       return ValueQuery.queryEach(impl, sId, impl.parent, null, null);
-                       
-               }
+//             } else {
+//
+//                     return QueryCacheBase.runnerValueQuery(impl, sId, impl.parent, null, null);
+//                     
+//             }
+//             
+//             throw new IllegalStateException("Internal error");
 
        }
 
@@ -4774,7 +3808,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //                     if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#Value" + sId);
 //                     else impl.state.barrier.inc(null, null);
 
-                       ValueQuery.queryEach(impl, sId, impl.parent, listener, ip);
+                       try {
+                               QueryCache.runnerValueQuery(impl, sId, impl.parent, listener, ip);
+                       } catch (DatabaseException e) {
+                               Logger.defaultLogError(e);
+                       }
 
                } else {
 
@@ -4798,7 +3836,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
                        int sId = querySupport.getId(subject);
 
-                       ValueQuery.queryEach(impl, sId, impl.parent, listener, ip);
+                       try {
+                               QueryCache.runnerValueQuery(impl, sId, impl.parent, listener, ip);
+                       } catch (DatabaseException e) {
+                               Logger.defaultLogError(e);
+                       }
 
                }
 
@@ -4878,7 +3920,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //             if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#DirectObjects#" + sId);
 //             else impl.state.barrier.inc(null, null);
 
-               Objects.runner(impl, sId, getInverseOf(), impl.parent, listener, ip);
+               try {
+                       QueryCache.runnerObjects(impl, sId, getInverseOf(), impl.parent, listener, ip);
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
@@ -4916,85 +3962,63 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 //             if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "Resource");
 //             else impl.state.barrier.inc(null, null);
 
-               forResource(impl, id, impl.parent, ip);
-
-       }
-
-       @Override
-       final public void forBuiltin(final ReadGraphImpl impl, final String id, final AsyncProcedure<Resource> procedure) {
-
-               assert(id != null);
-               assert(procedure != null);
-
-//             impl.state.barrier.inc();
-
-               forBuiltin(impl, id, impl.parent, new InternalProcedure<Integer>() {
-
-                       @Override
-                       public void execute(ReadGraphImpl graph, Integer result) {
-                               try {
-                                       procedure.execute(graph, querySupport.getResource(result)); 
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-//                             impl.state.barrier.dec();
-                       }   
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       procedure.exception(graph, t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-//                             impl.state.barrier.dec();
-                       }
-
-               });
+               forResource(impl, id, impl.parent, ip);
 
        }
 
        @Override
-       final public void forHasStatement(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Boolean> procedure) {
+       final public void forBuiltin(final ReadGraphImpl impl, final String id, final AsyncProcedure<Resource> procedure) {
 
-               assert(subject != null);
+               assert(id != null);
                assert(procedure != null);
 
-               final ListenerBase listener = getListenerBase(procedure);
-
 //             impl.state.barrier.inc();
 
-               DirectPredicates.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, new IntProcedure() {
-
-                       boolean found = false;
-
-                       @Override
-                       public void execute(ReadGraphImpl graph, int object) {
-                               found = true;
-                       }
+               try {
+                       forBuiltin(impl, id, impl.parent, new InternalProcedure<Integer>() {
 
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               try {
-                                       procedure.execute(graph, found);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
+                               @Override
+                               public void execute(ReadGraphImpl graph, Integer result) {
+                                       try {
+                                               procedure.execute(graph, querySupport.getResource(result)); 
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
+                               }   
 
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       procedure.exception(graph, t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                       try {
+                                               procedure.exception(graph, t);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
+                               }
 
-               });
+                       });
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
+
+       }
+
+       @Override
+       final public void forHasStatement(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Boolean> procedure) {
+
+               assert(subject != null);
+               assert(procedure != null);
+
+               final ListenerBase listener = getListenerBase(procedure);
 
+               try {
+                       IntSet result = QueryCache.resultDirectPredicates(impl, querySupport.getId(subject), impl.parent, listener);
+                       procedure.execute(impl, !result.isEmpty());
+               } catch (DatabaseException e) {
+                       procedure.exception(impl, e);
+               }
+                       
        }
 
        @Override
@@ -5094,30 +4118,34 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
 //             impl.state.barrier.inc();
 
-               ValueQuery.queryEach(impl, querySupport.getId(subject), impl.parent, listener, new InternalProcedure<byte[]>() {
+               try {
+                       QueryCache.runnerValueQuery(impl, querySupport.getId(subject), impl.parent, listener, new InternalProcedure<byte[]>() {
 
-                       @Override
-                       public void execute(ReadGraphImpl graph, byte[] object) {
-                               boolean result = object != null;
-                               try {
-                                       procedure.execute(graph, result);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
+                               @Override
+                               public void execute(ReadGraphImpl graph, byte[] object) {
+                                       boolean result = object != null;
+                                       try {
+                                               procedure.execute(graph, result);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       procedure.exception(graph, t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
                                }
+
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                       try {
+                                               procedure.exception(graph, t);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
+                               }
 
-               });
+                       });
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
+               }
 
        }
 
@@ -5129,149 +4157,155 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
                final ListenerBase listener = getListenerBase(procedure);
 
-//             impl.state.barrier.inc();
-
-               OrderedSet.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, new IntProcedure() {
+               try {
+                       
+                       QueryCache.runnerOrderedSet(impl, querySupport.getId(subject), impl.parent, listener, new IntProcedure() {
 
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               try {
-                                       procedure.exception(graph, t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
+                               @Override
+                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                       try {
+                                               procedure.exception(graph, t);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
 //                             impl.state.barrier.dec();
-                       }
-
-                       @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-                               try {
-                                       procedure.execute(graph, querySupport.getResource(i));
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
                                }
-                       }
 
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               try {
-                                       procedure.finished(graph);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
+                               @Override
+                               public void execute(ReadGraphImpl graph, int i) {
+                                       try {
+                                               procedure.execute(graph, querySupport.getResource(i));
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
                                }
-//                             impl.state.barrier.dec();
-                       }
-
-               });
-
-       }
-
-       @Override
-       final public <T> void query(final ReadGraphImpl impl, final AsyncRead<T> request, final CacheEntry parent, final AsyncProcedure<T> procedure, ListenerBase listener) {
-
-               assert(request != null);
-               assert(procedure != null);
 
-//             if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(request, "#" + request.toString() + ".1999");
-//             else impl.state.barrier.inc(null, null);
-
-               runAsyncRead(impl, request, parent, listener, procedure);
-
-       }
-
-       @Override
-       final public <T> T tryQuery(final ReadGraphImpl graph, final Read<T> request) throws DatabaseException {
-
-               assert(graph != null);
-               assert(request != null);
+                               @Override
+                               public void finished(ReadGraphImpl graph) {
+                                       try {
+                                               procedure.finished(graph);
+                                       } catch (Throwable t2) {
+                                               Logger.defaultLogError(t2);
+                                       }
+//                             impl.state.barrier.dec();
+                               }
 
-               final ReadEntry entry = readMap.get(request);
-               if(entry != null && entry.isReady()) {
-                   return (T)entry.get(graph, this, null);
-               } else {
-                       return request.perform(graph);
+                       });
+               } catch (DatabaseException e) {
+                       Logger.defaultLogError(e);
                }
 
        }
 
-    final public <T> T tryQuery(final ReadGraphImpl graph, final ExternalRead<T> request) throws DatabaseException {
-
-        assert(graph != null);
-        assert(request != null);
-
-        final ExternalReadEntry<T> entry = externalReadMap.get(request);
-        if(entry != null && entry.isReady()) {
-            if(entry.isExcepted()) {
-                Throwable t = (Throwable)entry.getResult();
-                if(t instanceof DatabaseException) throw (DatabaseException)t;
-                else throw new DatabaseException(t);
-            } else {
-                return (T)entry.getResult();
-            }            
-        } else {
-
-            final DataContainer<T> result = new DataContainer<T>();
-            final DataContainer<Throwable> exception = new DataContainer<Throwable>();
-            
-            request.register(graph, new Listener<T>() {
-                
-                @Override
-                public void exception(Throwable t) {
-                    exception.set(t);
-                }
-
-                @Override
-                public void execute(T t) {
-                    result.set(t);
-                }
-
-                @Override
-                public boolean isDisposed() {
-                    return true;
-                }
-            
-            });
-            
-            Throwable t = exception.get();
-            if(t != null) {
-                if(t instanceof DatabaseException) throw (DatabaseException)t;
-                else throw new DatabaseException(t);
-            }
-            
-            return result.get();
+//     @Override
+//     final public <T> void query(final ReadGraphImpl impl, final AsyncRead<T> request, final CacheEntry parent, final AsyncProcedure<T> procedure, ListenerBase listener) throws DatabaseException {
+//
+//             assert(request != null);
+//             assert(procedure != null);
+//
+//             QueryCache.runnerAsyncReadEntry(impl, request, parent, listener, procedure);
+//
+//     }
 
-        }
+//     @Override
+//     final public <T> T tryQuery(final ReadGraphImpl graph, final Read<T> request) throws DatabaseException {
+//
+//             assert(graph != null);
+//             assert(request != null);
+//
+//             final ReadEntry entry = (ReadEntry)cache.getCached(request);
+//             if(entry != null && entry.isReady()) {
+//                 return (T)entry.get(graph, this, null);
+//             } else {
+//                     return request.perform(graph);
+//             }
+//
+//     }
 
-    }
+//    final public <T> T tryQuery(final ReadGraphImpl graph, final ExternalRead<T> request) throws DatabaseException {
+//
+//        assert(graph != null);
+//        assert(request != null);
+//
+//        final ExternalReadEntry<T> entry = cache.externalReadMap.get(request);
+//        if(entry != null && entry.isReady()) {
+//            if(entry.isExcepted()) {
+//                Throwable t = (Throwable)entry.getResult();
+//                if(t instanceof DatabaseException) throw (DatabaseException)t;
+//                else throw new DatabaseException(t);
+//            } else {
+//                return (T)entry.getResult();
+//            }            
+//        } else {
+//
+//            final DataContainer<T> result = new DataContainer<T>();
+//            final DataContainer<Throwable> exception = new DataContainer<Throwable>();
+//            
+//            request.register(graph, new Listener<T>() {
+//                
+//                @Override
+//                public void exception(Throwable t) {
+//                    exception.set(t);
+//                }
+//
+//                @Override
+//                public void execute(T t) {
+//                    result.set(t);
+//                }
+//
+//                @Override
+//                public boolean isDisposed() {
+//                    return true;
+//                }
+//            
+//            });
+//            
+//            Throwable t = exception.get();
+//            if(t != null) {
+//                if(t instanceof DatabaseException) throw (DatabaseException)t;
+//                else throw new DatabaseException(t);
+//            }
+//            
+//            return result.get();
+//
+//        }
+//
+//    }
        
-       @Override
-       final public <T> void tryQuery(final ReadGraphImpl graph, final AsyncRead<T> request, AsyncProcedure<T> procedure) {
-
-               assert(graph != null);
-               assert(request != null);
-
-               final AsyncReadEntry entry = asyncReadMap.get(request);
-               if(entry != null && entry.isReady()) {
-                       if(entry.isExcepted()) {
-                               procedure.exception(graph, (Throwable)entry.getResult());
-                       } else {
-                               procedure.execute(graph, (T)entry.getResult());
-                       }
-               } else {
-                       request.perform(graph, procedure);
-               }
-
-       }
+//     @Override
+//     final public <T> void tryQuery(final ReadGraphImpl graph, final AsyncRead<T> request, AsyncProcedure<T> procedure) {
+//
+//             assert(graph != null);
+//             assert(request != null);
+//
+//             final AsyncReadEntry entry = cache.asyncReadMap.get(request);
+//             if(entry != null && entry.isReady()) {
+//                     if(entry.isExcepted()) {
+//                             procedure.exception(graph, (Throwable)entry.getResult());
+//                     } else {
+//                             procedure.execute(graph, (T)entry.getResult());
+//                     }
+//             } else {
+//                     request.perform(graph, procedure);
+//             }
+//
+//     }
 
        @Override
-       final public <T> void query(final ReadGraphImpl impl, final MultiRead<T> request, final CacheEntry parent, final AsyncMultiProcedure<T> procedure, ListenerBase listener) {
+       final public <T> void query(final ReadGraphImpl impl, final MultiRead<T> request, final CacheEntry parent, final SyncMultiProcedure<T> procedure, ListenerBase listener) {
 
                assert(request != null);
                assert(procedure != null);
 
-//             impl.state.barrier.inc(null, null);
+               try {
 
-               queryMultiRead(impl, request, parent, listener, procedure);
+                       queryMultiRead(impl, request, parent, listener, procedure);
+                       
+               } catch (DatabaseException e) {
+                       
+                       throw new IllegalStateException(e);
+                       
+               }
 
        }
 
@@ -5329,40 +4363,48 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
 
        }
 
-       @Override
-       final public <T> void query(final ReadGraphImpl impl, final ExternalRead<T> request, final CacheEntry parent, final Procedure<T> procedure, ListenerBase listener) {
-
-               assert(request != null);
-               assert(procedure != null);
-
-               queryPrimitiveRead(impl, request, parent, listener, new Procedure<T>() {
-
-                       @Override
-                       public void execute(T result) {
-                               try {
-                                       procedure.execute(result);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-                       }
-
-                       @Override
-                       public String toString() {
-                               return procedure.toString();
-                       }
-
-                       @Override
-                       public void exception(Throwable t) {
-                               try {
-                                       procedure.exception(t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
-                               }
-                       }
-
-               });
-
-       }
+//     @Override
+//     final public <T> void query(final ReadGraphImpl impl, final ExternalRead<T> request, final CacheEntry parent, final Procedure<T> procedure, ListenerBase listener) throws DatabaseException {
+//
+//             assert(request != null);
+//             assert(procedure != null);
+//
+//             try {
+//             
+//                     queryPrimitiveRead(impl, request, parent, listener, new AsyncProcedure<T>() {
+//     
+//                             @Override
+//                             public String toString() {
+//                                     return procedure.toString();
+//                             }
+//     
+//                             @Override
+//                             public void execute(AsyncReadGraph graph, T result) {
+//                                     try {
+//                                             procedure.execute(result);
+//                                     } catch (Throwable t2) {
+//                                             Logger.defaultLogError(t2);
+//                                     }
+//                             }
+//
+//                             @Override
+//                             public void exception(AsyncReadGraph graph, Throwable throwable) {
+//                                     try {
+//                                             procedure.exception(throwable);
+//                                     } catch (Throwable t2) {
+//                                             Logger.defaultLogError(t2);
+//                                     }
+//                             }
+//     
+//                     });
+//                     
+//             } catch (DatabaseException e) {
+//                     
+//                     throw new IllegalStateException(e);
+//                     
+//             }
+//
+//     }
 
        @Override
        public VirtualGraph getProvider(Resource subject, Resource predicate, Resource object) {
@@ -5408,5 +4450,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
                }
                return L0;
        }
+
+    public static ThreadLocal<Integer> thread = new ThreadLocal<Integer>() {
+        protected Integer initialValue() {
+            return -1;
+        }
+    };
        
 }
index 6ba47cac780d45bd8a5595e3a7a11f2d5a7eaaa5..3071c30c042d8730799004eec9d10b7168b70fd4 100644 (file)
@@ -16,6 +16,7 @@ import java.io.InputStream;
 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.graph.ReadGraphImpl;
 
@@ -35,11 +36,11 @@ public interface QuerySupport extends ResourceTranslator {
        int getSingleInstance(int subject);
        int getSingleSuperrelation(int subject);
        int getFunctionalObject(int subject, int predicate);
-       boolean getObjects(ReadGraphImpl graph, int subject, int predicate, IntProcedure procedure);
+       boolean getObjects(ReadGraphImpl graph, int subject, int predicate, IntProcedure procedure) throws DatabaseException;
     
        org.simantics.db.DirectStatements getStatements(ReadGraphImpl graph, final int subject, QueryProcessor processor, boolean ignoreVirtual);
     
-    void getPredicates(ReadGraphImpl graph, int subject, IntProcedure procedure);
+    void getPredicates(ReadGraphImpl graph, int subject, IntProcedure procedure) throws DatabaseException;
     byte[] getValue(ReadGraphImpl graph, int resource);
     InputStream getValueStream(ReadGraphImpl graph, int resource);
     
index a5e79244e10e16e532ad843e56a75cb64f2b763c..ab10efa0baab252a1ff5ef8b8485c313b2b32db1 100644 (file)
@@ -3,17 +3,17 @@ package org.simantics.db.impl.query;
 import java.util.ArrayList;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.ReentrantLock;
 
 import org.simantics.db.Session;
 import org.simantics.db.common.SessionThread;
-import org.simantics.db.common.utils.Logger;
 import org.simantics.db.impl.query.QueryProcessor.SessionTask;
 import org.simantics.db.impl.query.QueryProcessor.ThreadState;
+import org.slf4j.LoggerFactory;
 
 class QueryThread extends Thread implements SessionThread {
 
+       private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(QueryThread.class);
+
        boolean disposed = false;
        private Semaphore exited = new Semaphore(0);
 
@@ -21,42 +21,44 @@ class QueryThread extends Thread implements SessionThread {
 
        private Session session;
        private QuerySupport querySupport;
+       private final QueryProcessor processor;
 
        final private ArrayList<SessionTask> tasks = new ArrayList<SessionTask>();
-       final private ArrayList<SessionTask> own;
-       final private ArrayList<SessionTask> ownSync;
-       final private ArrayList<SessionTask> queue;
-       final private ReentrantLock lock;
-       final private Condition condition;
+//     final private ArrayList<SessionTask> own;
+//     final private ArrayList<SessionTask> ownSync;
+//     final private ArrayList<SessionTask> queue;
+//     final private ReentrantLock lock;
+//     final private Condition condition;
        final private Object querySupportLock;
        final private int THREADS;
        final private AtomicInteger sleepers;
        final private ThreadState[] threadStates;
-       final private ArrayList<SessionTask>[] delayQueues;
-       final private QueryThread[] executors;
-       final private ReentrantLock[] threadLocks;
-       final private ArrayList<SessionTask>[] queues;
-       final private ArrayList<SessionTask>[] ownSyncTasks;
+//     final private ArrayList<SessionTask>[] delayQueues;
+//     final private QueryThread[] executors;
+//     final private ReentrantLock[] threadLocks;
+//     final private ArrayList<SessionTask>[] queues;
+//     final private ArrayList<SessionTask>[] ownSyncTasks;
 
        public QueryThread(Session session, QueryProcessor processor, int index, String name) {
                super(QueryProcessor.QueryThreadGroup, null, name);
                this.session = session;
+               this.processor = processor;
                this.index = index;
-               own = processor.ownTasks[index];
-               ownSync = processor.ownSyncTasks[index];
-               queue = processor.queues[index];
-               lock = processor.threadLocks[index];
-               condition = processor.threadConditions[index];
+//             own = processor.ownTasks[index];
+//             ownSync = processor.ownSyncTasks[index];
+//             queue = processor.queues[index];
+//             lock = processor.threadLocks[index];
+//             condition = processor.threadConditions[index];
                querySupportLock = processor.querySupportLock;
                THREADS = processor.THREADS;
                sleepers = processor.sleepers;
                querySupport = processor.querySupport;
                threadStates = processor.threadStates;
-               delayQueues = processor.delayQueues;
-               executors = processor.executors;
-               threadLocks = processor.threadLocks;
-               queues = processor.queues;
-               ownSyncTasks = processor.ownSyncTasks;
+//             delayQueues = processor.delayQueues;
+//             executors = processor.executors;
+//             threadLocks = processor.threadLocks;
+//             queues = processor.queues;
+//             ownSyncTasks = processor.ownSyncTasks;
        }
 
        synchronized void dispose() {
@@ -64,20 +66,19 @@ class QueryThread extends Thread implements SessionThread {
 //             System.err.println("qt dispose");
 
                disposed = true;
-               lock.lock();
-               condition.signalAll();
-               lock.unlock();
+//             lock.lock();
+//             condition.signalAll();
+//             lock.unlock();
                
                try {
                        exited.acquire();
                } catch (InterruptedException e) {
-                       Logger.defaultLogError(e);
+                       LOGGER.error("dispose was interrupted", e);
                }
 
                session = null;
                querySupport = null;
 
-
 //             System.err.println("qt disposed");
 
        }
@@ -94,43 +95,31 @@ class QueryThread extends Thread implements SessionThread {
 
        }
 
+       private boolean pumpTask() {
+               if(!processor.freeScheduling.isEmpty()) {
+                       tasks.add(processor.freeScheduling.removeFirst());
+                       return true;
+               }
+               return false;
+       }
+       
        ArrayList<SessionTask> newTasks(boolean doWait, ArrayList<SessionTask> tasks) {
 
                try {
 
                        while(true) {
 
-                               // Perform own tasks first
-                               if(tasks.addAll(own)) {
-                                       own.clear();
-                               } else if (doWait && !ownSync.isEmpty()) {
-                                       tasks.add(ownSync.remove(ownSync.size()-1));
-                               }
-
-                               // Try some queued tasks
-                               lock.lock();
-                               if(tasks.addAll(queue)) {
-                                       queue.clear();
-                                       lock.unlock();
-                                       return tasks;
-                               } else {
-                                       lock.unlock();
-                               }
-
                                // Return tasks if some were found
                                if(!tasks.isEmpty()) return tasks;
+                               
                                if(!doWait) return null;
 
                                synchronized (querySupportLock) {
 
-                                       lock.lock();
-                                       
-                                       // Just maybe someone inserted tasks and notified just before synchronized block
-                                       if(tasks.addAll(queue)) {
-                                               queue.clear();
-                                               lock.unlock();
+                                       if(pumpTask())
                                                return tasks;
-                                       }
+
+//                                     lock.lock();
 
                                        // We are the last one awake
                                        if(sleepers.incrementAndGet() == THREADS) {
@@ -141,12 +130,8 @@ class QueryThread extends Thread implements SessionThread {
                                                if(querySupport == null) System.err.println("null qs");
                                                querySupport.ceased(index);
 
-                                               if(tasks.addAll(own)) {
-                                                       own.clear();
-                                               }
-                                               //                                      System.err.println("tasks after ceased: " + tasks.size());
-                                               if(!tasks.isEmpty()) {
-                                                       lock.unlock();
+                                               if(pumpTask()) {
+//                                                     lock.unlock();
                                                        return tasks;
                                                }
 
@@ -163,30 +148,44 @@ class QueryThread extends Thread implements SessionThread {
                                // We are done
                                if(isDisposed()) {
                                        threadStates[index] = ThreadState.DISPOSED;
-                                       lock.unlock();
+//                                     lock.unlock();
                                        return null;
                                }
 
+                               
                                threadStates[index] = ThreadState.SLEEP;
-                               condition.await();
+                               
+                               synchronized (querySupportLock) {
+                                       querySupportLock.wait(100);
+                                       
+                               }
+                               
+//                             boolean woken = condition.await(10, TimeUnit.MILLISECONDS);
+//                             if(!woken) {
+//                                     synchronized (querySupportLock) {
+//                                             if(!processor.freeScheduling.isEmpty())
+//                                                     System.err.println("some tasks are available!");
+//                                     }
+//                             }
+
+                               sleepers.decrementAndGet();
 
                                // We are done
                                if(isDisposed()) {
                                        threadStates[index] = ThreadState.DISPOSED;
-                                       lock.unlock();
+                                       //lock.unlock();
                                        return null;
                                }
 
                                threadStates[index] = ThreadState.RUN;
 
-                               lock.unlock();
+                               //lock.unlock();
 
                        }
 
                } catch (InterruptedException e) {
 
-                       e.printStackTrace();
-
+                       LOGGER.error("Query handling (newTasks) was interrupted", e);
                        throw new RuntimeException("Querying was interrupted.", e);
 
                }
@@ -197,17 +196,17 @@ class QueryThread extends Thread implements SessionThread {
 
                boolean didExecute = false;
 
-               for(int performer=0;performer<THREADS;performer++) {
-                       if(!delayQueues[index * THREADS + performer].isEmpty()) {
-                               synchronized(executors[performer]) {
-                                       threadLocks[performer].lock();
-                                       queues[performer].addAll(delayQueues[index * THREADS + performer]);
-                                       delayQueues[index * THREADS + performer].clear();
-                                       executors[performer].notify();
-                                       threadLocks[performer].unlock();
-                               }
-                       }
-               }
+//             for(int performer=0;performer<THREADS;performer++) {
+//                     if(!delayQueues[index * THREADS + performer].isEmpty()) {
+//                             synchronized(executors[performer]) {
+//                                     threadLocks[performer].lock();
+//                                     queues[performer].addAll(delayQueues[index * THREADS + performer]);
+//                                     delayQueues[index * THREADS + performer].clear();
+//                                     executors[performer].notify();
+//                                     threadLocks[performer].unlock();
+//                             }
+//                     }
+//             }
 
                if(tasks.isEmpty()) {
                        ArrayList<SessionTask> finished = newTasks(false, tasks);
@@ -218,12 +217,13 @@ class QueryThread extends Thread implements SessionThread {
 
                        SessionTask task = tasks.remove(tasks.size() - 1);
 
-                       if(task.syncCaller == index) {
-                               ownSyncTasks[index].add(task);
-                       } else {
+//                     if(task.syncCaller == index) {
+//                             ownSyncTasks[index].add(task);
+//                     } else {
                                task.run(index);
+//                             System.err.println("QT(s) " + index + " runs " + task);
                                didExecute = true;
-                       }
+//                     }
 
                }
 
@@ -234,6 +234,8 @@ class QueryThread extends Thread implements SessionThread {
        @Override
        public void run() {
 
+               processor.thread.set(index);
+               
                QuerySupport support = this.querySupport;
 
                try {
@@ -248,27 +250,28 @@ class QueryThread extends Thread implements SessionThread {
                                while(!tasks.isEmpty()) {
 
                                        SessionTask task = tasks.remove(tasks.size()-1);
+//                                     System.err.println("QT " + index + " runs " + task);
                                        task.run(index);
 
                                }
 
-                               for(int performer=0;performer<THREADS;performer++) {
-                                       if(!delayQueues[index * THREADS + performer].isEmpty()) {
-                                               synchronized(executors[performer]) {
-                                                       threadLocks[performer].lock();
-                                                       queues[performer].addAll(delayQueues[index * THREADS + performer]);
-                                                       delayQueues[index * THREADS + performer].clear();
-                                                       executors[performer].notify();
-                                                       threadLocks[performer].unlock();
-                                               }
-                                       }
-                               }
+//                             for(int performer=0;performer<THREADS;performer++) {
+//                                     if(!delayQueues[index * THREADS + performer].isEmpty()) {
+//                                             synchronized(executors[performer]) {
+//                                                     threadLocks[performer].lock();
+//                                                     queues[performer].addAll(delayQueues[index * THREADS + performer]);
+//                                                     delayQueues[index * THREADS + performer].clear();
+//                                                     executors[performer].notify();
+//                                                     threadLocks[performer].unlock();
+//                                             }
+//                                     }
+//                             }
 
                        }
 
                } catch (Throwable t) {
 
-                       Logger.defaultLogError("FATAL BUG: QueryThread task processing caused unexpected exception.", t);
+                       LOGGER.error("FATAL BUG: QueryThread task processing caused unexpected exception.", t);
                        support.exit(t);
 
                } finally {
index e4ff1ea874bb2c3b9f8e288d413eaedc49f51c51..c95242defc77a45ae859f49042a2fc1e13df4f20 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -14,153 +14,171 @@ package org.simantics.db.impl.query;
 import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.impl.graph.WriteGraphImpl;
 import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.request.Read;
 import org.simantics.db.request.ReadExt;
 import org.simantics.db.request.RequestFlags;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-final public class ReadEntry<T> extends CacheEntryBase {
+public final class ReadEntry<T> extends CacheEntryBase<AsyncProcedure<T>> implements AsyncProcedure<T> {
 
-       protected Read<T> request;
+    private static final Logger LOGGER = LoggerFactory.getLogger(ReadEntry.class);
 
-       public ReadEntry(Read<T> request) {
-       this.request = request;
+    protected Read<T> request;
+
+    public ReadEntry(Read<T> request) {
+        this.request = request;
     }
-    
+
     @Override
     int makeHash() {
-       return request.hashCode();
+        return request.hashCode();
     }
-       
+
     @Override
     public Object getOriginalRequest() {
         return request;
     }
-    
+
     @Override
     public void discard() {
-       super.discard();
-       setResult(null);
-    }
-       
-    final public void addOrSet(AsyncReadGraph graph, Object item) {
-
-       assert(assertPending());
-       
-//        ArrayList<Pair<AsyncProcedure<T>, AsyncBarrier>> p = null;
-
-       synchronized(this) {
-           
-            setResult(item);
-               setReady();
-//             p = procs;
-//             procs = null;
-               
-       }
-
-//        if(p != null)
-//             for(Pair<AsyncProcedure<T>, AsyncBarrier> proc : p) {
-//                     proc.first.execute(graph, (T)item);
-//                     proc.second.dec();
-//             }
-        
+        super.discard();
+        setResult(null);
     }
 
     @Override
     final public Query getQuery() {
-        
+
         return new Query() {
 
-                       @Override
-                       public void recompute(ReadGraphImpl graph_, Object provider, CacheEntry entry) {
-                               
-                               QueryProcessor qp = (QueryProcessor)provider;
-                               
-                       WriteGraphImpl write = qp.getCore().getSession().getService(WriteGraphImpl.class);
-                               
-                       ReadGraphImpl graph = write.newSync(entry);
+            @Override
+            public void recompute(ReadGraphImpl graph) {
+
+                try {
 
-                               try {
+                    T result = request.perform(graph);
+                    setResult(result);
+                    setReady();
 
-                                       entry.setPending();
-                                   T result = request.perform(graph);
-                                   addOrSet(graph, result);
+                } catch (Throwable t) {
 
-                               } catch (Throwable t) {
+                    except(t);
+
+                }
+
+            }
+
+            @Override
+            public void removeEntry(QueryProcessor processor) {
+                processor.cache.remove(ReadEntry.this);
+            }
 
-                                       except(t);
-                    
+            @Override
+            public int type() {
+                if (request instanceof ReadExt) {
+                    return ((ReadExt) request).getType();
+                } else {
+                    return RequestFlags.INVALIDATE;
                 }
-                               
-                       }
-
-                       @Override
-                       public void removeEntry(QueryProcessor processor) {
-                               processor.readMap.remove(request);
-                       }
-
-                       @Override
-                       public int type() {
-                               if(request instanceof ReadExt) {
-                                       return ((ReadExt)request).getType();
-                               } else {
-                                       return RequestFlags.INVALIDATE;
-                               }
-                       }
-                       
-                       @Override
-                       public String toString() {
-                               if(request == null) return "DISCARDED";
-                               else return request.toString() + statusOrException;
-                       }
-               
+            }
+
+            @Override
+            public String toString() {
+                if (request == null)
+                    return "DISCARDED";
+                else
+                    return request.toString() + statusOrException;
+            }
+
         };
-        
+
     }
-    
-       public void performFromCache(ReadGraphImpl graph, Object provider,      Object procedure) {
-           
-        AsyncProcedure<T> proc = (AsyncProcedure<T>)procedure;
 
-           if(isExcepted()) {
+    public static <T> void computeForEach(ReadGraphImpl graph, Read<T> request, ReadEntry<T> entry,
+            AsyncProcedure<T> procedure_) throws DatabaseException {
 
-            try {
-                proc.exception(graph, (Throwable)getResult());
-            } catch (Throwable t) {
-                t.printStackTrace();
-            }
-               
-           } else {
-               
-            try {
-                proc.execute(graph, (T)getResult());
-            } catch (Throwable t) {
-                t.printStackTrace();
+        AsyncProcedure<T> procedure = entry != null ? entry : procedure_;
+
+        ReadGraphImpl queryGraph = entry != null ? graph.withParent(entry) : graph;
+
+        try {
+
+            T result = request.perform(queryGraph);
+            procedure.execute(graph, result);
+
+        } catch (DatabaseException e) {
+
+            procedure.exception(graph, e);
+
+        } catch (Throwable t) {
+
+            DatabaseException dbe = new DatabaseException(t);
+            procedure.exception(graph, dbe);
+
+        }
+
+        if (entry != null)
+            entry.performFromCache(queryGraph, procedure_);
+
+    }
+
+    public Object performFromCache(ReadGraphImpl graph, AsyncProcedure<T> procedure) {
+
+        AsyncProcedure<T> proc = (AsyncProcedure<T>) procedure;
+
+        if (proc != null) {
+            if (isExcepted()) {
+                try {
+                    proc.exception(graph, (Throwable) getResult());
+                } catch (Throwable t) {
+                    LOGGER.error("performFromCache proc.exception failed", t);
+                }
+            } else {
+                try {
+                    proc.execute(graph, (T) getResult());
+                } catch (Throwable t) {
+                    LOGGER.error("performFromCache proc.execute failed", t);
+                }
             }
+        }
+
+        return (T) getResult();
 
-           }
-               
-       }
-       
-       @Override
-       public String toString() {
-               if(request == null) return "DISCARDED";
-               else return request.toString() + " - " + statusOrException;
-       }
-       
-       public Object get(ReadGraphImpl graph, QueryProcessor processor, Object procedure) throws DatabaseException {
-               if(procedure != null) performFromCache(graph, processor, procedure);
-               checkAndThrow();
-               return getResult();
-       }
-       
-       @Override
-       boolean isImmutable(ReadGraphImpl graph) throws DatabaseException {
-               if(request instanceof ReadExt) {
-                       return ((ReadExt)request).isImmutable(graph);
-               }
-               return false;
-       }
+    }
+
+    @Override
+    public String toString() {
+        if (request == null)
+            return "DISCARDED";
+        else
+            return request.toString() + " - " + statusOrException;
+    }
+
+    public Object get(ReadGraphImpl graph, AsyncProcedure<T> procedure) throws DatabaseException {
+        if (procedure != null)
+            performFromCache(graph, procedure);
+        checkAndThrow();
+        return getResult();
+    }
+
+    @Override
+    boolean isImmutable(ReadGraphImpl graph) throws DatabaseException {
+        if (request instanceof ReadExt) {
+            return ((ReadExt) request).isImmutable(graph);
+        }
+        return false;
+    }
+
+    @Override
+    public void execute(AsyncReadGraph graph, T result) {
+        setResult(result);
+        setReady();
+    }
+
+    @Override
+    public void exception(AsyncReadGraph graph, Throwable throwable) {
+        except(throwable);
+    }
 
 }
index d32da5be54bfcf324f4555ff1740cb5cd258a3c6..0b60fdd0c596a144fd9ccf5f7211786fdaf5c839 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 import org.simantics.db.RelationInfo;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.procedure.InternalProcedure;
-import org.simantics.db.procedure.ListenerBase;
 import org.simantics.db.request.RequestFlags;
 
-final public class RelationInfoQuery extends UnaryQuery<InternalProcedure<RelationInfo>> {
-    
-//     public ArrayList<InternalProcedure<RelationInfo>> procs = null;
-
-       private RelationInfoQuery(final int resource) {
-        super(resource);
-    }
-    
-    final static RelationInfo runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<RelationInfo> procedure) {
+public final class RelationInfoQuery extends UnaryQueryP<RelationInfo> {
 
-       RelationInfoQuery entry = (RelationInfoQuery)provider.relationInfoMap.get(r);
-        if(entry == null) {
-               
-               entry = new RelationInfoQuery(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-            provider.performForEach(graph, entry, parent, listener, procedure);
-            
-            return entry.getResult();
-            
-        } else {
-               
-            if(!entry.isReady()) {
-               synchronized(entry) {
-                    if(!entry.isReady()) {
-                        throw new IllegalStateException();
-//                     if(entry.procs == null) entry.procs = new ArrayList<InternalProcedure<RelationInfo>>();
-//                                     entry.procs.add(procedure);
-//                        provider.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                                     return entry.getResult();
-                    }
-               }
-            }
-            provider.performForEach(graph, entry, parent, listener, procedure);
-            
-            return entry.getResult();
-            
-        }
+       RelationInfoQuery(int resource) {
+               super(resource);
+       }
 
-    }
-    
-    final public static RelationInfo queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<RelationInfo> procedure) {
-        
-       RelationInfoQuery entry = (RelationInfoQuery)provider.relationInfoMap.get(r);
-       if(entry != null && entry.isReady()) {
-               entry.performFromCache(graph, provider, procedure);
-               return entry.getResult();
-       }
+       @Override
+       public final void removeEntry(QueryProcessor provider) {
+               provider.cache.remove(this);
+       }
 
-        return runner(graph, r, provider, parent, listener, procedure);
-         
-    }
-     
-    final public static RelationInfoQuery probe(ReadGraphImpl graph, int resource) {
-        
-        final int thread = graph.thread(resource);
-       RelationInfoQuery entry = (RelationInfoQuery)graph.processor.relationInfoMap.get(resource);
-       if(entry != null && entry.isReady()) {
-               return entry;
-       } else {
-               return null;
-       }
-         
-    }
+       private static void computeAssertions(ReadGraphImpl graph, int r, final boolean isFinal, final boolean isFunctional, RelationInfoQuery parent, final InternalProcedure<RelationInfo> procedure) throws DatabaseException {
 
-    @Override
-       public UnaryQuery<InternalProcedure<RelationInfo>> getEntry(QueryProcessor provider) {
-        return provider.relationInfoMap.get(id);
-       }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-        provider.relationInfoMap.put(id, this);
-       }
+               QueryProcessor processor = graph.processor;
 
-       @Override
-       final public void removeEntry(QueryProcessor provider) {
-               provider.relationInfoMap.remove(id);
-       }
+               final int isUsedInAssertion = processor.getHasPredicateInverse();
+               assert(isUsedInAssertion != 0);
 
-       private void computeAssertions(ReadGraphImpl graph, final boolean isFinal, final boolean isFunctional, final QueryProcessor queryProvider, final InternalProcedure<RelationInfo> proc) {
+               QueryCache.runnerDirectObjects(graph, r, isUsedInAssertion, parent, null, new IntProcedure() {
 
-           final int isUsedInAssertion = queryProvider.getHasPredicateInverse();
-        assert(isUsedInAssertion != 0);
-               
-        DirectObjects.queryEach(graph, id, isUsedInAssertion, queryProvider, this, null, new IntProcedure() {
+                       boolean done = false;
 
-                       AtomicBoolean done = new AtomicBoolean(false);
-                       
                        @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-                               if(done.compareAndSet(false, true)) {
-//                                     System.err.println("Assertions for relation " + id);
-                                       RelationInfo result = new RelationInfo(id, isFunctional, isFinal, true);
-                                       addOrSet(graph, result, queryProvider);
-                                       proc.execute(graph, result);
-                               }
+                       public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                               if(done) return;
+                               done = true;
+                               RelationInfo result = new RelationInfo(r, isFunctional, isFinal, true);
+                               procedure.execute(graph, result);
                        }
 
                        @Override
-                       public void finished(ReadGraphImpl graph) {
-                               if(done.compareAndSet(false, true)) {
-//                                     System.err.println("No assertions for relation " + id);
-                                       RelationInfo result = new RelationInfo(id, isFunctional, isFinal, false);
-                                       addOrSet(graph, result, queryProvider);
-                                       proc.execute(graph, result);
-                               }
+                       public void finished(ReadGraphImpl graph) throws DatabaseException {
+                               if(done) return;
+                               done = true;
+                               RelationInfo result = new RelationInfo(r, isFunctional, isFinal, false);
+                               procedure.execute(graph, result);
                        }
 
                        @Override
-                       public void exception(ReadGraphImpl graph, Throwable throwable) {
-                               if(done.compareAndSet(false, true)) {
-                                       DatabaseException e = new DatabaseException("Internal error in RelationInfoQuery");
-                                       except(e);
-                                       proc.exception(graph, e);
-                               }
+                       public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+                               if(done) return;
+                               done = true;
+                               DatabaseException e = new DatabaseException("Internal error in RelationInfoQuery");
+                               procedure.exception(graph, e);
                        }
-                       
-               });
-               
-//         Types.queryEach(callerThread, id, queryProvider, this, null, new InternalProcedure<IntSet>() {
-//             
-//          @Override
-//          public void execute(int callerThread, IntSet types) {
-//               computeAssertions(callerThread, isFinal, isFunctional, queryProvider, proc);
-////             
-////             
-//////              System.out.println("RelationInfoQuery: computeTypes execute " + types);
-////
-////              RelationInfo result = new RelationInfo(id, types.contains(queryProvider.getFunctionalRelation()), isFinal);
-////              
-////              addOrSet(callerThread, result, queryProvider);
-////              
-////              proc.execute(callerThread, result);
-////              
-//          }
-//                     
-//                     @Override
-//                     public void exception(int callerThread, Throwable t) {
-//                             proc.exception(callerThread, t);
-//          }
-//
-//      });
 
-       }
-       
-       private void computeTypes(ReadGraphImpl graph, final boolean isFinal, final QueryProcessor queryProvider, final InternalProcedure<RelationInfo> proc) {
-        
-//        System.out.println("RelationInfoQuery: computeTypes " + id);
-
-           Types.queryEach(graph, id, queryProvider, this, null, new InternalProcedure<IntSet>() {
-               
-            @Override
-            public void execute(ReadGraphImpl graph, IntSet types) {
-               computeAssertions(graph, isFinal, types.contains(queryProvider.getFunctionalRelation()), queryProvider, proc);
-//
-////                System.out.println("RelationInfoQuery: computeTypes execute " + types);
-//
-//                RelationInfo result = new RelationInfo(id, types.contains(queryProvider.getFunctionalRelation()), isFinal);
-//                
-//                addOrSet(callerThread, result, queryProvider);
-//                
-//                proc.execute(callerThread, result);
-//                
-            }
-                       
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               proc.exception(graph, t);
-            }
+               });
 
-        });
+       }
 
-       }
-       
-       @Override
-       public Object computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final InternalProcedure<RelationInfo> procedure, boolean store) {
-           
-//        System.out.println("RelationInfoQuery computeForEach begin " + id + " " + getResult() + " " + statusOrException);
+       public static void computeForEach(ReadGraphImpl graph, int r, RelationInfoQuery entry, InternalProcedure<RelationInfo> procedure_) throws DatabaseException {
 
-           final int superRelationOf = provider.getSuperrelationOf();
-        assert(superRelationOf != 0);
-        
-        DirectPredicates.queryEach(graph, id, provider, this, null, new IntProcedure() {
-            
-            boolean found = false;
+               InternalProcedure<RelationInfo> procedure = entry != null ? entry : procedure_;
 
-            @Override
-            public void execute(ReadGraphImpl graph, int i) {
-//                System.out.println("RelationInfoQuery: execute " + i + " super = " + superRelationOf);
-                if(i == superRelationOf) {
-                    computeTypes(graph, false, provider, procedure);
-                    found = true;
-                }
-            }
+               QueryProcessor provider = graph.processor;
 
-            @Override
-            public void finished(ReadGraphImpl graph) {
-//                System.out.println("RelationInfoQuery: finished");
-                if(!found) {
-                    computeTypes(graph, true, provider, procedure);
-                }
-            }
-            
-            @Override
-            public void exception(ReadGraphImpl graph, Throwable t) {
-//                System.out.println("RelationInfoQuery: exception");
-                procedure.exception(graph, t);
-            }
+               final int superRelationOf = provider.getSuperrelationOf();
+               assert(superRelationOf != 0);
 
-        });
-        
-        return getResult();
-        
-    }
-    
-    @Override
-    public String toString() {
-       return "RelationInfoQuery[" + id + "]";
-    }
+               IntSet direct = QueryCache.resultDirectPredicates(graph, r, entry, null);
+               IntSet types = QueryCache.resultTypes(graph, r, entry, null);
 
-    public void addOrSet(ReadGraphImpl graph, final RelationInfo result, final QueryProcessor provider) {
-        
-       assert(isPending());
-       
-//     ArrayList<InternalProcedure<RelationInfo>> p = null;
-       
-       synchronized(this) {
+               computeAssertions(graph, r, !direct.contains(superRelationOf), types.contains(graph.processor.getFunctionalRelation()), entry, procedure);
 
-           setResult(result);
-           setReady();
-        
-//             p = procs;
-//             procs = null;
-               
-       }
-       
-//     if(p != null) {
-//          for(InternalProcedure<RelationInfo> proc : p) 
-//              proc.execute(graph, (RelationInfo)result);
-//     }
-        
-    }            
+               if(entry != null) entry.performFromCache(graph, procedure_);
 
-    @Override
-    public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<RelationInfo> procedure) {
+       }
 
-        assert(isReady());
-        
-       if(handleException(graph, procedure)) return EXCEPTED;
-        
-       RelationInfo result = getResult();
-       
-        procedure.execute(graph, result);
-        
-        return result;
+       @Override
+       public void compute(ReadGraphImpl graph, final InternalProcedure<RelationInfo> procedure) throws DatabaseException {
+               computeForEach(graph, id, this, procedure);
+       }
 
-    }
-    
-    @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-        
-        final Semaphore s = new Semaphore(0);
-        
-        computeForEach(graph, provider, new InternalProcedure<RelationInfo>() {
+       @Override
+       public String toString() {
+               return "RelationInfoQuery[" + id + "]";
+       }
 
-            @Override
-            public void execute(ReadGraphImpl graph, RelationInfo result) {
-                s.release();
-            }
-            
-            @Override
-            public void exception(ReadGraphImpl graph, Throwable t) {
-                throw new Error("Error in recompute.", t);
-            }
+       @Override
+       public void setResult(Object result) {
+               super.setResult(result);
+               setReady();
+       }
 
-        }, true);
-        
-       while(!s.tryAcquire()) {
-               provider.resume(graph);
-       }
-//        try {
-//            s.acquire();
-//        } catch (InterruptedException e) {
-//            throw new Error(e);
-//        }
+       @Override
+       public int type() {
+               return RequestFlags.IMMEDIATE_UPDATE;
+       }
 
-    }
-    
-    @Override
-    public int type() {
-        return RequestFlags.IMMEDIATE_UPDATE;
-    }
-    
 }
index 935b8115962df76e3672d5479521e5dba41378f3..6652f1b6bac9aac657ec22aa8c2f2d329591b8aa 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.simantics.db.RelationInfo;
 import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.procedure.InternalProcedure;
@@ -25,59 +23,13 @@ import org.simantics.db.impl.procedure.TripleIntProcedureAdapter;
 import org.simantics.db.procedure.ListenerBase;
 import org.simantics.db.request.RequestFlags;
 
-final public class Statements extends CollectionBinaryQuery<TripleIntProcedure> {
-       
-//     public ArrayList<TripleIntProcedure> procs = null;
+public final class Statements extends CollectionBinaryQuery<TripleIntProcedure> implements TripleIntProcedure {
        
     public Statements(final int r1, final int r2) {
         super(r1, r2);
     }
-
-    final static Statements entry(final QueryProcessor processor, final int r1, final int r2) {
-        
-        return (Statements)processor.statementsMap.get(id(r1,r2));
-
-    }
-    
-       final static Collection<Statements> entries(final QueryProcessor processor, final int r1) {
-               return processor.statementsMap.values(r1);
-       }
     
-    final static void runner(ReadGraphImpl graph, final int r1, final int r2, CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) {
-        
-       QueryProcessor processor = graph.processor;
-
-        Statements entry = (Statements)processor.statementsMap.get(id(r1,r2));
-        if(entry == null) {
-               
-               entry = new Statements(r1, r2);
-               entry.setPending();
-               entry.clearResult(processor.querySupport);
-               entry.putEntry(processor);
-               
-               processor.performForEach(graph, entry, parent, listener, procedure);
-            
-        } else {
-               
-            if(entry.isPending()) {
-               synchronized(entry) {
-                    if(entry.isPending()) {
-                        throw new IllegalStateException();
-//                        if(entry.procs == null) entry.procs = new ArrayList<TripleIntProcedure>();
-//                     entry.procs.add(procedure);
-//                     processor.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                     return;
-                    }
-               }
-            }
-            
-            processor.performForEach(graph, entry, parent, listener, procedure);
-            
-        }
-
-    }
-    
-    final public static void queryEach(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) {
+    final public static void queryEach(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) throws DatabaseException {
         
        assert(r1 != 0);
        assert(r2 != 0);
@@ -87,23 +39,13 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                return;
         }
         
-        runner(graph, r1, r2, parent, listener, procedure);
+        QueryCache.runnerStatements(graph, r1, r2, parent, listener, procedure);
          
     }
 
-    @Override
-    public BinaryQuery<TripleIntProcedure> getEntry(QueryProcessor provider) {
-        return provider.statementsMap.get(id);
-    }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-           provider.statementsMap.put(id, this);
-       }
-
        @Override
        final public void removeEntry(QueryProcessor provider) {
-        provider.statementsMap.remove(id);
+        provider.cache.remove(this);
        }
        
     final static TripleIntProcedure NOPT = new TripleIntProcedure() {
@@ -123,7 +65,7 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
        
     };
        
-    final static private IntArray getAssertionMap(ReadGraphImpl graph, final int r1, final int r2, final Statements entry) {
+    final static private IntArray getAssertionMap(ReadGraphImpl graph, final int r1, final int r2, final Statements entry) throws DatabaseException {
        
         class AssertionMapProc implements IntProcedure {
                
@@ -153,10 +95,9 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                }
                
             @Override
-            public void execute(ReadGraphImpl graph, int type) {
-                AssertedStatements stms = AssertedStatements.queryEach(graph, type, r2, graph.processor, entry, null, NOPT);
+            public void execute(ReadGraphImpl graph, int type) throws DatabaseException {
                 if(result == null) {
-                       result = stms.getResult();
+                       result = QueryCache.resultAssertedStatements(graph, type, r2, entry, null);
                 } else {
                        if (first) {
                                IntArray ia = result;
@@ -166,7 +107,7 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                                }
                                first = false;
                        }
-                       IntArray ia = stms.getResult();
+                       IntArray ia = QueryCache.resultAssertedStatements(graph, type, r2, entry, null);
                        if(ia.data != null) {
                                for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]);
                        }
@@ -186,18 +127,17 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
         AssertionMapProc amp = new AssertionMapProc();
 
         // This dependency could be cut
-       PrincipalTypes.queryEach(graph, r1, graph.processor, entry, null, amp);
+        QueryCache.runnerPrincipalTypes(graph, r1, entry, null, amp);
        
         return amp.result;
        
     }
        
-    final static private void forSingleAssertion(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final TripleIntProcedure procedure) {
-        
-       IntArray map = getAssertionMap(graph, r1, r2, entry);
+    final static private void forSingleAssertion(ReadGraphImpl graph, final int r1, final int r2, final Statements parent, final TripleIntProcedure procedure) throws DatabaseException {
+       
+       IntArray map = getAssertionMap(graph, r1, r2, parent);
        if(map == null) {
-            if(entry != null) entry.finish(graph, procedure);
-               else procedure.finished(graph);
+               procedure.finished(graph);
             return;
        }
         
@@ -208,33 +148,27 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                int p = map.data[1];
                int o = map.data[2];
                
-            if(entry != null) {
-               entry.addOrSetFunctional(s,p,o);
-               entry.finish(graph, procedure);
-            } else {
                        procedure.execute(graph, s,p,o);
                        procedure.finished(graph);
-               }
 
         } else if(size == 0) {
 
-            if(entry != null) entry.finish(graph, procedure);
-               else procedure.finished(graph);
+               procedure.finished(graph);
                
         } else {
 
                int candidateS = map.data[0];
                int candidateP = map.data[1];
                int candidateO = map.data[2];
-
-                       SuperTypes candidate = SuperTypes.queryEach(graph, candidateS, graph.processor, entry, null, NOP);
-                       if(candidate.isExcepted()) {
-                               if(entry != null) entry.except((Throwable)candidate.getResult());
-                               procedure.exception(graph, (Throwable)candidate.getResult());
+               
+                       IntSet candidateIs = null;
+                       try {
+                               candidateIs = QueryCache.resultSuperTypes(graph, candidateS, parent, null);
+                       } catch (DatabaseException e) {
+                               procedure.exception(graph, e);
                                return;
                        }
-                       IntSet candidateIs = candidate.getResult();
-               
+
                        for(int i=3;i<map.size();i+=3) {
 
                                int nextS = map.data[i];
@@ -249,13 +183,13 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                                        
                                } else {
                                
-                                       SuperTypes next = SuperTypes.queryEach(graph, nextS, graph.processor, entry, null, NOP);
-                                       if(next.isExcepted()) {
-                                               if(entry != null) entry.except((Throwable)next.getResult());
-                                               procedure.exception(graph, (Throwable)next.getResult());
-                                               return;
-                                       }
-                                       IntSet nextIs = next.getResult();
+                                       IntSet nextIs = null;
+                                       try {
+                                               nextIs = QueryCache.resultSuperTypes(graph, nextS, parent, null);
+                                       } catch (DatabaseException e) {
+                                               procedure.exception(graph, e);
+                                               return;
+                                       }
                                        
                                        if(nextIs.contains(candidateS)) {
 
@@ -267,14 +201,10 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                                                candidateIs = nextIs;
                                                
                                        } else {
-
                                                // candidate and next are unrelated => error
                                                ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has conflicting assertions.", r1);
-                                               
-                                               if(entry != null) entry.except(exception);
                                                procedure.exception(graph, exception);
                                                return;                                         
-                                               
                                        }
                                
                                }
@@ -283,13 +213,8 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                        
                }
                
-               if(entry != null) {
-               entry.addOrSetFunctional(candidateS, candidateP, candidateO);
-               entry.finish(graph, procedure);
-            } else {
-                       procedure.execute(graph, candidateS, candidateP, candidateO);
-                       procedure.finished(graph);
-               }
+            procedure.execute(graph, candidateS, candidateP, candidateO);
+            procedure.finished(graph);
                
         }
         
@@ -308,7 +233,7 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
     };
        
        // Search for one statement
-       final static public void computeFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final RelationInfo ri, final TripleIntProcedure procedure) {
+       final static public void computeFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Statements parent, final RelationInfo ri, final TripleIntProcedure procedure) throws DatabaseException {
         
         if(ri.isFinal) {
             
@@ -317,16 +242,15 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                if(result == 0) {
 
                // Check for assertions
-               forSingleAssertion(graph, r1, r2, entry, procedure);
+               forSingleAssertion(graph, r1, r2, parent, procedure);
 
                } else if(result == -1) {
 
                graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() {
 
                        @Override
-                       public void execute(ReadGraphImpl graph, int i) {
-                               if(entry != null) entry.addOrSetFunctional(r1, r2, i);
-                               else procedure.execute(graph, r1, r2, i);
+                       public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                               procedure.execute(graph, r1, r2, i);
                        }
 
                        @Override
@@ -341,18 +265,13 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                });
 
                // Check for assertions
-               forSingleAssertion(graph, r1, r2, entry, procedure);
+               forSingleAssertion(graph, r1, r2, parent, procedure);
                        
                } else {
 
                // If functional relation was found there is no need to check assertions
-                       if(entry != null) {
-                               entry.addOrSetFunctional(r1, r2, result);
-                               entry.finish(graph, procedure);
-                       } else {
-                               procedure.execute(graph, r1, r2, result);
-                               procedure.finished(graph);
-                       }
+                procedure.execute(graph, r1, r2, result);
+                procedure.finished(graph);
                        
                }
 
@@ -362,25 +281,23 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
             final AtomicBoolean found = new AtomicBoolean(false);
             
             // Note! The dependency is intentionally cut!
-            DirectPredicates.queryEach(graph, r1, graph.processor, null, null, new SyncIntProcedure() {
+            IntSet direct = QueryCache.resultDirectPredicates(graph, r1, null, null);
+            direct.forEach(graph, new SyncIntProcedure() {
                 
                 @Override
-                public void run(ReadGraphImpl graph) {
+                public void run(ReadGraphImpl graph) throws DatabaseException {
                     
                     if(found.get()) {
-                       if(entry != null) entry.finish(graph, procedure);
-                       else procedure.finished(graph);
+                       procedure.finished(graph);
                     } else {
-                    
-                           // Check for assertions
-                           forSingleAssertion(graph, r1, r2, entry, procedure);
-                           
+                        // Check for assertions
+                        forSingleAssertion(graph, r1, r2, parent, procedure);
                     }
                     
                 }
 
                 @Override
-                public void execute(ReadGraphImpl graph, final int pred) {
+                public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException {
                     
                     if(found.get()) return;
 
@@ -389,33 +306,27 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                         inc();
                         
                         // Note! The dependency is intentionally cut!
-                        DirectObjects.queryEach(graph, r1, pred, graph.processor, null, null, new IntProcedure() {
+                        QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() {
 
                             @Override
-                            public void execute(ReadGraphImpl graph, int i) {
+                            public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
                                 
                                if(found.compareAndSet(false, true)) {
-                                    
-                                    if(entry != null) entry.addOrSetFunctional(r1, pred, i);
-                                    else procedure.execute(graph, r1, pred, i);
-                                       
+                                    procedure.execute(graph, r1, pred, i);
                                } else {
-
                                        ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1);
-                                       if(entry != null) entry.except(exception);
                                        procedure.exception(graph, exception);
-                                       
                                }
 
                             }
 
                             @Override
-                            public void finished(ReadGraphImpl graph) {
+                            public void finished(ReadGraphImpl graph) throws DatabaseException {
                                 dec(graph);
                             }
                                                
                                                @Override
-                                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                        procedure.exception(graph, t);
                                 dec(graph);
                                    }
@@ -426,10 +337,10 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                         
                         inc();
                     
-                        SuperRelations.queryEach(graph, pred, graph.processor, entry, null, new InternalProcedure<IntSet>() {
+                        QueryCache.runnerSuperRelations(graph, pred, parent, null, new InternalProcedure<IntSet>() {
     
                             @Override
-                            public void execute(ReadGraphImpl graph, IntSet result) {
+                            public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
                                 
                                 if(found.get()) {
                                     dec(graph);
@@ -441,33 +352,27 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                                     inc();
                                     
                                     // Note! The dependency is intentionally cut!
-                                    DirectObjects.queryEach(graph, r1, pred, graph.processor, null, null, new IntProcedure() {
+                                    QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() {
     
                                         @Override
-                                        public void execute(ReadGraphImpl graph, int i) {
+                                        public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
                                             
                                                if(found.compareAndSet(false, true)) {
-                                                
-                                               if(entry != null) entry.addOrSetFunctional(r1, pred, i);
-                                               else procedure.execute(graph, r1, pred, i);
-                                                       
+                                               procedure.execute(graph, r1, pred, i);
                                                } else {
-
                                                ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1);
-                                               if(entry != null) entry.except(exception);
                                                procedure.exception(graph, exception);
-                                                       
                                                }
                                             
                                         }
     
                                         @Override
-                                        public void finished(ReadGraphImpl graph) {
+                                        public void finished(ReadGraphImpl graph) throws DatabaseException {
                                             dec(graph);
                                         }
                                                        
                                                        @Override
-                                                       public void exception(ReadGraphImpl graph, Throwable t) {
+                                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                                procedure.exception(graph, t);
                                             dec(graph);
                                            }
@@ -481,7 +386,7 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                             }
                                                
                                                @Override
-                                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                        procedure.exception(graph, t);
                                 dec(graph);
                                    }
@@ -493,10 +398,8 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                 }
 
                 @Override
-                public void finished(ReadGraphImpl graph) {
-                    
+                public void finished(ReadGraphImpl graph) throws DatabaseException {
                     dec(graph);
-                    
                 }
                 
             });
@@ -505,33 +408,29 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
 
        }
     
-    final static private void forAssertions(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final TripleIntProcedure procedure) {
+    final static private void forAssertions(ReadGraphImpl graph, final int r1, final int r2, final Statements parent, final TripleIntProcedure procedure) throws DatabaseException {
 
-        PrincipalTypes.queryEach(graph, r1, graph.processor, entry, null, new SyncIntProcedure() {
+       QueryCache.runnerPrincipalTypes(graph, r1, parent, null, new SyncIntProcedure() {
             
             @Override
-            public void run(ReadGraphImpl graph) {
-                
-                if(entry != null) entry.finish(graph, procedure);
-                else procedure.finished(graph);
-                
+            public void run(ReadGraphImpl graph) throws DatabaseException {
+                procedure.finished(graph);
             }
             
             TripleIntProcedure proc = new TripleIntProcedureAdapter() {
 
                 @Override
-                public void execute(ReadGraphImpl graph, int s, int p, int o) {
-                       if(entry != null) entry.addOrSet(s, p, o);
-                       else procedure.execute(graph, s, p, o);
+                public void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException {
+                       procedure.execute(graph, s, p, o);
                 }
 
                 @Override
-                public void finished(ReadGraphImpl graph) {
+                public void finished(ReadGraphImpl graph) throws DatabaseException {
                     dec(graph);
                 }
                                
                                @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
+                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                     dec(graph);
                                        procedure.exception(graph, t);
                    }
@@ -539,21 +438,18 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
             }; 
 
             @Override
-            public void execute(ReadGraphImpl graph, int type) {
-
+            public void execute(ReadGraphImpl graph, int type) throws DatabaseException {
                 inc();
-                
-                AssertedStatements.queryEach(graph, type, r2, graph.processor, entry, null, proc);
-                
+                QueryCache.runnerAssertedStatements(graph, type, r2, parent, null, proc);
             }
             
             @Override
-            public void finished(ReadGraphImpl graph) {
+            public void finished(ReadGraphImpl graph) throws DatabaseException {
                 dec(graph);       
             }
             
             @Override
-            public void exception(ReadGraphImpl graph, Throwable t) {
+            public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                 dec(graph);
             }
             
@@ -562,20 +458,19 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
 
     }
 
-       final static public void computeNotFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Statements entry,  final RelationInfo ri, final TripleIntProcedure procedure) {
+       final static public void computeNotFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Statements parent, final RelationInfo ri, final TripleIntProcedure procedure) throws DatabaseException {
 
                if(ri.isFinal) {
 
                        graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() {
 
                                @Override
-                               public void execute(ReadGraphImpl graph, int i) {
-                                       if(entry != null) entry.addOrSet(r1, r2, i);
-                                       else procedure.execute(graph, r1, r2, i);
+                               public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                                       procedure.execute(graph, r1, r2, i);
                                }
 
                                @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
+                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                        if(DebugException.DEBUG) new DebugException(t).printStackTrace();
                                        procedure.exception(graph, t);
                                }
@@ -587,47 +482,44 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                        });
 
                        if(ri.isAsserted) {
-                               forAssertions(graph, r1, r2, entry, procedure);
+                               forAssertions(graph, r1, r2, parent, procedure);
                        } else {
-                               if(entry != null) entry.finish(graph, procedure);
-                               else procedure.finished(graph);
+                               procedure.finished(graph);
                        }
 
         } else {
 
             // Note! The dependency is intentionally cut!
-            DirectPredicates.queryEach(graph, r1, graph.processor, null, null, new SyncIntProcedure() {
+            IntSet direct = QueryCache.resultDirectPredicates(graph, r1, null, null);
+            direct.forEach(graph, new SyncIntProcedure() {
                 
                 @Override
-                public void run(ReadGraphImpl graph) {
-                    
-                    forAssertions(graph, r1, r2, entry, procedure);
-                    
+                public void run(ReadGraphImpl graph) throws DatabaseException {
+                    forAssertions(graph, r1, r2, parent, procedure);
                 }
 
                 @Override
-                public void execute(ReadGraphImpl graph, final int pred2) {
+                public void execute(ReadGraphImpl graph, final int pred2) throws DatabaseException {
 
                     if(pred2 == r2) {
                         
                         inc();
                         
                         // Note! The dependency is intentionally cut!
-                        DirectObjects.queryEach(graph, r1, pred2, graph.processor, null, null, new IntProcedure() {
+                        QueryCache.runnerDirectObjects(graph, r1, pred2, null, null, new IntProcedure() {
 
                             @Override
-                            public void execute(ReadGraphImpl graph, int i) {
-                               if(entry != null) entry.addOrSet(r1, pred2, i);
-                               else procedure.execute(graph, r1, pred2, i);
+                            public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                               procedure.execute(graph, r1, pred2, i);
                             }
 
                             @Override
-                            public void finished(ReadGraphImpl graph) {
+                            public void finished(ReadGraphImpl graph) throws DatabaseException {
                                 dec(graph);
                             }
                                                
                                                @Override
-                                               public void exception(ReadGraphImpl graph, Throwable t) {
+                                               public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                        procedure.exception(graph, t);
                                 dec(graph);
                                    }
@@ -640,28 +532,27 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
 
                         try {
                             
-                            IntSet result = SuperRelations.queryEach2(graph, pred2, graph.processor, entry, null, null);
+                            IntSet result = QueryCache.resultSuperRelations(graph, pred2, parent, null);
                             if(result.contains(r2)) {
 
                                 inc();
 
                                 // Note! The dependency is intentionally cut!
-                                DirectObjects.queryEach(graph, r1, pred2, graph.processor, null, null, new IntProcedure() {
+                                QueryCache.runnerDirectObjects(graph, r1, pred2, null, null, new IntProcedure() {
 
                                     @Override
-                                    public void execute(ReadGraphImpl graph, int i) {
-                                        if(entry != null) entry.addOrSet(r1, pred2, i);
-                                        else procedure.execute(graph, r1, pred2, i);
+                                    public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+                                        procedure.execute(graph, r1, pred2, i);
 
                                     }
 
                                     @Override
-                                    public void finished(ReadGraphImpl graph) {
+                                    public void finished(ReadGraphImpl graph) throws DatabaseException {
                                         dec(graph);
                                     }
 
                                     @Override
-                                    public void exception(ReadGraphImpl graph, Throwable t) {
+                                    public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                         procedure.exception(graph, t);
                                         dec(graph);
                                     }
@@ -679,7 +570,7 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
                 }
 
                 @Override
-                public void finished(ReadGraphImpl graph) {
+                public void finished(ReadGraphImpl graph) throws DatabaseException {
                     dec(graph);
                 }
                 
@@ -688,46 +579,20 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
         }
         
     }
-    
-    @Override
-    public void computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final TripleIntProcedure procedure, final boolean store) {
-       computeForEach(graph, r1(), r2(), this, procedure);
-    }
        
-    public static void computeForEach(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final TripleIntProcedure procedure) {
-
-       RelationInfoQuery riEntry = RelationInfoQuery.probe(graph, r2);
-       if(riEntry != null) {
-               RelationInfo ri = riEntry.getResult();
-               graph.ensureLoaded(r1, r2);       
-               if(ri.isFunctional) {
-                       computeFunctionalIndex(graph, r1, r2, entry, ri, procedure);
-               } else {
-                       computeNotFunctionalIndex(graph, r1, r2, entry, ri, procedure);
-               }
-               return;
-       }
+    public static void computeForEach(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final TripleIntProcedure procedure_) throws DatabaseException {
+        
+        TripleIntProcedure procedure = entry != null ? entry : procedure_;
        
-        RelationInfoQuery.queryEach(graph, r2, graph.processor, entry, null, new InternalProcedure<RelationInfo>() {
-
-            @Override
-            public void execute(ReadGraphImpl graph, final RelationInfo ri) {
-               
-               graph.ensureLoaded(r1, r2);
-               if(ri.isFunctional) {
-                       computeFunctionalIndex(graph, r1, r2, entry, ri, procedure);
-               } else {
-                       computeNotFunctionalIndex(graph, r1, r2, entry, ri, procedure);
-               }
-                
-            }
-                       
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               procedure.exception(graph, t);
-            }
+        RelationInfo ri = QueryCache.resultRelationInfoQuery(graph, r2, entry, null);
+        graph.ensureLoaded(r1, r2);
+        if(ri.isFunctional) {
+            computeFunctionalIndex(graph, r1, r2, entry, ri, procedure);
+        } else {
+            computeNotFunctionalIndex(graph, r1, r2, entry, ri, procedure);
+        }
 
-        });
+        if(entry != null) entry.performFromCache(graph, procedure_);
         
     }
     
@@ -736,38 +601,18 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
        return "Statements[" + r1() + " - " + r2() + "]";
     }
 
-    final private void finish(ReadGraphImpl graph, TripleIntProcedure procedure) {
+    final private void finish(ReadGraphImpl graph, TripleIntProcedure procedure) throws DatabaseException {
        
         assert(assertPending());
 
-//        ArrayList<TripleIntProcedure> p = null;
-
         synchronized(this) {
-
             setReady();
-//            p = procs;
-//            procs = null;
-
+            //new Exception(toString() + " is READY").printStackTrace();
         }
 
         IntArray v = (IntArray)getResult();
         final IntArray value = (IntArray)getResult();
 
-//        if(p != null) {
-//
-//             for(TripleIntProcedure proc : p) {
-//                     for(int i=0;i<value.size();i+=3) {
-//                             proc.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
-//                     }
-//             }
-//             for(int i=0;i<value.size();i+=3) {
-//                     procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
-//             }
-//
-//            for(TripleIntProcedure proc : p) proc.finished(graph);
-//
-//        }
-
         for(int i=0;i<value.size();i+=3) {
                procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
         }
@@ -776,35 +621,6 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
        
     }
 
-//    final private void finish(ReadGraphImpl graph, QueryProcessor provider) {
-//        
-//     assert(isPending());
-//
-//        ArrayList<TripleIntProcedure> p = null;
-//
-//        synchronized(this) {
-//             
-//             setReady();
-//            p = procs;
-//            procs = null; 
-//        
-//        }
-//        
-//        if(p != null) {
-//             
-//             final IntArray value = (IntArray)getResult();
-//             for(TripleIntProcedure proc : p) {
-//                     for(int i=0;i<value.size();i+=3) {
-//                             proc.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
-//                     }
-//             }
-//
-//             for(TripleIntProcedure proc : p) proc.finished(graph);
-//
-//        }
-//
-//    }
-    
     synchronized public void addOrSet(int s, int p, int o) {
         
        assert(assertPending());
@@ -842,50 +658,39 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
     }
     
     @Override
-    public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, final TripleIntProcedure procedure) {
+    public Object performFromCache(ReadGraphImpl graph, final TripleIntProcedure procedure) throws DatabaseException {
 
        assert(isReady());
 
-       if(handleException(graph, procedure)) return;
-       
         final IntArray value = (IntArray)getResult();
+
+       if(handleException(graph, procedure)) return value;
+       
         for(int i=0;i<value.size();i+=3) {
                procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
         }
 
         procedure.finished(graph);
         
+        return value;
+        
     }
     
     @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
+    public void recompute(ReadGraphImpl graph) throws DatabaseException {
         
-        final Semaphore s = new Semaphore(0);
-       
-        computeForEach(graph, provider, new TripleIntProcedureAdapter() {
+        computeForEach(graph, r1(), r2(), this, new TripleIntProcedureAdapter() {
 
             @Override
             public void finished(ReadGraphImpl graph) {
-                s.release();
             }
                        
                        @Override
                        public void exception(ReadGraphImpl graph, Throwable t) {
                                new Error("Error in recompute.", t).printStackTrace();
-                               s.release();
             }
 
-        }, true);
-        
-       while(!s.tryAcquire()) {
-               provider.resume(graph);
-       }
-        
-//        try {
-//            s.acquire();
-//        } catch (InterruptedException e) {
-//            throw new Error(e);
-//        }
+        });
         
     }
 
@@ -899,5 +704,20 @@ final public class Statements extends CollectionBinaryQuery<TripleIntProcedure>
     boolean isImmutable(ReadGraphImpl graph) {
        return graph.processor.isImmutable(r1());
     }
+
+    @Override
+    public void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException {
+        addOrSet(s, p, o);
+    }
+
+    @Override
+    public void finished(ReadGraphImpl graph) throws DatabaseException {
+        setReady();
+    }
+
+    @Override
+    public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+        except(throwable);
+    }
     
 }
index 36d6acc5ae377e5c55e7f5019af705c48085cfe9..3498b1ac2763167d3834d1abefa964ec9f8fdc90 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.request.RequestFlags;
 
-abstract public class StringQuery<Procedure> extends CacheEntryBase implements Query {
+public abstract class StringQuery<Procedure> extends CacheEntryBase<Procedure> implements Query {
 
-    final public String id;
-    final public int hash;
+    public final String id;
+    protected final int hash;
 
     public StringQuery(String id) {
         assert(id != null);
-       this.id = id;
-       hash = id.hashCode();
+        this.id = id;
+        hash = id.hashCode();
     }
-    
+
     @Override
     int makeHash() {
-       return id.hashCode();
+        return id.hashCode();
     }
-    
-    final protected static int hash(String id) {
+
+    protected static final int hash(String id) {
         return id.hashCode();
     }
-    
+
     @Override
     public int type() {
         return RequestFlags.INVALIDATE;
     }
-    
+
     @Override
     final public boolean equals(Object object) {
         if (this == object)
@@ -47,30 +46,15 @@ abstract public class StringQuery<Procedure> extends CacheEntryBase implements Q
             return false;
         else if (getClass() != object.getClass())
             return false;
-        StringQuery other = (StringQuery)object;
+        StringQuery<?> other = (StringQuery<?>) object;
         return id == other.id;
     }
-    
+
     @Override
     final public Query getQuery() {
         return this;
     }
-    
-    @Override
-    public void recompute(ReadGraphImpl graph, Object provider, CacheEntry entry) {
-        throw new Error("Recompute of primitive queries is not supported.");
-    }
-    
-    @Override
-    public void performFromCache(ReadGraphImpl graph, Object provider, Object procedure) {
-       throw new Error("Not possible.");
-    }
-    
-    abstract public void recompute(ReadGraphImpl graph, QueryProcessor provider);
-    abstract public void computeForEach(ReadGraphImpl graph, QueryProcessor provider, Procedure procedure);
-    abstract public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, Procedure procedure);
-    abstract public void putEntry(QueryProcessor provider);
+
     abstract public void removeEntry(QueryProcessor provider);
-    abstract public StringQuery<Procedure> getEntry(QueryProcessor provider);
-       
+
 }
index e76f702e14f54ca8b1a379ba255ca8d4e69f229c..1f540062e9440d2db81164ee820c05566f4a55c0 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import gnu.trove.procedure.TIntProcedure;
-import gnu.trove.set.hash.TIntHashSet;
-
-import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicInteger;
 
+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;
-import org.simantics.db.procedure.ListenerBase;
-
-final public class SuperRelations extends UnaryQuery<InternalProcedure<IntSet>> {
-       
-//     public ArrayList<InternalProcedure<IntSet>> procs = null;
-    
-    private SuperRelations(final int resource) {
-        super(resource);
-    }
-    
-    final static SuperRelations entry(final QueryProcessor provider, final int r) {
-        
-        return (SuperRelations)provider.superRelationsMap.get(r);
-
-    }
 
-    final static IntSet runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
-
-        SuperRelations entry = (SuperRelations)provider.superRelationsMap.get(r);
-        if(entry == null) {
-
-               entry = new SuperRelations(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-               return (IntSet)provider.performForEach(graph, entry, parent, listener, procedure);
-            
-        } else {
-               
-            if(!entry.isReady()) {
-                throw new IllegalStateException();
-            }
-            return (IntSet)provider.performForEach(graph, entry, parent, listener, procedure);
-            
-        }
-
-    }
-    
-    final static IntSet runner2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) throws Throwable {
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.set.hash.TIntHashSet;
 
-        SuperRelations entry = (SuperRelations)provider.superRelationsMap.get(r);
-        if(entry == null) {
+public final class SuperRelations extends UnaryQueryP<IntSet> {
 
-            entry = new SuperRelations(r);
-            entry.setPending();
-            entry.clearResult(provider.querySupport);
-            entry.putEntry(provider);
-            
-            return (IntSet)provider.performForEach2(graph, entry, parent, listener, procedure);
-            
-        } else {
-            
-            if(!entry.isReady()) {
-                throw new IllegalStateException();
-            }
-            return (IntSet)provider.performForEach2(graph, entry, parent, listener, procedure);
-            
-        }
-
-    }    
-    
-    final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
-
-        if(parent == null && listener == null) {
-               SuperRelations entry = (SuperRelations)provider.superRelationsMap.get(r);
-               if(entry != null && entry.isReady()) {
-                   entry.performFromCache(graph, provider, procedure);
-                   return;
-               }
-        }
-        
-        runner(graph, r, provider, parent, listener, procedure);
-         
+    SuperRelations(final int resource) {
+        super(resource);
     }
 
-    final public static IntSet queryEach2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) throws Throwable {
-
-        if(parent == null && listener == null) {
-            SuperRelations entry = (SuperRelations)provider.superRelationsMap.get(r);
-            if(entry != null && entry.isReady()) {
-                return (IntSet)entry.get(graph, provider, procedure);
-            }
-        }
-        
-        return runner2(graph, r, provider, parent, listener, procedure);
-         
+    static final SuperRelations entry(final QueryProcessor provider, final int r) {
+        return (SuperRelations)provider.cache.superRelationsMap.get(r);
     }
-    
-       @Override
-       public UnaryQuery<InternalProcedure<IntSet>> getEntry(QueryProcessor provider) {
-        return provider.superRelationsMap.get(id);
-       }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-        provider.superRelationsMap.put(id, this);
-       }
 
        @Override
-       final public void removeEntry(QueryProcessor provider) {
-               provider.superRelationsMap.remove(id);
+       public final void removeEntry(QueryProcessor provider) {
+               provider.cache.remove(this);
        }
        
-       static int histoCounter = 0;
-       static IntSet EMPTY_SET = new IntSet();
-    static int counter = 0;
-    
-    class Koss {
+    static class Ints {
         
         private TIntHashSet set = null;
         public int single = 0;
@@ -157,67 +66,75 @@ final public class SuperRelations extends UnaryQuery<InternalProcedure<IntSet>>
         
     }
 
-       @Override
-       public Object computeForEach(final ReadGraphImpl graph, final QueryProcessor provider, final InternalProcedure<IntSet> procedure, final boolean store) {
+       public void compute(final ReadGraphImpl graph, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+           computeForEach(graph, id, this, procedure);
+       }
 
-               provider.querySupport.ensureLoaded(graph, id);
+    static class DirectProcedure extends Ints implements IntProcedure, TIntProcedure, InternalProcedure<IntSet> {
+        
+        IntSet result;
+        InternalProcedure<IntSet> proc;
+        
+        public DirectProcedure(IntSet result, InternalProcedure<IntSet> proc) {
+            this.result = result;
+            this.proc = proc;
+        }
+        
+        @Override
+        final public boolean execute(int r) {
+            result.add(r);
+            return true;
+        }
+        @Override
+        final public void execute(ReadGraphImpl graph, int r) {
+            if(single == 0) {
+                single = r;
+                return;
+            }
+            add(r);
+        }
+        @Override
+        public final void execute(ReadGraphImpl graph, IntSet set) throws DatabaseException {
+            set.forEach(this);
+            proc.execute(graph, result);
+        }
+        @Override
+        public void finished(ReadGraphImpl graph) {
+        }
+        @Override
+        public void exception(ReadGraphImpl graph, Throwable t) {
+            throw new Error("Errors are not supported.", t);
+        }
+
+    }
+
+       public static Object computeForEach(final ReadGraphImpl graph, int id, SuperRelations entry, final InternalProcedure<IntSet> procedure_) throws DatabaseException {
+           
+           InternalProcedure<IntSet> procedure = entry != null ? entry : procedure_;
+
+           QueryProcessor processor = graph.processor;
+               
+               processor.querySupport.ensureLoaded(graph, id);
                
            final InternalProcedure<IntSet> proc = (InternalProcedure<IntSet>)procedure;
 
-           final int subrelationOf = provider.getSubrelationOf();
-
-           final IntSet result = new IntSet(provider.querySupport);
-
-           final class DirectProcedure extends Koss implements IntProcedure, TIntProcedure, InternalProcedure<IntSet> {
-               @Override
-               final public boolean execute(int r) {
-                       result.add(r);
-                       return true;
-               }
-               @Override
-               final public void execute(ReadGraphImpl graph, int r) {
-                       if(single == 0) {
-                               single = r;
-                               return;
-                       }
-                       add(r);
-               }
-               @Override
-               final public void execute(ReadGraphImpl graph, IntSet set) {
-                       set.forEach(this);
-                       addOrSet(graph, result, provider);
-                       proc.execute(graph, result);
-               }
-               @Override
-               public void finished(ReadGraphImpl graph) {
-               }
-               @Override
-               public void exception(ReadGraphImpl graph, Throwable t) {
-                       throw new Error("Errors are not supported.", t);
-               }
+           final int subrelationOf = processor.getSubrelationOf();
 
-           }
+           final IntSet result = new IntSet(processor.querySupport);
 
-           final DirectProcedure directProc = new DirectProcedure();
+           final DirectProcedure directProc = new DirectProcedure(result, proc);
 
-           provider.querySupport.getObjects(graph, id, subrelationOf, directProc);
+          processor.querySupport.getObjects(graph, id, subrelationOf, directProc);
 
            int size = directProc.size();
 
            if(size == 0) {
-
-               addOrSet(graph, EMPTY_SET, provider);
-               proc.execute(graph, EMPTY_SET);
-
+               proc.execute(graph, IntSet.EMPTY);
            } else if (size == 1) {
-
                result.add(directProc.single);
-               SuperRelations.queryEach(graph, directProc.single, provider, SuperRelations.this, null, directProc);
-
+               QueryCache.runnerSuperRelations(graph, directProc.single, entry, null, directProc);
            } else {
 
-               //                  if((counter++ % 500) == 0) System.out.println("SR " + counter);
-
                final TIntProcedure addToResult = new TIntProcedure() {
                        @Override
                        public boolean execute(int r) {
@@ -234,26 +151,34 @@ final public class SuperRelations extends UnaryQuery<InternalProcedure<IntSet>>
 
                        @Override
                        public boolean execute(int arg0) {
+                               try {
+                                               return execute0(arg0);
+                                       } catch (DatabaseException e) {
+                                               Logger.defaultLogError(e);
+                                       }
+                               return false;
+                       }
+
+                       public boolean execute0(int arg0) throws DatabaseException {
 
                                synchronized(result) {
                                        result.add(arg0);
                                }
 
-                               SuperRelations.queryEach(graph, arg0, provider, SuperRelations.this, null, new InternalProcedure<IntSet>() {
+                               QueryCache.runnerSuperRelations(graph, arg0, entry, null, new InternalProcedure<IntSet>() {
 
                                        @Override
-                                       public void execute(ReadGraphImpl graph, IntSet set) {
+                                       public void execute(ReadGraphImpl graph, IntSet set) throws DatabaseException {
                                                set.forEach(addToResult);
                                                int current = finishes.addAndGet(1);
                                                if(current == directProc.size()) {
-                                                       addOrSet(graph, result, provider);
                                                        proc.execute(graph, result);
                                                        return; 
                                                }
                                        }
 
                                        @Override
-                                       public void exception(ReadGraphImpl graph, Throwable t) {
+                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                                proc.exception(graph, t);
                                        }
 
@@ -267,6 +192,8 @@ final public class SuperRelations extends UnaryQuery<InternalProcedure<IntSet>>
 
            }
            
+           if(entry != null) entry.performFromCache(graph, procedure_);
+            
            return result;
         
     }
@@ -275,77 +202,5 @@ final public class SuperRelations extends UnaryQuery<InternalProcedure<IntSet>>
     public String toString() {
        return "SuperRelations[" + id + "]";
     }
-
-    private void addOrSet(ReadGraphImpl graph, final IntSet value, QueryProcessor provider) {
-
-        assert(!isReady());
-
-//        ArrayList<InternalProcedure<IntSet>> p = null;
-
-        synchronized(this) {
-        
-            value.trim();
-            setResult(value);
-            setReady();
-//            p = procs;
-//            procs = null; 
-        
-        }
-
-//        if(p != null) {
-//             IntSet v = (IntSet)getResult();
-//             if(v != null) {
-//                 for(InternalProcedure<IntSet> proc : p) proc.execute(graph, v);
-//             }
-//        }
-        
-    }
-    
-    @Override
-    public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<IntSet> procedure) {
-              
-        assert(isReady());
-
-       if(handleException(graph, procedure)) return null;
-        
-       IntSet result = getResult();
-       
-        procedure.execute(graph, result);
-        
-        return result;
-        
-    }
-
-    @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-        
-        final Semaphore s = new Semaphore(0);
-
-        computeForEach(graph, provider, new InternalProcedure<IntSet>() {
-
-               @Override
-               public void execute(ReadGraphImpl graph, IntSet result) {
-                s.release();
-               }
-
-            @Override
-            public void exception(ReadGraphImpl graph, Throwable t) {
-               s.release();
-                new Error("Error in recompute.", t).printStackTrace();
-            }
-
-        }, true);
-
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
-        
-    }
-    
-
-    @Override
-    boolean isImmutable(ReadGraphImpl graph) {
-       return graph.processor.isImmutable(id);
-    }
     
 }
index 0489546c55d6caa5fdd50f5537bf321302db4f7f..a02fda4623342fc7d80889f8c543f6d5aec70316 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import gnu.trove.procedure.TIntProcedure;
-
-import java.util.concurrent.Semaphore;
-
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.procedure.InternalProcedure;
-import org.simantics.db.procedure.ListenerBase;
 
-final public class SuperTypes extends UnaryQuery<InternalProcedure<IntSet>> {
-    
-//     public ArrayList<InternalProcedure<IntSet>> procs = null;
-       
-    private SuperTypes(final int resource) {
+import gnu.trove.procedure.TIntProcedure;
+
+public final class SuperTypes extends UnaryQueryP<IntSet> {
+
+    SuperTypes(int resource) {
         super(resource);
     }
-    
-    final static SuperTypes runner(ReadGraphImpl graph, final int r, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
-
-       SuperTypes entry = (SuperTypes)provider.superTypesMap.get(r);
-        if(entry == null) {
-               
-               entry = new SuperTypes(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-            provider.performForEach(graph, entry, parent, listener, procedure);
-            
-            return entry;
-            
-        } else {
-               
-            if(!entry.isReady()) {
-               synchronized(entry) {
-                    if(!entry.isReady()) {
-                        throw new IllegalStateException();
-//                     if(entry.procs == null) entry.procs = new ArrayList<InternalProcedure<IntSet>>();
-//                     entry.procs.add(procedure);
-//                                             provider.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                     return entry;
-                    }
-               }
-            }
-            provider.performForEach(graph, entry, parent, listener, procedure);
-        }
-        
-        return entry;
 
+    @Override
+    public final void removeEntry(QueryProcessor provider) {
+        provider.cache.remove(this);
     }
-    
-    final public static SuperTypes queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
-    
-        if(parent == null && listener == null) {
-               SuperTypes entry = (SuperTypes)provider.superTypesMap.get(r);
-               if(entry != null && entry.isReady()) { 
-                       entry.performFromCache(graph, provider, procedure);
-                       return entry;
-               }
-        }
-        
-        return runner(graph, r, parent, provider, listener, procedure);
-         
+
+    @Override
+    public void compute(ReadGraphImpl graph, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+        computeForEach(graph, id, this, procedure);
     }
-       
-       @Override
-       public UnaryQuery<InternalProcedure<IntSet>> getEntry(QueryProcessor provider) {
-        return provider.superTypesMap.get(id);
-       }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-        provider.superTypesMap.put(id, this);
-       }
-
-       @Override
-       final public void removeEntry(QueryProcessor provider) {
-               provider.superTypesMap.remove(id);
-       }
-
-       @Override
-       public Object computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final InternalProcedure<IntSet> procedure, boolean store) {
+
+    public static Object computeForEach(ReadGraphImpl graph, int r, SuperTypes entry, final InternalProcedure<IntSet> procedure_) throws DatabaseException {
+
+        InternalProcedure<IntSet> procedure = entry != null ? entry : procedure_;
+
+        QueryProcessor provider = graph.processor;
 
         final int inherits = provider.getInherits();
-        
-        final CacheEntry parent = graph.parent;
-        
-        assert(graph.parent != this);
 
         final IntSet result = new IntSet(provider.querySupport);
-        
+
         final TIntProcedure addToResult = new TIntProcedure() {
             @Override
             public boolean execute(int r) {
-               synchronized(result) {
-                       result.add(r);
-               }
+                synchronized(result) {
+                    result.add(r);
+                }
                 return true;
             }
         };
 
-        DirectObjects.queryEach(graph, id, inherits, provider, this, null, new SyncIntProcedure() {
-            
-            @Override
-            public void run(ReadGraphImpl graph) {
+        QueryCache.runnerDirectObjects(graph, r, inherits, entry, null, new SyncIntProcedure() {
 
-                addOrSet(graph, result, provider);
+            @Override
+            public void run(ReadGraphImpl graph) throws DatabaseException {
                 procedure.execute(graph, result);
-                
             }
-            
+
             @Override
-            public void execute(ReadGraphImpl graph, final int i) {
-                
-               assert(graph.parent == parent);
-               
-               synchronized(result) {
-                       result.add(i);
-               }
-                
+            public void execute(ReadGraphImpl graph, final int i) throws DatabaseException {
+
+                synchronized(result) {
+                    result.add(i);
+                }
+
                 inc();
 
-                SuperTypes.queryEach(graph, i, provider, SuperTypes.this, null, new InternalProcedure<IntSet>() {
+                QueryCache.runnerSuperTypes(graph, i, entry, null, new InternalProcedure<IntSet>() {
 
                     @Override
-                    public void execute(ReadGraphImpl graph, IntSet types) {
+                    public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException {
 
                         types.forEach(addToResult);
                         dec(graph);
                         
                     }
-                               
-                               @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
-                                       procedure.exception(graph, t);
-                   }
+
+                    @Override
+                    public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                        procedure.exception(graph, t);
+                    }
 
                 });
-                
+
             }
 
             @Override
-            public void finished(ReadGraphImpl graph) {
+            public void finished(ReadGraphImpl graph) throws DatabaseException {
                 dec(graph);
             }
-            
+
         });
-        
-        return result;
-        
-    }
-    
-    @Override
-    public String toString() {
-       return "SuperTypes2[" + id + "]";
-    }
 
-    private void addOrSet(ReadGraphImpl graph, final IntSet value, QueryProcessor provider) {
-       
-        assert(!isReady());
-
-//        ArrayList<InternalProcedure<IntSet>> p = null;
-
-        synchronized(this) {
-        
-            value.trim();
-            setResult(value);
-            setReady();
-//            p = procs;
-//            procs = null; 
-        
-        }
-
-//        if(p != null) {
-//             IntSet v = (IntSet)getResult();
-//             if(v != null) {
-//                 for(InternalProcedure<IntSet> proc : p) proc.execute(graph, v);
-//             }
-//        }
-        
-    }
+        if(entry != null) entry.performFromCache(graph, procedure_);
 
-    @Override
-    public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<IntSet> procedure) {
-       
-       assert(isReady());
-
-       if(handleException(graph, procedure)) return null;
-       
-       IntSet result = getResult();
-       
-        procedure.execute(graph, result);
-        
         return result;
-        
-    }
-    
-    @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-        
-        final Semaphore s = new Semaphore(0);
-
-        computeForEach(graph, provider, new InternalProcedure<IntSet>() {
-
-               @Override
-               public void execute(ReadGraphImpl graph, IntSet result) {
-                s.release();
-               }
-
-            @Override
-            public void exception(ReadGraphImpl graph, Throwable t) {
-               s.release();
-                new Error("Error in recompute.", t).printStackTrace();
-            }
-
-        }, true);
 
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
-        
     }
-    
+
     @Override
-    boolean isImmutable(ReadGraphImpl graph) {
-       return graph.processor.isImmutable(id);
+    public String toString() {
+        return "SuperTypes[" + id + "]";
     }
-    
+
 }
index f79910358e1706770f8fb033dcbb39e68de9aeb1..c03f63b5ea56497ec236611aa58463bb3c44b2a8 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 
-
-abstract public class SyncIntProcedure implements IntProcedure, ThreadRunnable {
+public abstract class SyncIntProcedure implements IntProcedure, ThreadRunnable {
 
        int barrier = 1;
-//     
+
 //    final private AtomicInteger barrier = new AtomicInteger(1);
-    
+
     public SyncIntProcedure() {
     }
-    
-    final protected void inc() {
-//     System.err.println("inc " + barrier.get());
+
+    protected final void inc() {
+//        System.err.println("inc " + barrier.get());
        ++barrier;
-//     barrier.incrementAndGet();
+//        barrier.incrementAndGet();
     }
-    
-    final protected void dec(ReadGraphImpl graph) {
-//     System.err.println("dec " + barrier.get());
-       if((--barrier) == 0) {
+
+    protected final void dec(ReadGraphImpl graph) throws DatabaseException {
+//        System.err.println("dec " + barrier.get());
+        if((--barrier) == 0) {
             run(graph);
-       }
+        }
     }
-    
+
     @Override
-    public void exception(ReadGraphImpl graph, Throwable t) {
-       throw new Error("Errors are not supported,", t);
+    public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+        throw new Error("Errors are not supported,", t);
     }
-    
+
 }
index 779495484cdcc87a8620403970f8eba39cbe985f..60dc593bf6db1498fc107d307d1b7ad16875693d 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 
 public interface ThreadRunnable {
 
-    void run(ReadGraphImpl graph);
-    
+    void run(ReadGraphImpl graph) throws DatabaseException;
+
 }
index 341dd48f9bf5b37a71e409e6ef7019389fa7477c..7fbbdf76c9e1ec42f12f883897b92ee2696e112d 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 
 
 public interface TripleIntProcedure {
 
-    void execute(ReadGraphImpl graph, int s, int p, int o);
-    void finished(ReadGraphImpl graph);
-    void exception(ReadGraphImpl graph, Throwable throwable);
-    
+    void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException ;
+    void finished(ReadGraphImpl graph) throws DatabaseException ;
+    void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException;
+
 }
index 5c5d6cb093d1f3e3a90f10c30fb2560ff35b5bc5..5c2be0c64e6dca1908b182ee340073de9405bfa3 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import gnu.trove.procedure.TIntProcedure;
-
-import java.util.concurrent.Semaphore;
-
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.procedure.InternalProcedure;
 import org.simantics.db.procedure.ListenerBase;
 
-final public class TypeHierarchy extends UnaryQuery<InternalProcedure<IntSet>> {
-    
-//     public ArrayList<InternalProcedure<IntSet>> procs = null;
-       
-    private TypeHierarchy(final int resource) {
+import gnu.trove.procedure.TIntProcedure;
+
+public final class TypeHierarchy extends UnaryQueryP<IntSet> {
+
+    TypeHierarchy(int resource) {
         super(resource);
     }
-    
-    final static void runner(ReadGraphImpl graph, final int r, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
-
-       TypeHierarchy entry = (TypeHierarchy)provider.typeHierarchyMap.get(r);
-        if(entry == null) {
-
-               entry = new TypeHierarchy(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-            provider.performForEach(graph, entry, parent, listener, procedure);
-            
-        } else {
-               
-            if(!entry.isReady()) {
-               synchronized(entry) {
-                    if(!entry.isReady()) {
-                        throw new IllegalStateException();
-//                     if(entry.procs == null) entry.procs = new ArrayList<InternalProcedure<IntSet>>();
-//                     entry.procs.add(procedure);
-//                                             provider.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                     return;
-                    }
-               }
-            }
-            provider.performForEach(graph, entry, parent, listener, procedure);
-        }
 
+    public static final void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+        QueryCache.runnerTypeHierarchy(graph, r, parent, listener, procedure);
+    }
+
+    @Override
+    public final void removeEntry(QueryProcessor provider) {
+        provider.cache.remove(this);
     }
-    
-    final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
-        
-        if(parent == null && listener == null) {
-               TypeHierarchy entry = (TypeHierarchy)provider.typeHierarchyMap.get(r);
-               if(entry != null && entry.isReady()) { 
-                       entry.performFromCache(graph, provider, procedure);
-                       return;
-               }
-        }
-        
-        runner(graph, r, parent, provider, listener, procedure);
-         
+
+    @Override
+    public void compute(final ReadGraphImpl graph, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+        computeForEach(graph, id, this, procedure);
     }
-       
-       @Override
-       public UnaryQuery<InternalProcedure<IntSet>> getEntry(QueryProcessor provider) {
-        return provider.typeHierarchyMap.get(id);
-       }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-        provider.typeHierarchyMap.put(id, this);
-       }
-
-       @Override
-       final public void removeEntry(QueryProcessor provider) {
-               provider.typeHierarchyMap.remove(id);
-       }
-
-       @Override
-       public IntSet computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final InternalProcedure<IntSet> procedure, boolean store) {
-
-        final IntSet result = new IntSet(provider.querySupport, id);
-        
+
+    public static IntSet computeForEach(ReadGraphImpl graph, int id, TypeHierarchy entry, final InternalProcedure<IntSet> procedure_) throws DatabaseException {
+
+        InternalProcedure<IntSet> procedure = entry != null ? entry : procedure_;
+
+        QueryProcessor processor = graph.processor;
+
+        final IntSet result = new IntSet(processor.querySupport, id);
+
         final TIntProcedure addToResult = new TIntProcedure() {
             @Override
             public boolean execute(int r) {
@@ -98,102 +53,31 @@ final public class TypeHierarchy extends UnaryQuery<InternalProcedure<IntSet>> {
                 return true;
             }
         };
-        
-        SuperTypes.queryEach(graph, id, provider, TypeHierarchy.this, null, new InternalProcedure<IntSet>() {
-
-               @Override
-               public void execute(ReadGraphImpl graph, IntSet types) {
 
-                       types.forEach(addToResult);
-                       addOrSet(graph, result, provider);
-                       procedure.execute(graph, result); 
+        QueryCache.runnerSuperTypes(graph, id, entry, null, new InternalProcedure<IntSet>() {
 
-               }
+            @Override
+            public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException {
+                types.forEach(addToResult);
+                procedure.execute(graph, result); 
+            }
 
-               @Override
-               public void exception(ReadGraphImpl graph, Throwable t) {
-                       procedure.exception(graph, t);
-               }
+            @Override
+            public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                procedure.exception(graph, t);
+            }
 
         });
-        
+
+        if(entry != null) entry.performFromCache(graph, procedure_);
+
         return result;
-                        
-    }
-    
-    @Override
-    public String toString() {
-       return "TypeHierarchy[" + id + "]";
-    }
 
-    private void addOrSet(ReadGraphImpl graph, final IntSet value, QueryProcessor provider) {
-       
-        assert(!isReady());
-
-//        ArrayList<InternalProcedure<IntSet>> p = null;
-
-        synchronized(this) {
-        
-            value.trim();
-            setResult(value);
-            setReady();
-//            p = procs;
-//            procs = null; 
-        
-        }
-
-//        if(p != null) {
-//             IntSet v = (IntSet)getResult();
-//             if(v != null) {
-//                 for(InternalProcedure<IntSet> proc : p) proc.execute(graph, v);
-//             }
-//        }
-        
     }
 
     @Override
-    public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<IntSet> procedure) {
-       
-       assert(isReady());
-
-       if(handleException(graph, procedure)) return null;
-       
-       IntSet result = getResult();
-       
-        procedure.execute(graph, result);
-        
-        return result;
-        
+    public String toString() {
+        return "TypeHierarchy[" + id + "]";
     }
-    
-    @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-        
-        final Semaphore s = new Semaphore(0);
-
-        computeForEach(graph, provider, new InternalProcedure<IntSet>() {
-
-               @Override
-               public void execute(ReadGraphImpl graph, IntSet result) {
-                s.release();
-               }
 
-            @Override
-            public void exception(ReadGraphImpl graph, Throwable t) {
-               s.release();
-                new Error("Error in recompute.", t).printStackTrace();
-            }
-
-        }, true);
-
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
-        
-    }
-    
-    @Override
-    boolean isImmutable(ReadGraphImpl graph) {
-       return graph.processor.isImmutable(id);
-    }    
 }
index 49cb5c4c61ac0fabb59d01cf326d96c7ba1ad0b1..a9fe36bc6bfcb60608e2758f3a28721c165e09dc 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import gnu.trove.procedure.TIntProcedure;
-
-import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.procedure.InternalProcedure;
-import org.simantics.db.procedure.ListenerBase;
 
-final public class Types extends UnaryQuery<InternalProcedure<IntSet>> {
-    
-//     public ArrayList<InternalProcedure<IntSet>> procs;
-       
-    private Types(final int resource) {
+import gnu.trove.procedure.TIntProcedure;
+
+public final class Types extends UnaryQueryP<IntSet> {
+
+    Types(int resource) {
         super(resource);
     }
-    
-    final static Types entry(final QueryProcessor provider, final int r) {
-        return (Types)provider.typesMap.get(r);
-    }
-    
-   final static void runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, Types cached, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
-
-       Types entry = cached != null ? cached : (Types)provider.typesMap.get(r); 
-        if(entry == null) {
-               
-               entry = new Types(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-            provider.performForEach(graph, entry, parent, listener, procedure);
-            
-        } else {
-
-               if(!entry.isReady()) {
-                   throw new IllegalStateException();
-            }
-            provider.performForEach(graph, entry, parent, listener, procedure);
-        }
-       
-    }
-    
-    final static IntSet runner2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
-
-       Types entry = (Types)provider.typesMap.get(r); 
-        if(entry == null) {
-               
-               entry = new Types(r);
-               entry.setPending();
-               entry.clearResult(provider.querySupport);
-               entry.putEntry(provider);
-               
-            return (IntSet)provider.performForEach2(graph, entry, parent, null, null);
-            
-        } else {
-
-               if(!entry.isReady()) {
-                   throw new IllegalStateException();
-            }
-            return (IntSet)provider.performForEach2(graph, entry, parent, null, null);
-            
-        }
-       
+
+    @Override
+    public final void removeEntry(QueryProcessor provider) {
+        provider.cache.remove(this);
     }
-    
-    final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
-        
-       final Types entry = (Types)provider.typesMap.get(r);
-       
-       if(parent == null && listener == null) {
-               if(entry != null && entry.isReady()) { 
-                       entry.performFromCache(graph, provider, procedure);
-                       return;
-               }
-        }
-       
-        runner(graph, r, provider, entry, parent, listener, procedure);
-         
+
+    @Override
+    public void compute(final ReadGraphImpl graph, final InternalProcedure<IntSet> procedure) throws DatabaseException {
+        computeForEach(graph, id, this, procedure);
     }
 
-    final public static IntSet queryEach2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
-        
-        if(parent == null) {
-            Types entry = (Types)provider.typesMap.get(r);
-            if(entry != null && entry.isReady()) {
-                return (IntSet)entry.get(graph, provider, null);
-            }
-        }
-        
-        return runner2(graph, r, provider, parent);
-         
+    public static void computeForEach(final ReadGraphImpl graph, int id, Types entry,
+            final InternalProcedure<IntSet> procedure_) throws DatabaseException {
+
+        InternalProcedure<IntSet> procedure = entry != null ? entry : procedure_;
+
+        computeForEach2(graph, id, entry, procedure);
+
+        if (entry != null)
+            entry.performFromCache(graph, procedure_);
+
     }
-    
-       @Override
-       public UnaryQuery<InternalProcedure<IntSet>> getEntry(QueryProcessor provider) {
-        return provider.typesMap.get(id);
-       }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-        provider.typesMap.put(id, this);
-       }
 
-       @Override
-       final public void removeEntry(QueryProcessor provider) {
-               provider.typesMap.remove(id);
-       }
+    public static void computeForEach2(final ReadGraphImpl graph, int id, Types parent,
+            final InternalProcedure<IntSet> procedure) throws DatabaseException {
 
-       @Override
-       public Object computeForEach(final ReadGraphImpl graph, final QueryProcessor queryProvider, final InternalProcedure<IntSet> procedure, final boolean store) {
+        QueryProcessor processor = graph.processor;
 
-               queryProvider.querySupport.ensureLoaded(graph, id);
-               int ret = queryProvider.querySupport.getSingleInstance(id);
-               if(ret > 0) {
+        processor.querySupport.ensureLoaded(graph, id);
 
-                       TypeHierarchy.queryEach(graph, ret, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
+        int ret = processor.querySupport.getSingleInstance(id);
+        if (ret > 0) {
 
-                               @Override
-                               public void execute(ReadGraphImpl graph, IntSet types) {
+            TypeHierarchy.queryEach(graph, ret, processor, parent, null, new InternalProcedure<IntSet>() {
 
-                                       addOrSet(graph, types, queryProvider);
-                                       procedure.execute(graph, types);
+                @Override
+                public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException {
+                    procedure.execute(graph, types);
+                }
 
-                               }
+                @Override
+                public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                    procedure.exception(graph, t);
+                }
 
-                               @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
-                                       procedure.exception(graph, t);
-                               }
+            });
 
-                       });
+            return;
 
-                       return getResult();
+        }
 
-               }
-               
-               final int instanceOf = queryProvider.getInstanceOf();
-        final int inherits = queryProvider.getInherits();
-        final int subrelationOf = queryProvider.getSubrelationOf();
+        final int instanceOf = processor.getInstanceOf();
+        final int inherits = processor.getInherits();
+        final int subrelationOf = processor.getSubrelationOf();
+
+        final IntSet result = new IntSet(processor.querySupport);
 
-        final IntSet result = new IntSet(queryProvider.querySupport);
-        
         final TIntProcedure addToResult = new TIntProcedure() {
             @Override
             public boolean execute(int r) {
-               synchronized(result) {
-                       result.add(r);
-               }
+                synchronized (result) {
+                    result.add(r);
+                }
                 return true;
             }
         };
-        
+
         final AtomicInteger finishes = new AtomicInteger(0);
-        
+
         SyncIntProcedure instanceOfProcedure = new SyncIntProcedure() {
-            
+
             @Override
-            public void run(ReadGraphImpl graph) {
-               
-                if(finishes.addAndGet(1) == 3) {
-                    if(store) addOrSet(graph, result, queryProvider);
+            public void run(ReadGraphImpl graph) throws DatabaseException {
+
+                if (finishes.addAndGet(1) == 3) {
                     procedure.execute(graph, result);
-               }
-                
+                }
+
             }
-            
+
             @Override
-            public void execute(ReadGraphImpl graph, int i) {
-                
-               synchronized(result) {
-                       result.add(i);
-               }
-                
+            public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+
+                result.add(i);
+
                 inc();
 
-                SuperTypes.queryEach(graph, i, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
+                QueryCache.runnerSuperTypes(graph, i, parent, null, new InternalProcedure<IntSet>() {
 
                     @Override
-                    public void execute(ReadGraphImpl graph, IntSet types) {
+                    public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException {
                         types.forEach(addToResult);
                         dec(graph);
                     }
-                               
-                               @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
-                                       procedure.exception(graph, t);
+
+                    @Override
+                    public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                        procedure.exception(graph, t);
                         dec(graph);
-                   }
+                    }
 
                 });
-                
+
             }
 
             @Override
-            public void finished(ReadGraphImpl graph) {
+            public void finished(ReadGraphImpl graph) throws DatabaseException {
                 dec(graph);
             }
-            
-        }; 
-        
+
+        };
+
         SyncIntProcedure inheritsProcedure = new SyncIntProcedure() {
-            
+
             @Override
-            public void run(ReadGraphImpl graph) {
+            public void run(ReadGraphImpl graph) throws DatabaseException {
 
-               int current = finishes.addAndGet(1);
-               if(current == 3) {
-                    if(store) addOrSet(graph, result, queryProvider);
+                int current = finishes.addAndGet(1);
+                if (current == 3) {
                     procedure.execute(graph, result);
-               }
-                
+                }
+
             }
-            
+
             @Override
-            public void execute(ReadGraphImpl graph, int i) {
-                
+            public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+
                 inc();
 
-                Types.queryEach(graph, i, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
+                QueryCache.runnerTypes(graph, i, parent, null, new InternalProcedure<IntSet>() {
 
                     @Override
-                    public void execute(ReadGraphImpl graph, IntSet types) {
+                    public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException {
                         types.forEach(addToResult);
                         dec(graph);
                     }
-                               
-                               @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
-                                       procedure.exception(graph, t);
+
+                    @Override
+                    public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                        procedure.exception(graph, t);
                         dec(graph);
-                   }
+                    }
 
                 });
-                
+
             }
 
             @Override
-            public void finished(ReadGraphImpl graph) {
+            public void finished(ReadGraphImpl graph) throws DatabaseException {
 
                 dec(graph);
 
             }
-            
-        }; 
+
+        };
 
         SyncIntProcedure subrelationOfProcedure = new SyncIntProcedure() {
 
             @Override
-            public void run(ReadGraphImpl graph) {
+            public void run(ReadGraphImpl graph) throws DatabaseException {
 
-               int current = finishes.addAndGet(1);
-               if(current == 3) {
-                    if(store) addOrSet(graph, result, queryProvider);
+                int current = finishes.addAndGet(1);
+                if (current == 3) {
                     procedure.execute(graph, result);
-               }
-                
+                }
+
             }
-            
+
             @Override
-            public void execute(ReadGraphImpl graph, int i) {
-                
+            public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+
                 inc();
-                
-                Types.queryEach(graph, i, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
+
+                QueryCache.runnerTypes(graph, i, parent, null, new InternalProcedure<IntSet>() {
 
                     @Override
-                    public void execute(ReadGraphImpl graph, IntSet types) {
+                    public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException {
 
                         types.forEach(addToResult);
                         dec(graph);
-                        
+
                     }
-                               
-                               @Override
-                               public void exception(ReadGraphImpl graph, Throwable t) {
-                                       procedure.exception(graph, t);
+
+                    @Override
+                    public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                        procedure.exception(graph, t);
                         dec(graph);
-                   }
+                    }
 
                 });
-                
+
             }
 
             @Override
-            public void finished(ReadGraphImpl graph) {
-                
+            public void finished(ReadGraphImpl graph) throws DatabaseException {
+
                 dec(graph);
 
             }
-            
-        }; 
-        
-        queryProvider.querySupport.getObjects(graph, id, instanceOf, instanceOfProcedure);
+
+        };
+
+        processor.querySupport.getObjects(graph, id, instanceOf, instanceOfProcedure);
         instanceOfProcedure.finished(graph);
-        queryProvider.querySupport.getObjects(graph, id, inherits, inheritsProcedure);
+        processor.querySupport.getObjects(graph, id, inherits, inheritsProcedure);
         inheritsProcedure.finished(graph);
-        queryProvider.querySupport.getObjects(graph, id, subrelationOf, subrelationOfProcedure);
+        processor.querySupport.getObjects(graph, id, subrelationOf, subrelationOfProcedure);
         subrelationOfProcedure.finished(graph);
-        
-        return result;
-        
-    }
-    
-    @Override
-    public String toString() {
-       return "Types[" + id + "]";
-    }
-    
-    private void addOrSet(ReadGraphImpl graph, final IntSet value, QueryProcessor provider) {
-       
-        assert(!isReady());
-
-        synchronized(this) {
-        
-            value.trim();
-            setResult(value);
-            setReady();
-        
-        }
-        
-    }
-    
-    @Override
-    final public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<IntSet> procedure) {
-        
-       assert(isReady());
-       
-       if(handleException(graph, procedure)) return EXCEPTED;
-       
-       IntSet result = getResult();
-       
-        procedure.execute(graph, result);
-        
-        return result;
-        
-    }
-    
-    @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-        
-        final Semaphore s = new Semaphore(0);
-
-        computeForEach(graph, provider, new InternalProcedure<IntSet>() {
-
-               @Override
-               public void execute(ReadGraphImpl graph, IntSet result) {
-                s.release();
-               }
-
-            @Override
-            public void exception(ReadGraphImpl graph, Throwable t) {
-               s.release();
-                new Error("Error in recompute.", t).printStackTrace();
-            }
-
-        }, true);
 
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
-        
     }
 
     @Override
-    boolean isImmutable(ReadGraphImpl graph) {
-       return graph.processor.isImmutable(id);
+    public String toString() {
+        return "Types[" + id + "]";
     }
-    
+
 }
index c466cb261cca975d10c16a70461eab15bb3f77b2..ec7ebeed7fad0324035280af18dc69225307c1ac 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-
-import java.util.concurrent.Semaphore;
-
 import org.simantics.databoard.util.URIStringUtils;
+import org.simantics.db.ObjectResourceIdMap;
 import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ResourceNotFoundException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.procedure.InternalProcedure;
-import org.simantics.db.procedure.ListenerBase;
 
-public class URIToResource extends StringQuery<InternalProcedure<Integer>> {
+public class URIToResource extends StringQuery<InternalProcedure<Integer>> implements InternalProcedure<Integer> {
 
-//    public ArrayList<InternalProcedure<Integer>> procs = null;
-    
-    private URIToResource(final String id) {
+    URIToResource(String id) {
         super(id);
     }
-    
-    final static URIToResource entry(final QueryProcessor provider, final String id) {
-        return (URIToResource)provider.uriToResourceMap.get(id);
-    }
-
-    final static void runner(ReadGraphImpl graph, final String id, CacheEntry parent, final ListenerBase listener, final InternalProcedure<Integer> procedure) {
-
-       QueryProcessor processor = graph.processor;
-       
-        URIToResource entry = (URIToResource)processor.uriToResourceMap.get(id); 
-        if(entry == null) {
-
-               entry = new URIToResource(id);
-               entry.setPending();
-               entry.clearResult(processor.querySupport);
-               entry.putEntry(processor);
 
-               processor.performForEach(graph, entry, parent, listener, procedure);
-            
-        } else {
-               
-            if(entry.isPending()) {
-                synchronized(entry) {
-                    if(entry.isPending()) {
-                        throw new IllegalStateException();
-//                     if(entry.procs == null) entry.procs = new ArrayList<InternalProcedure<Integer>>();
-//                        entry.procs.add(procedure);
-//                        processor.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                        return;
-                    }
-                }
-            }
-            
-            processor.performForEach(graph, entry, parent, listener, procedure);
-            
-        }
-        
-    }
-    
-    final public static void queryEach(ReadGraphImpl graph, final String id, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<Integer> procedure) {
-        
-        assert(id != null);
-        
-        if(graph.parent == null && listener == null) {
-               URIToResource.computeForEach(graph, id, null, procedure);
-        } else {
-            runner(graph, id, parent, listener, procedure);
-        }
-         
-    }
-     
-    @Override
-    public URIToResource getEntry(QueryProcessor provider) {
-        return provider.uriToResourceMap.get(id);
-    }
-    
     @Override
-    public void putEntry(QueryProcessor provider) {
-        provider.uriToResourceMap.put(id, this);
+    public final void removeEntry(QueryProcessor provider) {
+        provider.cache.remove(this);
     }
 
-    @Override
-    final public void removeEntry(QueryProcessor provider) {
-        provider.uriToResourceMap.remove(id);
+    public Object compute(ReadGraphImpl graph, final InternalProcedure<Integer> procedure) throws DatabaseException {
+        computeForEach(graph, id, this, procedure);
+        return getResult();
     }
 
-    private void lookup(ReadGraphImpl graph, final QueryProcessor processor, final InternalProcedure<Integer> procedure, final String namespace, final String name) {
-        
-        NamespaceIndex.queryEach(graph, namespace, processor, this, null, new InternalProcedure<TObjectIntHashMap<String>>() {
+    static void computeForEach(ReadGraphImpl graph, String id, final URIToResource entry, final InternalProcedure<Integer> procedure_) throws DatabaseException {
 
-            @Override
-            public void execute(ReadGraphImpl graph, TObjectIntHashMap<String> index) {
-
-                if(index != null) {
-                    int result = index.get(name);
-                    if(result != 0) {
-                        addOrSet(graph, processor, result);
-                        procedure.execute(graph, result);
-                        return;
-                    }
-                }
-                
-                addOrSet(graph, processor, new Integer(0));
-                procedure.execute(graph, new Integer(0));
-
-            }
+        InternalProcedure<Integer> procedure = entry != null ? entry : procedure_;
 
-            @Override
-            public void exception(ReadGraphImpl graph, Throwable t) {
-                except(t);
-                procedure.exception(graph, t);
-            }
+        if("http://".equals(id) || "http:/".equals(id)) {
 
-        });
+            QueryProcessor processor = graph.processor;
+            procedure.execute(graph, processor.getRootLibrary());
 
-    }
+        } else {
 
-    private static void lookup(ReadGraphImpl graph, final URIToResource entry, final InternalProcedure<Integer> procedure, final String namespace, final String name) {
-        
-        NamespaceIndex.queryEach(graph, namespace, graph.processor, entry, null, new InternalProcedure<TObjectIntHashMap<String>>() {
+            final String[] parts = URIStringUtils.splitURI(id);
+            if (parts != null) {
 
-            @Override
-            public void execute(ReadGraphImpl graph, TObjectIntHashMap<String> index) {
-
-                if(index != null) {
-                    int result = index.get(name);
-                    if(result != 0) {
-                        if(entry != null) entry.addOrSet(graph, graph.processor, result);
-                        procedure.execute(graph, result);
-                        return;
-                    }
-                }
-                
-                Integer zero = 0;
-                if(entry != null) entry.addOrSet(graph, graph.processor, zero);
-                procedure.execute(graph, zero);
+                QueryCache.runnerURIToResource(graph, parts[0], entry, null, new InternalProcedure<Integer>() {
 
-            }
+                    @Override
+                    public void execute(ReadGraphImpl graph, Integer parentId) throws DatabaseException {
 
-            @Override
-            public void exception(ReadGraphImpl graph, Throwable t) {
-                if(entry != null) entry.except(t);
-                procedure.exception(graph, t);
-            }
+                        ObjectResourceIdMap<String> map = QueryCache.resultChildMap(graph, parentId, entry, null);
+                        assert(map != null);
+                        int result = map.getId(URIStringUtils.unescape(parts[1]));
+                        if (result == 0) {
+                            ResourceNotFoundException e = new ResourceNotFoundException(id);
+                            procedure.exception(graph, e);
+                        } else {
+                            procedure.execute(graph, result);
+                        }
+                    }
 
-        });
+                    @Override
+                    public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+                        procedure.exception(graph, throwable);
+                    }
 
-    }
-    
-    @Override
-    public void computeForEach(ReadGraphImpl graph, final QueryProcessor processor, final InternalProcedure<Integer> procedure) {
-        
-//     new Exception("URIToResource " + id).printStackTrace();
-       
-        if("http://".equals(id) || "http:/".equals(id)) {
-            
-            addOrSet(graph, processor, processor.getRootLibrary());
-            procedure.execute(graph, processor.getRootLibrary());
+                });
 
-        } else {
-            
-            final String[] parts = URIStringUtils.splitURI(id);
-            if (parts != null) {
-                lookup(graph, processor, procedure, parts[0], parts[1]);
             } else {
-                lookup(graph, processor, procedure, "http://", id.replaceFirst("http://", ""));
+                ResourceNotFoundException e = new ResourceNotFoundException(id);
+                procedure.exception(graph, e);
             }
 
         }
-        
-    }
 
-    final private static void computeForEach(ReadGraphImpl graph, String id, final URIToResource entry, final InternalProcedure<Integer> procedure) {
-        
-        if("http://".equals(id) || "http:/".equals(id)) {
-            
-               QueryProcessor processor = graph.processor;
-            if(entry != null) entry.addOrSet(graph, processor, processor.getRootLibrary());
-            procedure.execute(graph, processor.getRootLibrary());
+        if(entry != null) entry.performFromCache(graph, procedure_);
 
-        } else {
-            
-            final String[] parts = URIStringUtils.splitURI(id);
-            if (parts != null) {
-                lookup(graph, entry, procedure, parts[0], parts[1]);
-            } else {
-                lookup(graph, entry, procedure, "http://", id.replaceFirst("http://", ""));
-            }
-
-        }
-        
     }
-    
-    public void addOrSet(ReadGraphImpl graph, QueryProcessor provider, Integer result) {
 
-        assert(isPending());
+    public void addOrSet(Integer result) {
 
-//        ArrayList<InternalProcedure<Integer>> p = null;
+        assert(isPending());
 
         synchronized(this) {
-
             setResult(result);
             setReady();
-//            p = procs;
-//            procs = null;
-            
         }
 
-//        if(p != null)
-//             for(InternalProcedure<Integer> proc : p) proc.execute(graph, result);
-        
     }
-    
+
     @Override
     public String toString() {
         return "URIToResource[" + id + "]";
     }
 
     @Override
-    public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<Integer> procedure) {
-        
+    public Object performFromCache(ReadGraphImpl graph, InternalProcedure<Integer> procedure) throws DatabaseException {
+
         assert(isReady());
-        
-       if(handleException(graph, procedure)) return;
-        
-        if(isExcepted()) {
-               procedure.exception(graph, (Throwable)statusOrException);
-        } else {
-            procedure.execute(graph, (Integer)getResult());
-        }
-        
+
+        if(handleException(graph, procedure)) return (Throwable)getResult();
+
+        Integer result = (Integer)getResult();
+        procedure.execute(graph, result);
+        return result;
+
     }
-    
+
     @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-        
-        final Semaphore s = new Semaphore(0);
-        
-        computeForEach(graph, provider, new InternalProcedure<Integer>() {
+    public void recompute(ReadGraphImpl graph) throws DatabaseException {
+
+        compute(graph, new InternalProcedure<Integer>() {
 
             @Override
             public void execute(ReadGraphImpl graph, Integer result) {
-                s.release();
             }
-            
+
             @Override
             public void exception(ReadGraphImpl graph, Throwable t) {
                 if(DebugException.DEBUG) new DebugException(t).printStackTrace();
@@ -260,11 +128,20 @@ public class URIToResource extends StringQuery<InternalProcedure<Integer>> {
             }
 
         });
-        
-       while(!s.tryAcquire()) {
-               provider.resume(graph);
-       }
-        
+
+    }
+
+    @Override
+    public void execute(ReadGraphImpl graph, Integer result) throws DatabaseException {
+        synchronized(this) {
+            setResult(result);
+            setReady();
+        }
     }
-       
+
+    @Override
+    public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+        except(throwable);
+    }
+
 }
index ee89bedf76f78de87234f5d83535ad2c66124cc6..26eff457dc99f29e741b53c73be2db895d4883a6 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -15,8 +15,8 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.request.RequestFlags;
 
-abstract public class UnaryQuery<Procedure> extends CacheEntryBase implements Query {
-       
+public abstract class UnaryQuery<Procedure> extends CacheEntryBase<Procedure> implements Query {
+
     final public int id;
 
     public UnaryQuery(int r) {
@@ -52,26 +52,11 @@ abstract public class UnaryQuery<Procedure> extends CacheEntryBase implements Qu
         return this;
     }
     
-    @Override
-    public void recompute(ReadGraphImpl graph, Object provider, CacheEntry entry) {
-        recompute(graph, (QueryProcessor)provider);
-    }
-    
-    @Override
-    public void performFromCache(ReadGraphImpl graph, Object provider, Object procedure) {
-        performFromCache(graph, (QueryProcessor)provider, (Procedure)procedure);
-    }
-    
-    abstract public void recompute(ReadGraphImpl graph, QueryProcessor provider);
-    abstract public Object computeForEach(ReadGraphImpl graph, QueryProcessor provider, Procedure procedure, boolean store);
-    abstract public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, Procedure procedure);
-    abstract public void putEntry(QueryProcessor provider);
     abstract public void removeEntry(QueryProcessor provider);
-    abstract public UnaryQuery<Procedure> getEntry(QueryProcessor provider);
        
-    public Object get(ReadGraphImpl graph, QueryProcessor processor, Object procedure) throws Throwable {
+    public Object get(ReadGraphImpl graph, Procedure procedure) throws Throwable {
         if(procedure != null) {
-            performFromCache(graph, processor, procedure);
+            performFromCache(graph, procedure);
         } else {
             checkAndThrow();
         }
index f259090aa690448dd9ee604f87b1eef6b49d8081..a1095fe18a05fd65d431776c57df60ae05fcd571 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -15,6 +15,7 @@ import gnu.trove.impl.hash.THash;
 
 import java.lang.reflect.Array;
 
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 
 
@@ -35,40 +36,25 @@ abstract public class UnaryQueryHash<Procedure> extends THash {
     protected final UnaryQuery<Procedure> REMOVED = new UnaryQuery<Procedure>(-1) {
 
         @Override
-        public Object computeForEach(ReadGraphImpl graph, QueryProcessor provider, Object procedure, boolean store) {
-            throw new Error("Not possible.");
-        }
-
-        @Override
-        public UnaryQuery<Procedure> getEntry(QueryProcessor provider) {
-            throw new Error("Not possible.");
-        }
-
-        @Override
-        public void putEntry(QueryProcessor provider) {
+        public void removeEntry(QueryProcessor provider) {
             throw new Error("Not possible.");
         }
 
         @Override
-        public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, Procedure procedure) {
+        public int type() {
             throw new Error("Not possible.");
         }
 
         @Override
-        public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
+        public void recompute(ReadGraphImpl graph) throws DatabaseException {
             throw new Error("Not possible.");
         }
 
         @Override
-        public void removeEntry(QueryProcessor provider) {
+        Object performFromCache(ReadGraphImpl graph, Procedure procedure) throws DatabaseException {
             throw new Error("Not possible.");
         }
 
-        @Override
-        public int type() {
-            throw new Error("Not possible.");
-        }
-        
     };
 
     /**
diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryP.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryP.java
new file mode 100644 (file)
index 0000000..cd5cd03
--- /dev/null
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.impl.query;
+
+import org.simantics.db.common.exception.DebugException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.impl.procedure.InternalProcedure;
+
+public abstract class UnaryQueryP<R> extends UnaryQuery<InternalProcedure<R>> implements InternalProcedure<R> {
+
+    public UnaryQueryP(int r) {
+        super(r);
+    }
+
+    public abstract void compute(ReadGraphImpl graph, InternalProcedure<R> procedure) throws DatabaseException;
+
+    @Override
+    public final void recompute(ReadGraphImpl graph) throws DatabaseException {
+
+        compute(graph, new InternalProcedure<R>() {
+
+            @Override
+            public void execute(ReadGraphImpl graph, R result) {
+            }
+
+            @Override
+            public void exception(ReadGraphImpl graph, Throwable t) {
+                if (DebugException.DEBUG)
+                    new DebugException(t).printStackTrace();
+                throw new Error("Error in recompute.", t);
+            }
+
+        });
+
+    }
+
+    @Override
+    public final Object performFromCache(ReadGraphImpl graph, InternalProcedure<R> procedure)
+            throws DatabaseException {
+
+        if (handleException(graph, procedure))
+            return (Throwable) statusOrException;
+
+        procedure.execute(graph, (R)getResult());
+
+        return result;
+
+    }
+
+    @Override
+    public final void execute(ReadGraphImpl graph, R result) throws DatabaseException {
+        setResult(result);
+        setReady();
+    }
+
+    @Override
+    public final void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+        except(throwable);
+    }
+
+    @Override
+    final boolean isImmutable(ReadGraphImpl graph) {
+        return graph.processor.isImmutable(id);
+    }
+
+}
index d85595831851a5b87916d0edba978d2c67acef36..ad4017f9cff863c0a2bbe42a4fb9458a655e57f2 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.impl.query;
 
-import java.util.concurrent.Semaphore;
-
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.procedure.InternalProcedure;
-import org.simantics.db.procedure.ListenerBase;
 
-final public class ValueQuery extends UnaryQuery<InternalProcedure<byte[]>> {
-    
-    private ValueQuery(final int resource) {
+public final class ValueQuery extends UnaryQueryP<byte[]> {
+
+    ValueQuery(int resource) {
         super(resource);
     }
-    
-    final static ValueQuery entry(final QueryProcessor provider, final int r) {
-        return (ValueQuery)provider.valueMap.get(r);
-    }
 
-    final static byte[] runner(final ReadGraphImpl graph, final int r, CacheEntry parent, final ListenerBase listener, final InternalProcedure<byte[]> procedure) {
-
-       QueryProcessor processor = graph.processor;
-       
-       ValueQuery entry = (ValueQuery)processor.valueMap.get(r); 
-        if(entry == null) {
-               
-               entry = new ValueQuery(r);
-               entry.setPending();
-               entry.clearResult(processor.querySupport);
-               entry.putEntry(processor);
-               
-               return (byte[])processor.performForEach(graph, entry, parent, listener, procedure);
-            
-        } else {
-               
-               return (byte[])processor.performForEach(graph, entry, parent, listener, procedure);
-            
-        }
-
-    }
-    
-    final public static byte[] queryEach(ReadGraphImpl graph, final int r, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<byte[]> procedure) {
-        
-       assert(r != 0);
-       
-       if(graph.parent == null && listener == null) {
-               return ValueQuery.computeForEach(graph, r, null, procedure);
-        } else {
-               return runner(graph, r, parent, listener, procedure);
-        }
-         
+    @Override
+    public final void removeEntry(QueryProcessor provider) {
+        provider.cache.remove(this);
     }
 
-    final public static byte[] queryEach(ReadGraphImpl graph, final int r, final CacheEntry parent) {
-        
-        assert(r != 0);
-        
-        if(graph.parent == null) {
-            return ValueQuery.computeForEach(graph, r);
-        } else {
-            return runner(graph, r, parent, null, null);
-        }
-         
+    @Override
+    public void compute(ReadGraphImpl graph, InternalProcedure<byte[]> procedure) throws DatabaseException {
+        computeForEach(graph, id, this, procedure);
     }
-    
-       @Override
-       public UnaryQuery<InternalProcedure<byte[]>> getEntry(QueryProcessor provider) {
-        return provider.valueMap.get(id);
-       }
-       
-       @Override
-       public void putEntry(QueryProcessor provider) {
-        provider.valueMap.put(id, this);
-       }
-
-       @Override
-       final public void removeEntry(QueryProcessor provider) {
-               provider.valueMap.remove(id);
-       }
-       
-               
-       public static byte[] computeForEach(ReadGraphImpl graph, final int r, final ValueQuery entry, final InternalProcedure<byte[]> procedure) {
 
-               graph.ensureLoaded(r);
-               
-               byte[] value = graph.getValue(r);
-               if(entry != null) {
-                       entry.setResult(value);
-                       entry.setReady();
-               }
-               if(procedure != null) {
-                       procedure.execute(graph, value);
-               }
-               
-               return value;
-               
-       }
+    public static byte[] computeForEach(ReadGraphImpl graph, final int r, final ValueQuery entry, final InternalProcedure<byte[]> procedure_) throws DatabaseException {
 
-    public static byte[] computeForEach(ReadGraphImpl graph, final int r) {
+        InternalProcedure<byte[]> procedure = entry != null ? entry : procedure_;
 
         graph.ensureLoaded(r);
-        
-        return graph.getValue(r);
-        
-    }
-       
-       @Override
-       public Object computeForEach(ReadGraphImpl graph, final QueryProcessor queryProvider, final InternalProcedure<byte[]> procedure, final boolean store) {
-               return computeForEach(graph, id, this, procedure);
-    }
-    
-    @Override
-    public String toString() {
-       return "Value[" + id + "]";
-    }
 
-    @Override
-    public Object performFromCache(ReadGraphImpl graph, QueryProcessor queryProvider, InternalProcedure<byte[]> procedure) {
-       return computeForEach(graph, queryProvider, procedure, false);
-    }
-    
-    @Override
-    public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
+        byte[] value = graph.getValue(r);
+        if(procedure != null) procedure.execute(graph, value);
 
-       final Semaphore s = new Semaphore(0);
-       
-        computeForEach(graph, provider, new InternalProcedure<byte[]>() {
+        if(entry != null && procedure_ != null) entry.performFromCache(graph, procedure_);
 
-            @Override
-            public void execute(ReadGraphImpl graph, byte[] result) {
-               s.release();
-            }
-                       
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               throw new Error("Error in recompute.", t);
-            }
+        return value;
 
-        }, true);
-        
-        while(!s.tryAcquire()) {
-               provider.resume(graph);
-        }
-        
     }
-    
+
     @Override
-    boolean isImmutable(ReadGraphImpl graph) {
-       return graph.processor.isImmutable(id);
-    }    
-    
+    public String toString() {
+        return "Value[" + id + "]";
+    }
+
 }
index be34bb9ba5165c9714e3e8573caed16077ccbcd6..8b29a9349b1a969c064ddf218b4837956790f872 100644 (file)
@@ -79,9 +79,7 @@ public class TGRemover extends AbstractRemover {
                         if (name != null) {
                             graph.deny(r, L0.HasName, L0.NameOf, name);
                             graph.denyValue(name);
-                            DirectStatementProcedure proc = new DirectStatementProcedure();
-                            dqs.forEachDirectPersistentStatement(graph, name, proc);
-                            for (Statement stm : proc.getOrThrow()) {
+                            for (Statement stm : dqs.getDirectPersistentStatements(graph, name)) {
                                 graph.deny(name, stm.getPredicate(), stm.getObject());
                             }
                         }
index fc32222084c0f7e08509c152a882b893e7bd5b61..4f98af7b4ab33fe4349e7bae9845fe703e728e98 100644 (file)
@@ -23,7 +23,6 @@ import java.util.UUID;
 import org.simantics.databoard.Bindings;
 import org.simantics.databoard.util.ObjectUtils;
 import org.simantics.datatypes.literal.GUID;
-import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ChangeSet;
 import org.simantics.db.ChangeSet.StatementChange;
 import org.simantics.db.MetadataI;
@@ -51,8 +50,8 @@ import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentAdditi
 import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentModification;
 import org.simantics.db.layer0.genericrelation.DependencyChanges.ComponentRemoval;
 import org.simantics.db.layer0.genericrelation.DependencyChanges.LinkChange;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncContextProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncContextProcedure;
 import org.simantics.db.service.CollectionSupport;
 import org.simantics.db.service.DirectQuerySupport;
 import org.simantics.db.service.GraphChangeListenerSupport;
@@ -95,9 +94,9 @@ public class DependenciesRelation extends UnsupportedRelation implements Generic
        class Process {
 
                final ArrayList<Entry> result = new ArrayList<Entry>();
-               final AsyncContextMultiProcedure<Resource, Resource> structure;
-               final AsyncContextProcedure<Entry, String> names;
-               final AsyncContextProcedure<Entry, Resource> type;
+               final SyncContextMultiProcedure<Resource, Resource> structure;
+               final SyncContextProcedure<Entry, String> names;
+               final SyncContextProcedure<Entry, Resource> type;
 
                Process(ReadGraph graph, final Resource resource) throws DatabaseException {
 
@@ -105,38 +104,38 @@ public class DependenciesRelation extends UnsupportedRelation implements Generic
                        final DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
                        final CollectionSupport cs = graph.getService(CollectionSupport.class);
 
-                       names = dqs.compilePossibleRelatedValue(graph, L0.HasName, new AsyncContextProcedure<Entry, String>() {
+                       names = dqs.compilePossibleRelatedValue(graph, L0.HasName, new SyncContextProcedure<Entry, String>() {
 
                                @Override
-                               public void execute(AsyncReadGraph graph, Entry entry, String name) {
+                               public void execute(ReadGraph graph, Entry entry, String name) {
                                        entry.name = name;
                                }
 
                                @Override
-                               public void exception(AsyncReadGraph graph, Throwable throwable) {
+                               public void exception(ReadGraph graph, Throwable throwable) {
                                        LOGGER.error("Could not compile possible related value for resource {}", resource, throwable);
                                }
 
                        });
 
-                       type = new AsyncContextProcedure<Entry, Resource>() {
+                       type = new SyncContextProcedure<Entry, Resource>() {
 
                                @Override
-                               public void execute(AsyncReadGraph graph, Entry entry, Resource type) {
+                               public void execute(ReadGraph graph, Entry entry, Resource type) {
                                        entry.principalType = type;
                                }
 
                                @Override
-                               public void exception(AsyncReadGraph graph, Throwable throwable) {
+                               public void exception(ReadGraph graph, Throwable throwable) {
                                        LOGGER.error("Could not find type for resource {}", resource, throwable);
                                }
 
                        };
 
-                       structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new AsyncContextMultiProcedure<Resource, Resource>() {
+                       structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new SyncContextMultiProcedure<Resource, Resource>() {
 
                                @Override
-                               public void execute(AsyncReadGraph graph, Resource parent, Resource child) {
+                               public void execute(ReadGraph graph, Resource parent, Resource child) {
                                        // WORKAROUND: don't browse virtual child resources
                                        if(!child.isPersistent()) return;
                                        Entry entry = new Entry(parent, child, "", "", "");
@@ -147,11 +146,11 @@ public class DependenciesRelation extends UnsupportedRelation implements Generic
                                }
 
                                @Override
-                               public void finished(AsyncReadGraph graph, Resource parent) {
+                               public void finished(ReadGraph graph, Resource parent) {
                                }
 
                                @Override
-                               public void exception(AsyncReadGraph graph, Throwable throwable) {
+                               public void exception(ReadGraph graph, Throwable throwable) {
                                    if (throwable instanceof NoSingleResultException) {
                                        // Ignore
                                        if (LOGGER.isDebugEnabled())
@@ -233,6 +232,7 @@ public class DependenciesRelation extends UnsupportedRelation implements Generic
 
                                ArrayList<Object[]> result = new ArrayList<Object[]>();
                                for (Entry entry : entries) {
+                                       if(entry.name == null) continue;
                                        result.add(new Object[] { ss.getRandomAccessId(entry.parent), ss.getRandomAccessId(entry.resource), entry.name, entry.types, entry.id });
                                }
                                return result;
index b090c4a7602170ea33f699e80cfe0a3770773c5d..8cf5652ce0367f31baeca31e72c0f70425657c0c 100644 (file)
@@ -29,17 +29,20 @@ class ExternalRequest extends ParametrizedPrimitiveRead<Pair<GenericRelationInde
         this.procedure = procedure;
         parameter.first.addListener(graph, parameter.second, this);
     }
-    
+
     @Override
     public void unregistered() {
-        parameter.first.removeListener(session, parameter.second, this);
+        // Session will be null if the listener was not added at all.
+        if (session != null) {
+            parameter.first.removeListener(session, parameter.second, this);
+        }
     }
-    
+
     @Override
     public void run() {
         synchronized(getClass()) {
             procedure.execute(value++);
         }
     }
-    
+
 }
\ No newline at end of file
index aebf657f1b7f4f432c523d16a9fd46c9ea5e5f0b..05ac11e62093851c5c3cc0fff70322015ef6a042 100644 (file)
@@ -16,7 +16,7 @@ import org.simantics.db.Resource;
 import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.request.ResourceMultiRead;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.layer0.Layer0;
 import org.simantics.project.ontology.ProjectResource;
 
@@ -30,7 +30,7 @@ public class NamespaceRequirements extends ResourceMultiRead<Resource> {
     }
 
     @Override
-    public void perform(ReadGraph graph, AsyncMultiProcedure<Resource> callback) throws DatabaseException {
+    public void perform(ReadGraph graph, SyncMultiProcedure<Resource> callback) throws DatabaseException {
         Layer0 L0 = Layer0.getInstance(graph);
         ProjectResource PROJ = ProjectResource.getInstance(graph);
 
index f1edc367ed7d217c5d2db004285f85e35a19702d..2394db7ed6f27a916c966f90d3c4f73d4d117698 100644 (file)
@@ -16,7 +16,7 @@ import org.simantics.db.Resource;
 import org.simantics.db.common.request.ResourceMultiRead;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.ResourceNotFoundException;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.layer0.Layer0;
 import org.simantics.project.ontology.ProjectResource;
 
@@ -29,7 +29,7 @@ public class OntologiesForModel extends ResourceMultiRead<Resource> {
         super(model);
     }
 
-    public void check(ReadGraph graph, Resource resource, AsyncMultiProcedure<Resource> callback) throws DatabaseException {
+    public void check(ReadGraph graph, Resource resource, SyncMultiProcedure<Resource> callback) throws DatabaseException {
 
         Layer0 L0 = Layer0.getInstance(graph);
         ProjectResource PROJ = ProjectResource.getInstance(graph);
@@ -51,7 +51,7 @@ public class OntologiesForModel extends ResourceMultiRead<Resource> {
     }
 
     @Override
-    public void perform(ReadGraph graph, AsyncMultiProcedure<Resource> callback) throws DatabaseException {
+    public void perform(ReadGraph graph, SyncMultiProcedure<Resource> callback) throws DatabaseException {
 
         Layer0 L0 = Layer0.getInstance(graph);
 
index bd2409f5d9b2eecde6a5f369562a141365938adb..1eea49e26d466cf582e79bdd0b0245afd9bc96cb 100644 (file)
@@ -17,9 +17,10 @@ import java.util.Map;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.ParametrizedRead;
+import org.simantics.db.common.request.ResourceRead;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.procedure.AsyncMultiProcedure;
 import org.simantics.db.procedure.Procedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.request.MultiRead;
 import org.simantics.db.request.Read;
 import org.simantics.layer0.Layer0;
@@ -41,9 +42,11 @@ public class Combinators {
                }
                @Override
                public void perform(ReadGraph graph,
-                               AsyncMultiProcedure<Resource> callback)
+                               SyncMultiProcedure<Resource> callback)
                                throws DatabaseException {
-                       graph.forEachObject(subject, relation, callback);
+                       for(Resource object : graph.getObjects(subject, relation)) {
+                               callback.execute(graph, object);
+                       }
                }               
            @Override
            public int hashCode() {
@@ -138,9 +141,7 @@ public class Combinators {
                }
                @Override
                public Resource perform(ReadGraph graph) throws DatabaseException {
-                       SynchronizationProcedure<Resource> procedure = new SynchronizationProcedure<Resource>();
-                       graph.forPossibleObject(subject, relation, procedure);
-                       return procedure.getResult();
+                       return graph.getPossibleObject(subject, relation);
                }       
            @Override
            public int hashCode() {
@@ -204,9 +205,7 @@ public class Combinators {
                }
                @Override
                public Resource perform(ReadGraph graph) throws DatabaseException {
-                       SynchronizationProcedure<Resource> procedure = new SynchronizationProcedure<Resource>();
-                       graph.forSingleObject(subject, relation, procedure);
-                       return procedure.getResult();
+                       return graph.getSingleObject(subject, relation);
                }       
            @Override
            public int hashCode() {
@@ -327,7 +326,7 @@ public class Combinators {
                        this.f = f;
                        this.g = g;
                }
-               public void perform(ReadGraph graph, final AsyncMultiProcedure<Y> callback)     throws DatabaseException {
+               public void perform(ReadGraph graph, final SyncMultiProcedure<Y> callback)      throws DatabaseException {
                    try {
                                for(X x : graph.syncRequest(g))
                                        callback.execute(graph, graph.syncRequest(f.get(x)));
@@ -410,7 +409,7 @@ public class Combinators {
                        this.g = g;
                }
                @Override
-               public void perform(ReadGraph graph, AsyncMultiProcedure<Y> callback)
+               public void perform(ReadGraph graph, SyncMultiProcedure<Y> callback)
                                throws DatabaseException {
                        graph.syncRequest(f.get(graph.syncRequest(g)), callback);
                }
@@ -469,7 +468,7 @@ public class Combinators {
                        this.f = f;
                        this.g = g;
                }
-               public void perform(ReadGraph graph, final AsyncMultiProcedure<Y> callback)     throws DatabaseException {
+               public void perform(ReadGraph graph, final SyncMultiProcedure<Y> callback)      throws DatabaseException {
                    try {
                                for(X x : graph.syncRequest(g))
                                        for(Y y : graph.syncRequest(f.get(x)))
@@ -614,7 +613,7 @@ public class Combinators {
                        this.value = value;
                }
                @Override
-               public void perform(ReadGraph graph, AsyncMultiProcedure<T> callback)
+               public void perform(ReadGraph graph, SyncMultiProcedure<T> callback)
                                throws DatabaseException {
                        callback.execute(graph, value);
                        callback.finished(graph);
@@ -640,29 +639,18 @@ public class Combinators {
        
        // ------------------------------------------------------------------------
        
-       private static class Name implements Read<String> {
-               Resource resource;
+       private static class Name extends ResourceRead<String> {
+               
                public Name(Resource resource) {
-                       this.resource = resource;
+                       super(resource);
                }
+               
                @Override
                public String perform(ReadGraph graph) throws DatabaseException {
                Layer0 L0 = Layer0.getInstance(graph);
-                       SynchronizationProcedure<String> procedure = new SynchronizationProcedure<String>();
-                       graph.forRelatedValue(resource, L0.HasName, procedure);
-                       return procedure.getResult();
+               return graph.getRelatedValue(resource, L0.HasName);
                }
-           @Override
-           public int hashCode() {
-               return getClass().hashCode() + 31 * resource.hashCode();
-           }
-               @Override
-               public boolean equals(Object obj) {
-                       if(obj == this) return true;
-                       if(obj == null || obj.getClass() != getClass()) return false;
-                       Name other = (Name)obj;
-                       return resource.equals(other.resource);
-               }               
+               
        }       
        public static Read<String> name(Resource resource) {
                return new Name(resource);
index 75c75764adb2b5668ef0e8736818cf4718cb6fa9..55fe1ac0111f008f90c3d0b816720b01ce34ce03 100644 (file)
@@ -6,7 +6,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import org.simantics.db.AsyncReadGraph;
+import org.simantics.databoard.Bindings;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.ResourceMap;
@@ -16,8 +16,7 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
 import org.simantics.db.layer0.util.TransferableGraphConfiguration2.SeedSpec;
 import org.simantics.db.layer0.util.TransferableGraphConfiguration2.SeedSpec.SeedSpecType;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.Procedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
 import org.simantics.db.service.DirectQuerySupport;
 import org.simantics.layer0.Layer0;
 import org.simantics.utils.datastructures.Pair;
@@ -26,8 +25,8 @@ class ConsistsOfProcess {
 
        final List<ConsistsOfProcessEntry> result;
        final Set<Resource> childrenWithNoName;
-       final AsyncContextMultiProcedure<ConsistsOfProcessEntry, Resource> structure;
-       final AsyncContextMultiProcedure<ConsistsOfProcessEntry, Resource> names;
+       final SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource> structure;
+       final SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource> names;
 
        public static Pair<List<ConsistsOfProcessEntry>,Set<Resource>> walk(ReadGraph graph, Collection<SeedSpec> specs, boolean ignoreVirtual) throws DatabaseException {
                return walk(graph, null, specs, ignoreVirtual);
@@ -58,44 +57,35 @@ class ConsistsOfProcess {
                
                result = new ArrayList<>();
                childrenWithNoName = new HashSet<>();
-               names = dqs.compileForEachObject(graph, L0.HasName, new AsyncContextMultiProcedure<ConsistsOfProcessEntry, Resource>() {
+               names = dqs.compileForEachObject(graph, L0.HasName, new SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource>() {
 
                        @Override
-                       public void execute(AsyncReadGraph graph, ConsistsOfProcessEntry entry, Resource nameResource) {
+                       public void execute(ReadGraph graph, ConsistsOfProcessEntry entry, Resource nameResource) throws DatabaseException {
                
                                if(status != null)
                                        status.put(nameResource, ExtentStatus.EXCLUDED);
                                
-                               graph.forPossibleValue(nameResource, new Procedure<String>() {
-
-                                       @Override
-                                       public void execute(String name) {
-                                           if(!entry.valid) return;
-                                           
-                                           if(name == null) {
-                                               entry.valid = false;
-                                           } else if (entry.name != null) {
-                                               entry.valid = false;
-                                           } else {
-                                               entry.name = name;
-                                           }
-                                       }
+                           if(!entry.valid) return;
+
+                               String name = graph.getValue(nameResource, Bindings.STRING);
+                               if(name == null) {
+                                       entry.valid = false;
+                               } else if (entry.name != null) {
+                                       entry.valid = false;
+                               } else {
+                                       entry.name = name;
+                               }
 
-                                       @Override
-                                       public void exception(Throwable t) {
-                                               Logger.defaultLogError(t);
-                                       }
-                                       
-                               });
+                               
                        }
 
                        @Override
-                       public void exception(AsyncReadGraph graph, Throwable throwable) {
+                       public void exception(ReadGraph graph, Throwable throwable) {
                                Logger.defaultLogError(throwable);
                        }
 
                        @Override
-                       public void finished(AsyncReadGraph graph, ConsistsOfProcessEntry entry) {
+                       public void finished(ReadGraph graph, ConsistsOfProcessEntry entry) {
                            if(entry.valid) {
                                if(entry.name != null) {
                                    result.add(entry);
@@ -110,10 +100,10 @@ class ConsistsOfProcess {
                        }
                });
                
-               structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new AsyncContextMultiProcedure<ConsistsOfProcessEntry, Resource>() {
+               structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource>() {
 
                        @Override
-                       public void execute(AsyncReadGraph graph, ConsistsOfProcessEntry parent, Resource child) {
+                       public void execute(ReadGraph graph, ConsistsOfProcessEntry parent, Resource child) {
 
                                if(status != null)
                                        if(ExtentStatus.EXCLUDED.equals(status.get(child))) return;
@@ -127,11 +117,11 @@ class ConsistsOfProcess {
                        }
 
                        @Override
-                       public void finished(AsyncReadGraph graph, ConsistsOfProcessEntry parent) {
+                       public void finished(ReadGraph graph, ConsistsOfProcessEntry parent) {
                        }
 
                        @Override
-                       public void exception(AsyncReadGraph graph, Throwable throwable) {
+                       public void exception(ReadGraph graph, Throwable throwable) {
                                Logger.defaultLogError(throwable);
                        }
 
index 9832f9d08be6815f2aaa6c24f6e0d64910a54e22..c5cb20af2c6d2ada95446a61cacdd3fa723747c0 100644 (file)
@@ -578,15 +578,15 @@ public class ModelTransferableGraphSourceRequest extends UniqueRead<ModelTransfe
 
                        final DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
 
-                       final DomainStatementProcedure3 proc = new DomainStatementProcedure3(result);
+//                     final DomainStatementProcedure3 proc = new DomainStatementProcedure3(result);
 
                        if (ignoreVirtual) {
                                for(Resource r : roots) {
-                                       dqs.forEachDirectPersistentStatement(graph, r, proc);
+                                       result.add(dqs.getDirectPersistentStatements(graph, r));
                                }
                        } else {
                                for(Resource r : roots) {
-                                       dqs.forEachDirectStatement(graph, r, proc);
+                                       result.add(dqs.getDirectStatements(graph, r));
                                }
                        }
                        
index 7df13315f8f68b093fdbf6cb91b0359b5bb909e1..df3b6904f3beb27060b094e6a604f57449d0ce38 100644 (file)
@@ -826,7 +826,7 @@ public final class ClusterTable implements IClusterTable {
                 System.err.println("value " + cc.getValueIndex()[i] + " changed.");
         }
     }
-    final void refreshImportance(ClusterImpl c) {
+    final synchronized void refreshImportance(ClusterImpl c) {
 
         if (c.isWriteOnly())
             return;
@@ -900,7 +900,7 @@ public final class ClusterTable implements IClusterTable {
     }
     
     @SuppressWarnings("unchecked")
-    public final <T extends ClusterI> T getClusterByResourceKey(final int resourceKey) {
+    public synchronized final <T extends ClusterI> T getClusterByResourceKey(final int resourceKey) {
         int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey);
         if (ClusterTraitsBase.isVirtualClusterKey(clusterKey))
             throw new RuntimeException("Tried to get a persistent cluster for a virtual resource.");
index f7e3a20cf4a9311e1cef6c7e3efe7b77757f5aea..5dea700c85e8733215192f6efcfa545145ebd003 100644 (file)
@@ -25,7 +25,7 @@ import org.simantics.db.impl.ForPossibleRelatedValueContextProcedure;
 import org.simantics.db.impl.ForPossibleRelatedValueProcedure;
 import org.simantics.db.impl.Table;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.procore.cluster.ClusterBig;
 import org.simantics.db.procore.cluster.ClusterImpl;
 import org.simantics.db.procore.cluster.ClusterTraits;
@@ -226,7 +226,7 @@ final public class ClusterWriteOnly extends ClusterImpl {
     }
     @Override
     public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey,
-            AsyncMultiProcedure<Resource> procedure) throws DatabaseException {
+            SyncMultiProcedure<Resource> procedure) throws DatabaseException {
         throw new DatabaseException("Not implemented.");
     }
     @Override
index c8560bad89ae1257c2f0987a722f4e0fa962b7d5..8b4df608f2eda9755f9636be2d5d79903d3d4ec1 100644 (file)
@@ -28,11 +28,8 @@ import gnu.trove.iterator.TIntIterator;
 import gnu.trove.list.array.TIntArrayList;
 import gnu.trove.map.hash.TIntIntHashMap;
 import gnu.trove.map.hash.TIntObjectHashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
 import gnu.trove.procedure.TIntObjectProcedure;
 import gnu.trove.procedure.TIntProcedure;
-import gnu.trove.procedure.TObjectIntProcedure;
-import gnu.trove.procedure.TObjectProcedure;
 import gnu.trove.set.hash.TIntHashSet;
 
 public class CollectionSupportImpl implements CollectionSupport {
@@ -117,196 +114,6 @@ public class CollectionSupportImpl implements CollectionSupport {
                return new IntResourceMap(session);
        }
 
-       static final class ObjectResourceMap<T> implements Map<T, Resource> {
-
-               final private SessionImplSocket session;
-               final private TObjectIntHashMap<T> backend;
-
-               ObjectResourceMap(SessionImplSocket session) {
-                       this.session = session;
-                       backend = new TObjectIntHashMap<T>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, 0);
-               }
-
-               ObjectResourceMap(SessionImplSocket session, int capacity) {
-                       this.session = session;
-                       backend = new TObjectIntHashMap<T>(capacity, Constants.DEFAULT_LOAD_FACTOR, 0);
-               }
-
-               @Override
-               public int size() {
-                       return backend.size();
-               }
-               @Override
-               public boolean isEmpty() {
-                       return backend.isEmpty();
-               }
-
-               @Override
-               public boolean containsKey(Object key) {
-                       return backend.contains(key);
-               }
-
-               @Override
-               public boolean containsValue(Object value) {
-                       ResourceImpl impl = (ResourceImpl) value;
-                       return backend.containsValue(impl.id);
-               }
-
-               @Override
-               public Resource get(Object key) {
-                       try {
-                               int result = backend.get(key);
-                               if (result == 0)
-                                       return null;
-                               return session.getResourceByKey(result);
-                       } catch (ResourceNotFoundException e) {
-                               e.printStackTrace();
-                       }
-                       return null;
-               }
-
-               @Override
-               public Resource put(T key, Resource value) {
-                       ResourceImpl impl = (ResourceImpl) value;
-                       int i = backend.put(key, impl.id);
-                       if (i == 0)
-                               return null;
-                       else
-                               try {
-                                       return session.getResourceByKey(i);
-                               } catch (ResourceNotFoundException e) {
-                                       e.printStackTrace();
-                               }
-                       return null;
-               }
-
-               @Override
-               public Resource remove(Object key) {
-                       throw new UnsupportedOperationException("remove not supported, structure is immutable");
-               }
-
-               @Override
-               public void putAll(Map<? extends T, ? extends Resource> map) {
-                       @SuppressWarnings("unchecked")
-                       ObjectResourceMap<T> other = (ObjectResourceMap<T>) map;
-                       other.backend.forEachEntry(new TObjectIntProcedure<T>() {
-
-                               @Override
-                               public boolean execute(T a, int b) {
-                                       backend.put(a, b);
-                                       return true;
-                               }
-                       });
-               }
-
-               @Override
-               public void clear() {
-                       throw new UnsupportedOperationException("clear not supported, structure is immutable");
-               }
-
-               @Override
-               public Set<T> keySet() {
-                       final Set<T> result = new HashSet<T>();
-                       backend.forEach(new TObjectProcedure<T>() {
-
-                               @Override
-                               public boolean execute(T object) {
-                                       result.add(object);
-                                       return true;
-                               }
-                       });
-                       return result;
-               }
-
-               @Override
-               public Collection<Resource> values() {
-                       ArrayList<Resource> result = new ArrayList<Resource>();
-                       for (int key : backend.values()) {
-                               try {
-                                       result.add(session.getResourceByKey(key));
-                               } catch (ResourceNotFoundException e) {
-                                       e.printStackTrace();
-                               }
-                       }
-                       return result;
-               }
-
-               @Override
-               public Set<java.util.Map.Entry<T, Resource>> entrySet() {
-                       final HashSet<java.util.Map.Entry<T, Resource>> result = new HashSet<java.util.Map.Entry<T, Resource>>();
-                       backend.forEachEntry(new TObjectIntProcedure<T>() {
-
-                               @Override
-                               public boolean execute(final T a, final int b) {
-                                       return result.add(new Map.Entry<T, Resource>() {
-
-                                               @Override
-                                               public T getKey() {
-                                                       return a;
-                                               }
-
-                                               @Override
-                                               public Resource getValue() {
-                                                       return new ResourceImpl(session.resourceSupport, b);
-                                               }
-
-                                               @Override
-                                               public Resource setValue(Resource value) {
-                                                       throw new UnsupportedOperationException("Map.Entry.setValue not supported, structure is immutable");
-                                               }
-
-                                       });
-                               }
-                       });
-                       return result;
-               }
-
-               @Override
-               public int hashCode() {
-                       return backend.hashCode();
-               }
-
-               @Override
-               public boolean equals(Object obj) {
-                       if (this == obj)
-                               return true;
-                       if (obj == null)
-                               return false;
-                       if (getClass() != obj.getClass()) {
-                               if (obj instanceof Map) {
-                                       // Nonoptimal fallback for comparing against generic Map
-                                       Map<?,?> m = (Map<?,?>) obj;
-                                       if (m.size() != size())
-                                               return false;
-                                       try {
-                                               Iterator<Entry<T,Resource>> i = entrySet().iterator();
-                                               while (i.hasNext()) {
-                                                       Entry<T,Resource> e = i.next();
-                                                       T key = e.getKey();
-                                                       Resource value = e.getValue();
-                                                       if (value == null) {
-                                                               if (!(m.get(key)==null && m.containsKey(key)))
-                                                                       return false;
-                                                       } else {
-                                                               if (!value.equals(m.get(key)))
-                                                                       return false;
-                                                       }
-                                               }
-                                               return true;
-                                       } catch (ClassCastException unused) {
-                                               return false;
-                                       } catch (NullPointerException unused) {
-                                               return false;
-                                       }
-                               }
-                               return false;
-                       }
-                       ObjectResourceMap<?> other = (ObjectResourceMap<?>) obj;
-                       return session == other.session && backend.equals(other.backend);
-               }
-
-       }
-
        @SuppressWarnings("unchecked")
        @Override
        public <T, I> T createObjectResourceMap(Class<I> clazz) {
index 0b640861e1d6af93255b25114c429b2f374ce54f..06c5ebfed22a0f3c3d51b727e1c0e1dc2338313a 100644 (file)
@@ -1,12 +1,9 @@
 package fi.vtt.simantics.procore.internal;
 
-import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.DirectStatements;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.RelationInfo;
 import org.simantics.db.Resource;
-import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
-import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;
 import org.simantics.db.exception.AssumptionException;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.NoSingleResultException;
@@ -19,18 +16,15 @@ import org.simantics.db.impl.ForPossibleRelatedValueProcedure;
 import org.simantics.db.impl.ResourceImpl;
 import org.simantics.db.impl.TransientGraph;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncContextProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
-import org.simantics.db.procedure.AsyncProcedure;
-import org.simantics.db.procedure.Procedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncContextProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.procedure.SyncProcedure;
 import org.simantics.db.procore.cluster.ClusterBig;
 import org.simantics.db.procore.cluster.ClusterImpl;
 import org.simantics.db.procore.cluster.ClusterSmall;
 import org.simantics.db.procore.cluster.ResourceTableSmall;
 import org.simantics.db.procore.cluster.ValueTableSmall;
-import org.simantics.db.request.AsyncRead;
 import org.simantics.db.service.DirectQuerySupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,166 +40,61 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
        }
 
        @Override
-       final public void forEachDirectPersistentStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure<DirectStatements> procedure) {
+       final public DirectStatements getDirectPersistentStatements(ReadGraph graph, final Resource subject) {
                ReadGraphImpl impl = (ReadGraphImpl)graph;
-               impl.processor.forEachDirectStatement(impl, subject, procedure, true);
+               return impl.processor.getDirectStatements(impl, subject, true);
        }
 
        @Override
-       final public void forEachDirectStatement(AsyncReadGraph graph, final Resource subject, final AsyncProcedure<DirectStatements> procedure) {
+       final public DirectStatements getDirectStatements(ReadGraph graph, final Resource subject) {
                ReadGraphImpl impl = (ReadGraphImpl)graph;
-               impl.processor.forEachDirectStatement(impl, subject, procedure, false);
+               return impl.processor.getDirectStatements(impl, subject, false);
        }
 
        @Override
-       public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, SyncProcedure<DirectStatements> procedure) {
-               forEachDirectStatement(graph, subject, new SyncToAsyncProcedure<DirectStatements>(procedure));
-       }
-
-       @Override
-       public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, Procedure<DirectStatements> procedure) {
+       public RelationInfo getRelationInfo(ReadGraph graph, Resource subject) throws DatabaseException {
                ReadGraphImpl impl = (ReadGraphImpl)graph;
-               impl.processor.forEachDirectStatement(impl, subject, procedure);
+               return impl.processor.getRelationInfo(impl, subject);
        }
 
        @Override
-       public void forRelationInfo(AsyncReadGraph graph, Resource subject, AsyncProcedure<RelationInfo> procedure) {
-               ReadGraphImpl impl = (ReadGraphImpl)graph;
-               impl.processor.forRelationInfo(impl, subject, procedure);
-       }
+       public SyncMultiProcedure<Resource> compileForEachObject(ReadGraph graph, final Resource relation, SyncMultiProcedure<Resource> user) throws DatabaseException {
 
-       @Override
-       public void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure<RelationInfo> procedure) {
-               forRelationInfo(graph, subject, new SyncToAsyncProcedure<RelationInfo>(procedure));
-       }
+               RelationInfo info = getRelationInfo(graph, relation);
+               final int predicateKey = ((ResourceImpl)relation).id;
+               return new ForEachObjectProcedure(predicateKey, info, session.queryProvider2, user);
 
-       @Override
-       public void forRelationInfo(AsyncReadGraph graph, Resource subject, Procedure<RelationInfo> procedure) {
-               forRelationInfo(graph, subject, new NoneToAsyncProcedure<RelationInfo>(procedure));
        }
 
        @Override
-       public AsyncMultiProcedure<Resource> compileForEachObject(ReadGraph graph, final Resource relation, AsyncMultiProcedure<Resource> user) {
-               
-               try {
-                       RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
+       public <C> SyncContextMultiProcedure<C, Resource> compileForEachObject(ReadGraph graph, final Resource relation, SyncContextMultiProcedure<C, Resource> user) throws DatabaseException {
 
-                               @Override
-                               public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
-                                       forRelationInfo(graph, relation, procedure);
-                               }
-
-                @Override
-                   public int threadHash() {
-                       return hashCode();
-                   }
+               RelationInfo info = getRelationInfo(graph, relation);
+               final int predicateKey = ((ResourceImpl)relation).id;
+               return new ForEachObjectContextProcedure<C>(predicateKey, info, session.queryProvider2, user);
 
-                               @Override
-                               public int getFlags() {
-                                       return 0;
-                               }
-
-                       });
-               final int predicateKey = ((ResourceImpl)relation).id;
-                       return new ForEachObjectProcedure(predicateKey, info, session.queryProvider2, user);
-               } catch (DatabaseException e) {
-                       return null;
-               }               
-        
        }
 
        @Override
-       public <C> AsyncContextMultiProcedure<C, Resource> compileForEachObject(ReadGraph graph, final Resource relation, AsyncContextMultiProcedure<C, Resource> user) {
-               
-               try {
-                       RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
-
-                               @Override
-                               public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
-                                       forRelationInfo(graph, relation, procedure);
-                               }
+       public <T> SyncProcedure<T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, SyncProcedure<T> user) throws DatabaseException {
 
-                @Override
-                   public int threadHash() {
-                       return hashCode();
-                   }
+               RelationInfo info = getRelationInfo(graph, relation);
+               final int predicateKey = ((ResourceImpl)relation).id;
+               return new ForPossibleRelatedValueProcedure<T>(predicateKey, info, user);
 
-                               @Override
-                               public int getFlags() {
-                                       return 0;
-                               }
-
-                       });
-               final int predicateKey = ((ResourceImpl)relation).id;
-                       return new ForEachObjectContextProcedure<C>(predicateKey, info, session.queryProvider2, user);
-               } catch (DatabaseException e) {
-                       return null;
-               }               
-        
-       }
-       
-       @Override
-       public <T> AsyncProcedure<T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncProcedure<T> user) {
-               
-               try {
-                       RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
-
-                               @Override
-                               public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
-                                       forRelationInfo(graph, relation, procedure);
-                               }
-
-                @Override
-                   public int threadHash() {
-                       return hashCode();
-                   }
-
-                               @Override
-                               public int getFlags() {
-                                       return 0;
-                               }
-
-                       });
-               final int predicateKey = ((ResourceImpl)relation).id;
-                       return new ForPossibleRelatedValueProcedure<T>(predicateKey, info, user);
-               } catch (DatabaseException e) {
-                       return null;
-               }               
-        
        }
 
        @Override
-       public <C, T> AsyncContextProcedure<C, T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncContextProcedure<C, T> user) {
-               
-               try {
-                       RelationInfo info = graph.syncRequest(new AsyncRead<RelationInfo>() {
+       public <C, T> SyncContextProcedure<C, T> compilePossibleRelatedValue(ReadGraph graph, final Resource relation, SyncContextProcedure<C, T> user) throws DatabaseException {
 
-                               @Override
-                               public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
-                                       forRelationInfo(graph, relation, procedure);
-                               }
-
-                @Override
-                   public int threadHash() {
-                       return hashCode();
-                   }
+               RelationInfo info = getRelationInfo(graph, relation);
+               final int predicateKey = ((ResourceImpl)relation).id;
+               return new ForPossibleRelatedValueContextProcedure<C, T>(predicateKey, info, user);
 
-                               @Override
-                               public int getFlags() {
-                                       return 0;
-                               }
-
-                       });
-               final int predicateKey = ((ResourceImpl)relation).id;
-                       return new ForPossibleRelatedValueContextProcedure<C, T>(predicateKey, info, user);
-               } catch (DatabaseException e) {
-                       return null;
-               }               
-        
        }
-       
+
        @Override
-       public void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, final AsyncMultiProcedure<Resource> procedure) {
+       public void forEachObjectCompiled(ReadGraph graph, Resource subject, final SyncMultiProcedure<Resource> procedure) {
                
         assert(subject != null);
         
@@ -261,7 +150,7 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
        }
 
        @Override
-       public <C> void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextMultiProcedure<C, Resource> procedure) {
+       public <C> void forEachObjectCompiled(ReadGraph graph, Resource subject, C context, final SyncContextMultiProcedure<C, Resource> procedure) {
                
                assert(subject != null);
 
@@ -283,9 +172,9 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
                }
                
        }
-       
+
        @Override
-       public <T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, final AsyncProcedure<T> procedure) {
+       public <T> void forPossibleRelatedValueCompiled(ReadGraph graph, Resource subject, final SyncProcedure<T> procedure) {
                
                assert(subject != null);
 
@@ -302,11 +191,24 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
         
 //        if(callerThread == suggestSchedule) {
                
-               if(info.isFunctional) {
-                       getRelatedValue4(impl, subjectId, proc);
-               } else {
-                       getRelatedValue4(impl, subjectId, proc);
+//             if(info.isFunctional) {
+        try {
+               T result = getRelatedValue4(impl, subjectId, proc);
+               try {
+                       proc.execute(graph, result);
+               } catch (DatabaseException e2) {
+                       LOGGER.error("Unexpected exception while handling related value", e2);
                }
+        } catch (DatabaseException e) {
+               try {
+                       proc.exception(graph, e);
+               } catch (DatabaseException e2) {
+                       LOGGER.error("Unexpected exception while handling related value", e2);
+               }
+        }
+//             } else {
+//                     getRelatedValue4(impl, subjectId, proc);
+//             }
                
 //        } else {
 //             
@@ -341,7 +243,7 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
        }
 
        @Override
-       public <C, T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextProcedure<C, T> procedure) {
+       public <C, T> void forPossibleRelatedValueCompiled(ReadGraph graph, Resource subject, C context, final SyncContextProcedure<C, T> procedure) {
                
                assert(subject != null);
 
@@ -356,15 +258,21 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
         
 //        impl.inc();
                
-        if(info.isFunctional) {
-               getRelatedValue4(impl, subjectId, context, proc);
-        } else {
-               getRelatedValue4(impl, subjectId, context, proc);
-        }
+//        if(info.isFunctional) {
+//        } else {
+//             getRelatedValue4(impl, subjectId, context, proc);
+//        }
+
+               try {
+                       T result = getRelatedValue4(impl, subjectId, context, proc);
+               proc.execute(graph, context, result);
+               } catch (DatabaseException e) {
+               proc.execute(graph, context, null);
+               }
                
        }
        
-       @Override
+/*     @Override
        public <T> void forPossibleType(final AsyncReadGraph graph, Resource subject, final AsyncProcedure<Resource> procedure) {
                
         assert(subject != null);
@@ -413,9 +321,11 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
        
                
        }
+       
+       */
 
        @Override
-       public <C> void forPossibleDirectType(final AsyncReadGraph graph, Resource subject, final C context, final AsyncContextProcedure<C, Resource> procedure) {
+       public <C> void forPossibleDirectType(final ReadGraph graph, Resource subject, final C context, final SyncContextProcedure<C, Resource> procedure) {
                
         assert(subject != null);
 
@@ -447,7 +357,7 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
 //                                             impl.state.dec(0);
                                                
                                        } catch (DatabaseException e) {
-                                               e.printStackTrace();
+                                               LOGGER.error("forPossibleDirectType requestCluster callback failed", e);
                                        }
                
                                        }
@@ -472,15 +382,14 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
                
         } catch (Throwable t) {
 
-               t.printStackTrace();
+               LOGGER.error("forPossibleDirectType failed unexpectedly", t);
                procedure.execute(graph, context, null);
                
         }
                
        }
        
-       
-       private <C, T> void getRelatedValue4(final ReadGraphImpl graph, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
+       private <C, T> T getRelatedValue4(final ReadGraphImpl graph, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) throws DatabaseException {
                
                int result = 0;
                
@@ -489,18 +398,14 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
                if(subject < 0) {
 
                        if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
-                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
-                                   g -> getRelatedValue4(g, subject, context, procedure)
-                               );
-                               return;
+                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, g -> {});
+                           return getRelatedValue4(graph, subject, context, procedure);
                        }
                        
                        for(TransientGraph g : session.virtualGraphServerSupport.providers) {
                 for (int id : g.getObjects(subject, predicate)) {
                        if(result != 0) {
-                               procedure.exception(graph, new DatabaseException("Multiple objects"));
-//                             graph.dec();
-                               return;
+                               throw new DatabaseException("Multiple objects");
                        } else {
                                result = id;
                        }
@@ -508,121 +413,93 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
                        }
                        
                        if(result == 0) {
-                               
-                       procedure.exception(graph, new DatabaseException("No objects for " + subject ));
-//                     graph.dec();
-                       return;
-                       
+                               throw new DatabaseException("No objects for " + subject );
                        } else {
-                               
-                               getValue4(graph, null, result, context, procedure);
-                               return;
-                               
+                               return getValue4(graph, null, result, context, procedure);
                        }
                        
                } 
                
         final org.simantics.db.procore.cluster.ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);
         if(!cluster.isLoaded()) {
-               cluster.load(session.clusterTranslator, () -> getRelatedValue4(graph, subject, context, procedure));
-               return;
+               cluster.load();
+               return getRelatedValue4(graph, subject, context, procedure);
         }
         
         if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
                        
                        if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
-                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
-                                   g -> getRelatedValue4(g, subject, context, procedure)
-                               );
-                               return;
+                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, g -> {});
+                               return getRelatedValue4(graph, subject, context, procedure);
                        }
                
                        for(TransientGraph g : session.virtualGraphServerSupport.providers) {
                 for (int id : g.getObjects(subject, predicate)) {
                        if(result != 0) {
-                               procedure.exception(graph, new DatabaseException("Multiple objects"));
-//                             graph.dec();
-                               return;
+                               throw new DatabaseException("Multiple objects");
                        } else {
                                result = id;
                        }
                 }
                        }
                        
-                       getRelatedDirectValue4(graph, cluster, subject, result, context, procedure);
+                       return getRelatedDirectValue4(graph, cluster, subject, result, context, procedure);
                        
                } else {
                        
-                       getRelatedDirectValue4(graph, cluster, subject, 0, context, procedure);
+                       return getRelatedDirectValue4(graph, cluster, subject, 0, context, procedure);
                        
                }
                
        }
        
-       private <T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
+       private <T> T getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) throws DatabaseException {
                
                Object result = null;
        
                if(subject < 0) {
 
                        if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
-                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, 
-                                   g -> getValue4(g, containerCluster, subject, procedure)
-                           );
-                               return;
+                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, g -> {});
+                           return getValue4(graph, containerCluster, subject, procedure);
                        }
                        
                        for(TransientGraph g : session.virtualGraphServerSupport.providers) {
                                Object value = g.getValue(subject);
                                if(value != null) {
                                        if(result != null) {
-                                               procedure.exception(graph, new DatabaseException("Multiple values"));
-//                                             graph.dec();
-                                               return;
+                                               throw new DatabaseException("Multiple values");
                                        } else {
                                                result = value;
                                        }
                                }
                        }
-
-                       procedure.execute(graph, (T)"name");
-//                     graph.dec();
-                       return;
-
+                       
+                       return (T)"name";
+                       
                }
                
                ClusterImpl cluster = containerCluster;
                if(!containerCluster.contains(subject)) {
                        cluster = session.clusterTable.getClusterByResourceKey(subject);
                        if(!cluster.isLoaded()) {
-                               cluster.load(session.clusterTranslator, new Runnable() {
-
-                                       @Override
-                                       public void run() {
-                                               getValue4(graph, containerCluster, subject, procedure);
-                                       }
-
-                               });
-                               return;
+                               cluster.load();
+                               return getValue4(graph, containerCluster, subject, procedure);
                        }
                }
                
         if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
 
                        if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
-                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
-                           g -> getValue4(g, containerCluster, subject, procedure)
-                           );
-                               return;
+                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, g -> {});
+                           return getValue4(graph, containerCluster, subject, procedure);
                        }
                
                        for(TransientGraph g : session.virtualGraphServerSupport.providers) {
                                Object value = g.getValue(subject);
                                if(value != null) {
                                        if(result != null) {
-                                               procedure.exception(graph, new DatabaseException("Multiple values"));
-//                                             graph.dec();
-                                               return;
+                                               throw new DatabaseException("Multiple values");
                                        } else {
                                                result = value;
                                        }
@@ -630,93 +507,72 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
                        }
                        
                        if(result != null) {
-                               
-                               procedure.execute(graph, (T)result);
-//                             graph.state.barrier.dec();
-                               
+                               return (T)result;
                        } else {
-                               
                                if(ClusterTypeEnum.SMALL == cluster.getType())
-                                       getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure);
+                                       return getDirectValue4(graph, (ClusterSmall)cluster, subject);
                                else 
-                                       getDirectValue4(graph, (ClusterBig)cluster, subject, procedure);
+                                       return getDirectValue4(graph, (ClusterBig)cluster, subject);
                        }
 
                } else {
 
                        if(ClusterTypeEnum.SMALL == cluster.getType())
-                               getDirectValue4(graph, (ClusterSmall)cluster, subject, procedure);
+                               return getDirectValue4(graph, (ClusterSmall)cluster, subject);
                        else 
-                               getDirectValue4(graph, (ClusterBig)cluster, subject, procedure);
+                               return getDirectValue4(graph, (ClusterBig)cluster, subject);
 
                }
        
        }
        
-       private <C, T> void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
+       private <C, T> T getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) throws DatabaseException {
                
                Object result = null;
        
                if(subject < 0) {
 
                        if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
-                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
-                                   g -> getValue4(g, containerCluster, subject, context, procedure)
-                           );
-                               return;
+                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, g -> {});
+                           return getValue4(graph, containerCluster, subject, context, procedure);
                        }
                        
                        for(TransientGraph g : session.virtualGraphServerSupport.providers) {
                                Object value = g.getValue(subject);
                                if(value != null) {
                                        if(result != null) {
-                                               procedure.exception(graph, new DatabaseException("Multiple values"));
-//                                             graph.dec();
-                                               return;
+                                               throw new DatabaseException("Multiple values");
                                        } else {
                                                result = value;
                                        }
                                }
                        }
 
-                       procedure.execute(graph, context, (T)"name");
-//                     graph.dec();
-                       return;
-
+                       return (T)"name";
+                       
                }
                
                ClusterImpl cluster = containerCluster;
                if(!containerCluster.contains(subject)) {
                        cluster = session.clusterTable.getClusterByResourceKey(subject);
                        if(!cluster.isLoaded()) {
-                               cluster.load(session.clusterTranslator, new Runnable() {
-
-                                       @Override
-                                       public void run() {
-                                               getValue4(graph, containerCluster, subject, context, procedure);
-                                       }
-
-                               });
-                               return;
+                               cluster.load();
+                               return getValue4(graph, containerCluster, subject, context, procedure);
                        }
                }
                
         if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
 
                        if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject)) {
-                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject,
-                                    g -> getValue4(g, containerCluster, subject, context, procedure)
-                           );
-                               return;
+                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, g -> {});
+                           return getValue4(graph, containerCluster, subject, context, procedure);
                        }
                
                        for(TransientGraph g : session.virtualGraphServerSupport.providers) {
                                Object value = g.getValue(subject);
                                if(value != null) {
                                        if(result != null) {
-                                               procedure.exception(graph, new DatabaseException("Multiple values"));
-//                                             graph.dec();
-                                               return;
+                                               throw new DatabaseException("Multiple values");
                                        } else {
                                                result = value;
                                        }
@@ -724,84 +580,64 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
                        }
                        
                        if(result != null) {
-                               
-                               procedure.execute(graph, context, (T)result);
-//                             graph.state.barrier.dec();
-                               
+                               return (T)result;
                        } else {
-                               
                                if(ClusterTypeEnum.SMALL == cluster.getType())
-                                       getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure);
+                                       return getDirectValue4(graph, (ClusterSmall)cluster, subject);
                                else 
-                                       getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure);
+                                       return getDirectValue4(graph, (ClusterBig)cluster, subject);
                        }
 
                } else {
 
                        if(ClusterTypeEnum.SMALL == cluster.getType())
-                               getDirectValue4(graph, (ClusterSmall)cluster, subject, context, procedure);
+                               return getDirectValue4(graph, (ClusterSmall)cluster, subject);
                        else 
-                               getDirectValue4(graph, (ClusterBig)cluster, subject, context, procedure);
+                               return getDirectValue4(graph, (ClusterBig)cluster, subject);
 
                }
        
        }
 
-       private <T> void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final ForPossibleRelatedValueProcedure<T> procedure) {
-
-               try {
+       private <T> T getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final ForPossibleRelatedValueProcedure<T> procedure) throws DatabaseException {
 
-                       int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);
-                       if(so == 0) {
-                               if(result == 0) {
-                                       procedure.exception(graph, new DatabaseException("No objects " + subject + " " + procedure.predicateKey));
-//                                     graph.dec();
-                               } else {
-                                       getValue4(graph, cluster, result, procedure);
-                               }
+               int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);
+               if(so == 0) {
+                       if(result == 0) {
+                               throw new DatabaseException("No objects " + subject + " " + procedure.predicateKey);
                        } else {
-                               if(result == 0) {
-                                       getValue4(graph, cluster, so, procedure);
-                               } else {
-                                       procedure.exception(graph, new DatabaseException("Multiple objects"));
-//                                     graph.dec();
-                               }
+                               return getValue4(graph, cluster, result, procedure);
+                       }
+               } else {
+                       if(result == 0) {
+                               return getValue4(graph, cluster, so, procedure);
+                       } else {
+                               throw new DatabaseException("Multiple objects");
                        }
-
-               } catch (DatabaseException e) {
-                       e.printStackTrace();
                }
-               
-       }
-
-       private <C, T> void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
 
-               try {
+       }
+       
+       private <C, T> T getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) throws DatabaseException {
 
-                       int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);
-                       if(so == 0) {
-                               if(result == 0) {
-                                       procedure.exception(graph, new NoSingleResultException("No objects " + subject + " " + procedure.predicateKey, result));
-//                                     graph.dec();
-                               } else {
-                                       getValue4(graph, cluster, result, context, procedure);
-                               }
+               int so = cluster.getSingleObject(subject, procedure, session.clusterTranslator);
+               if(so == 0) {
+                       if(result == 0) {
+                               throw new NoSingleResultException("No objects " + subject + " " + procedure.predicateKey, result);
                        } else {
-                               if(result == 0) {
-                                       getValue4(graph, cluster, so, context, procedure);
-                               } else {
-                                       procedure.exception(graph, new NoSingleResultException("Multiple objects for " + subject + " " + procedure.predicateKey, result));
-//                                     graph.dec();
-                               }
+                               return getValue4(graph, cluster, result, context, procedure);
+                       }
+               } else {
+                       if(result == 0) {
+                               return getValue4(graph, cluster, so, context, procedure);
+                       } else {
+                               throw new NoSingleResultException("Multiple objects for " + subject + " " + procedure.predicateKey, result);
                        }
-
-               } catch (DatabaseException e) {
-                       LOGGER.error("Could not compute related value for subject {} with predicate {}", subject, procedure.predicateKey);
                }
                
        }
        
-       public <T> void getRelatedValue4(final ReadGraphImpl graph, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
+       public <T> T getRelatedValue4(final ReadGraphImpl graph, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) throws DatabaseException {
                
                int result = 0;
                
@@ -810,18 +646,14 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
                if(subject < 0) {
 
                        if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
-                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
-                                   g -> getRelatedValue4(g, subject, procedure)
-                           );
-                               return;
+                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, g -> {});
+                           return getRelatedValue4(graph, subject, procedure);
                        }
                        
                        for(TransientGraph g : session.virtualGraphServerSupport.providers) {
                 for (int id : g.getObjects(subject, predicate)) {
                        if(result != 0) {
-                               procedure.exception(graph, new DatabaseException("Multiple objects"));
-//                             graph.dec();
-                               return;
+                               throw new DatabaseException("Multiple objects");
                        } else {
                                result = id;
                        }
@@ -829,64 +661,47 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
                        }
                        
                        if(result == 0) {
-                               
-                       procedure.exception(graph, new DatabaseException("No objects for " + subject ));
-//                     graph.dec();
-                       return;
-                       
+                               throw new DatabaseException("No objects for " + subject );
                        } else {
-                               
-                               getValue4(graph, null, result, procedure);
-                               return;
-                               
+                               return getValue4(graph, null, result, procedure);
                        }
                        
                } 
                
         final org.simantics.db.procore.cluster.ClusterImpl cluster = session.clusterTable.getClusterByResourceKey(subject);
         if(!cluster.isLoaded()) {
-               cluster.load(session.clusterTranslator, new Runnable() {
-
-                               @Override
-                               public void run() {
-                                       getRelatedValue4(graph, subject, procedure);
-                               }
-                       
-               });
-               return;
+               cluster.load();
+               return getRelatedValue4(graph, subject, procedure);
         }
         
         if(cluster.hasVirtual() && session.virtualGraphServerSupport.virtuals.contains(subject)) {
                        
                        if(!SessionImplSocket.areVirtualStatementsLoaded(session.virtualGraphServerSupport, subject, predicate)) {
-                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate,
-                                   g -> getRelatedValue4(graph, subject, procedure)
-                           );
-                               return;
+                           SessionImplSocket.loadVirtualStatements(session.virtualGraphServerSupport, graph, subject, predicate, g -> {});
+                           return getRelatedValue4(graph, subject, procedure);
                        }
                
                        for(TransientGraph g : session.virtualGraphServerSupport.providers) {
                 for (int id : g.getObjects(subject, predicate)) {
                        if(result != 0) {
-                               procedure.exception(graph, new DatabaseException("Multiple objects"));
-//                             graph.dec();
-                               return;
+                               throw new DatabaseException("Multiple objects");
                        } else {
                                result = id;
                        }
                 }
                        }
                        
-                       getRelatedDirectValue4(graph, cluster, subject, result, procedure);
+                       return getRelatedDirectValue4(graph, cluster, subject, result, procedure);
                        
                } else {
                        
-                       getRelatedDirectValue4(graph, cluster, subject, 0, procedure);
+                       return getRelatedDirectValue4(graph, cluster, subject, 0, procedure);
                        
                }
                
        }
-       
+
+       /*
        private <C, T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
                
                try {
@@ -900,40 +715,16 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
 //             graph.dec();
                
        }
+       */
 
-       private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
-               
-               try {
-                       byte[] bytes = cluster.getValue(subject, session.clusterTranslator);
-                       T value = (T)utf(bytes);
-                       procedure.execute(graph, value);
-               } catch (DatabaseException e) {
-                       procedure.execute(graph, null);
-               }
-
-//             graph.dec();
-               
-       }
+       private <T> T getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject) throws DatabaseException {
 
-       private <C, T> void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure<C, T> procedure) {
-               
-               try {
-                       byte[] bytes = cluster.getValue(subject, session.clusterTranslator);
-                       if(bytes == null) {
-                               procedure.execute(graph, context, null);
-                       } else {
-                               T value = (T)utf(bytes);
-                               procedure.execute(graph, context, value);
-                       }
-               } catch (DatabaseException e) {
-                       procedure.execute(graph, context, null);
-               }
+               byte[] bytes = cluster.getValue(subject, session.clusterTranslator);
+               return (T)utf(bytes);
 
-//             graph.dec();
-               
        }
-       
-       private <T> void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final ForPossibleRelatedValueProcedure<T> procedure) {
+
+       private <T> T getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject) throws DatabaseException {
 
                ResourceTableSmall rt = cluster.resourceTable;
                ValueTableSmall vt = cluster.valueTable;
@@ -941,25 +732,26 @@ public class DirectQuerySupportImpl implements DirectQuerySupport {
                byte[] bs = vt.table;
                long[] ls = rt.table;
 
-               int index = ((subject&0xFFFF) << 1) - 1 + rt.offset;
+               int index = ((subject&0xFFF) << 1) - 1 + rt.offset;
 
                int valueIndex = (int)(ls[index] >>> 24) & 0x3FFFFF + vt.offset;
 
                int size = (int)bs[valueIndex++]-1;
+               if(size <= 0) {
+                       throw new DatabaseException("No value for " + subject); 
+               }
+               
                char[] chars = new char[size];
                valueIndex++;
                for(int i=0;i<size;i++) {
                        chars[i] = (char)bs[valueIndex++];
                }
 
-               T value = (T)new String(chars);
+               return (T)new String(chars);
 
-               procedure.execute(graph, value);
-//             graph.dec();
-               
        }
 
-       final private String utf(byte[] bytes) throws AssumptionException {
+       private final String utf(byte[] bytes) throws AssumptionException {
 
                if(bytes == null) return null;
 
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
new file mode 100644 (file)
index 0000000..8b26442
--- /dev/null
@@ -0,0 +1,218 @@
+package fi.vtt.simantics.procore.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.simantics.db.ObjectResourceIdMap;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.ResourceNotFoundException;
+import org.simantics.db.impl.ResourceImpl;
+
+import gnu.trove.impl.Constants;
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.procedure.TObjectIntProcedure;
+import gnu.trove.procedure.TObjectProcedure;
+
+final class ObjectResourceMap<T> implements Map<T, Resource>, ObjectResourceIdMap<T> {
+
+       private final SessionImplSocket session;
+       private final TObjectIntHashMap<T> backend;
+
+       ObjectResourceMap(SessionImplSocket session) {
+               this.session = session;
+               backend = new TObjectIntHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, 0);
+       }
+
+       ObjectResourceMap(SessionImplSocket session, int capacity) {
+               this.session = session;
+               backend = new TObjectIntHashMap<>(capacity, Constants.DEFAULT_LOAD_FACTOR, 0);
+       }
+
+       @Override
+       public int size() {
+               return backend.size();
+       }
+       @Override
+       public boolean isEmpty() {
+               return backend.isEmpty();
+       }
+
+       @Override
+       public boolean containsKey(Object key) {
+               return backend.contains(key);
+       }
+
+       @Override
+       public boolean containsValue(Object value) {
+               ResourceImpl impl = (ResourceImpl) value;
+               return backend.containsValue(impl.id);
+       }
+
+       @Override
+       public Resource get(Object key) {
+               try {
+                       int result = backend.get(key);
+                       if (result == 0)
+                               return null;
+                       return session.getResourceByKey(result);
+               } catch (ResourceNotFoundException e) {
+                       e.printStackTrace();
+               }
+               return null;
+       }
+
+       @Override
+       public Resource put(T key, Resource value) {
+               ResourceImpl impl = (ResourceImpl) value;
+               int i = backend.put(key, impl.id);
+               if (i == 0)
+                       return null;
+               else
+                       try {
+                               return session.getResourceByKey(i);
+                       } catch (ResourceNotFoundException e) {
+                               e.printStackTrace();
+                       }
+               return null;
+       }
+
+       @Override
+       public Resource remove(Object key) {
+               throw new UnsupportedOperationException("remove not supported, structure is immutable");
+       }
+
+       @Override
+       public void putAll(Map<? extends T, ? extends Resource> map) {
+               @SuppressWarnings("unchecked")
+               ObjectResourceMap<T> other = (ObjectResourceMap<T>) map;
+               other.backend.forEachEntry(new TObjectIntProcedure<T>() {
+
+                       @Override
+                       public boolean execute(T a, int b) {
+                               backend.put(a, b);
+                               return true;
+                       }
+               });
+       }
+
+       @Override
+       public void clear() {
+               throw new UnsupportedOperationException("clear not supported, structure is immutable");
+       }
+
+       @Override
+       public Set<T> keySet() {
+               final Set<T> result = new HashSet<>();
+               backend.forEach(new TObjectProcedure<T>() {
+
+                       @Override
+                       public boolean execute(T object) {
+                               result.add(object);
+                               return true;
+                       }
+               });
+               return result;
+       }
+
+       @Override
+       public Collection<Resource> values() {
+               ArrayList<Resource> result = new ArrayList<>();
+               for (int key : backend.values()) {
+                       try {
+                               result.add(session.getResourceByKey(key));
+                       } catch (ResourceNotFoundException e) {
+                               e.printStackTrace();
+                       }
+               }
+               return result;
+       }
+
+       @Override
+       public Set<java.util.Map.Entry<T, Resource>> entrySet() {
+               final HashSet<java.util.Map.Entry<T, Resource>> result = new HashSet<>();
+               backend.forEachEntry(new TObjectIntProcedure<T>() {
+
+                       @Override
+                       public boolean execute(final T a, final int b) {
+                               return result.add(new Map.Entry<T, Resource>() {
+
+                                       @Override
+                                       public T getKey() {
+                                               return a;
+                                       }
+
+                                       @Override
+                                       public Resource getValue() {
+                                               return new ResourceImpl(session.resourceSupport, b);
+                                       }
+
+                                       @Override
+                                       public Resource setValue(Resource value) {
+                                               throw new UnsupportedOperationException("Map.Entry.setValue not supported, structure is immutable");
+                                       }
+
+                               });
+                       }
+               });
+               return result;
+       }
+
+       @Override
+       public int hashCode() {
+               return backend.hashCode();
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (getClass() != obj.getClass()) {
+                       if (obj instanceof Map) {
+                               // Nonoptimal fallback for comparing against generic Map
+                               Map<?,?> m = (Map<?,?>) obj;
+                               if (m.size() != size())
+                                       return false;
+                               try {
+                                       Iterator<Entry<T,Resource>> i = entrySet().iterator();
+                                       while (i.hasNext()) {
+                                               Entry<T,Resource> e = i.next();
+                                               T key = e.getKey();
+                                               Resource value = e.getValue();
+                                               if (value == null) {
+                                                       if (!(m.get(key)==null && m.containsKey(key)))
+                                                               return false;
+                                               } else {
+                                                       if (!value.equals(m.get(key)))
+                                                               return false;
+                                               }
+                                       }
+                                       return true;
+                               } catch (ClassCastException unused) {
+                                       return false;
+                               } catch (NullPointerException unused) {
+                                       return false;
+                               }
+                       }
+                       return false;
+               }
+               ObjectResourceMap<?> other = (ObjectResourceMap<?>) obj;
+               return session == other.session && backend.equals(other.backend);
+       }
+
+       @Override
+       public void putId(T t, int r) {
+               backend.put(t, r);
+       }
+
+       @Override
+       public int getId(T t) {
+               return backend.get(t);
+       }
+
+}
\ No newline at end of file
index d871720a8b714e51781cf7100c4f2d4b84f7b235..7165abef3547478f88dde81ba84c9cf15e7d90ef 100644 (file)
@@ -149,7 +149,7 @@ public class QueryControlImpl implements QueryControl {
        }
        
        @Override
-       public boolean resume(AsyncReadGraph graph) {
+       public boolean resume(ReadGraph graph) {
                ReadGraphImpl impl = (ReadGraphImpl)graph;
                return impl.processor.querySupport.resume(impl);
        }
index e3f73833941dcc7b7d9835c9bfd9e9079da20885..2974c90258fa87dd2a94b12a40df828f223e2e73 100644 (file)
@@ -22,7 +22,7 @@ public class QueryDebugImpl implements QueryDebug {
     @Override
     public Set<CacheEntry> getParents(AsyncRead<?> request) {
         HashSet<CacheEntry> result = new HashSet<CacheEntry>();
-        CacheEntryBase entry = session.queryProvider2.asyncReadMap.get(request);
+        CacheEntryBase<?> entry = session.queryProvider2.cache.entryAsyncRead(session.queryProvider2, request);
         if(entry != null) {
             for(CacheEntry parent : entry.getParents(session.queryProvider2)) result.add(parent);
         }
@@ -32,7 +32,7 @@ public class QueryDebugImpl implements QueryDebug {
     @Override
     public Set<CacheEntry> getParents(AsyncMultiRead<?> request) {
         HashSet<CacheEntry> result = new HashSet<CacheEntry>();
-        CacheEntryBase entry = session.queryProvider2.asyncMultiReadMap.get(request);
+        CacheEntryBase<?> entry = session.queryProvider2.cache.entryAsyncMultiRead(session.queryProvider2, request);
         if(entry != null) {
             for(CacheEntry parent : entry.getParents(session.queryProvider2)) result.add(parent);
         }
@@ -42,7 +42,7 @@ public class QueryDebugImpl implements QueryDebug {
     @Override
     public Set<CacheEntry> getParents(Read<?> request) {
         HashSet<CacheEntry> result = new HashSet<CacheEntry>();
-        CacheEntryBase entry = session.queryProvider2.readMap.get(request);
+        CacheEntryBase<?> entry = session.queryProvider2.cache.entryRead(session.queryProvider2, request);
         if(entry != null) {
             for(CacheEntry parent : entry.getParents(session.queryProvider2)) result.add(parent);
         }
@@ -52,7 +52,7 @@ public class QueryDebugImpl implements QueryDebug {
     @Override
     public Set<CacheEntry> getParents(MultiRead<?> request) {
         HashSet<CacheEntry> result = new HashSet<CacheEntry>();
-        CacheEntryBase entry = session.queryProvider2.multiReadMap.get(request);
+        CacheEntryBase<?> entry = session.queryProvider2.cache.entryMultiRead(session.queryProvider2, request);
         if(entry != null) {
             for(CacheEntry parent : entry.getParents(session.queryProvider2)) result.add(parent);
         }
index 190db364cbdf8bda86c56cc2c4f427990200c352..eea97e2e0a673c0050cf0f14f6aa1d2c99494719 100644 (file)
@@ -1,7 +1,5 @@
 package fi.vtt.simantics.procore.internal;
 
-import gnu.trove.set.hash.TIntHashSet;
-
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.Collection;
@@ -35,9 +33,14 @@ import org.simantics.db.procore.cluster.ClusterImpl;
 import org.simantics.db.procore.cluster.ClusterSmall;
 import org.simantics.db.service.SerialisationSupport;
 import org.simantics.utils.DataContainer;
+import org.slf4j.LoggerFactory;
+
+import gnu.trove.set.hash.TIntHashSet;
 
 public class QuerySupportImpl implements QuerySupport {
-       
+
+    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(QuerySupportImpl.class);
+
        final SessionImplSocket session;
        final State state;
        final ClusterTable clusterTable;
@@ -129,7 +132,8 @@ public class QuerySupportImpl implements QuerySupport {
                try {
                        return serializationSupport.getResource(id);
                } catch (DatabaseException e) {
-                       e.printStackTrace();
+                       // TODO: consider changing this method to throw something
+                       LOGGER.error("getResource(" + id + ") failed", e);
                }
                return null;
        }
@@ -212,7 +216,11 @@ public class QuerySupportImpl implements QuerySupport {
 
 //                    int suggestSchedule = graph.processor.processor.resourceThread(id);
 //                    if(graph.callerThread == suggestSchedule) {
-                       procedure.execute(graph, new ResourceImpl(resourceSupport, id));
+                       try {
+                                                       procedure.execute(graph, new ResourceImpl(resourceSupport, id));
+                                               } catch (DatabaseException e) {
+                                                       LOGGER.error("Unexpected exception while handling object", e);
+                                               }
 //                    } else {
 //                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
 //             
@@ -226,7 +234,11 @@ public class QuerySupportImpl implements QuerySupport {
                        
                 }
                        }
-                       procedure.finished(graph);
+               try {
+                       procedure.finished(graph);
+                       } catch (DatabaseException e) {
+                               LOGGER.error("Unexpected exception while handling objects", e);
+                       }
 //             graph.dec();
                return;
                
@@ -234,14 +246,12 @@ public class QuerySupportImpl implements QuerySupport {
                
         final ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
         if(!cluster.isLoaded()) {
-               cluster.load(session.clusterTranslator, new Runnable() {
-
-                               @Override
-                               public void run() {
-                                       getObjects4(graph, subject, procedure);
-                               }
-                       
-               });
+               try {
+                               cluster.load();
+                       } catch (DatabaseException e) {
+                               LOGGER.error("Unexpected exception while handling objects", e);
+                       }
+               getObjects4(graph, subject, procedure);
                return;
         }
                
@@ -249,9 +259,15 @@ public class QuerySupportImpl implements QuerySupport {
                        
                        for(TransientGraph g : virtualGraphServerSupport.providers) {
                 for (final int id : g.getObjects(subject, procedure.predicateKey)) {
+                       try {
+                       procedure.execute(graph, new ResourceImpl(resourceSupport, id));
+                               } catch (DatabaseException e) {
+                                       LOGGER.error("Unexpected exception while handling objects", e);
+                               }
+                       
+                       
 //                    int suggestSchedule = graph.processor.processor.resourceThread(id);
 //                    if(graph.callerThread == suggestSchedule) {
-                       procedure.execute(graph, new ResourceImpl(resourceSupport, id));
 //                    } else {
 //                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
 //             
@@ -292,7 +308,15 @@ public class QuerySupportImpl implements QuerySupport {
 
 //                    int suggestSchedule = graph.processor.processor.resourceThread(id);
 //                    if(graph.callerThread == suggestSchedule) {
-                       procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));
+                       
+                       try {
+                               procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));
+                               } catch (DatabaseException e) {
+                                       LOGGER.error("Unexpected exception while handling objects", e);
+                               }
+                       
+                       
+                       
 //                    } else {
 //                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
 //             
@@ -306,7 +330,14 @@ public class QuerySupportImpl implements QuerySupport {
                        
                 }
                        }
-                       procedure.finished(graph, context);
+                       
+               try {
+                       procedure.finished(graph, context);
+                       } catch (DatabaseException e) {
+                               LOGGER.error("Unexpected exception while handling objects", e);
+                       }
+
+                       
 //             graph.dec();
                return;
                
@@ -331,7 +362,11 @@ public class QuerySupportImpl implements QuerySupport {
                 for (final int id : g.getObjects(subject, procedure.predicateKey)) {
 //                    int suggestSchedule = graph.processor.processor.resourceThread(id);
 //                    if(graph.callerThread == suggestSchedule) {
-                       procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));
+                    try {
+                        procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));
+                    } catch (DatabaseException e) {
+                        LOGGER.error("Unexpected exception while handling objects", e);
+                    }
 //                    } else {
 //                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
 //             
@@ -435,178 +470,8 @@ public class QuerySupportImpl implements QuerySupport {
        
     }
 
-//     @Override
-//    public void getSingleSuperrelation(ReadGraphImpl graph, final int subject, final AsyncProcedure<Resource> procedure) {
-//     
-//     // Do not process this information for virtual resources
-//     if(subject < 0) {
-//             procedure.execute(graph, null);
-//                     graph.state.barrier.dec();
-//             return;
-//     }
-//
-//     final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
-//        if (cluster == null)
-//            System.out.println("null cluster: " + Integer.toString(subject, 16));
-//        
-//        assert (cluster != null);
-//
-//        if(!cluster.isLoaded()) {
-//            
-//             procedure.execute(graph, null);
-//                     graph.state.barrier.dec();
-//             return;
-//
-////           queryProvider2.requestCluster(callerThread, cluster.getClusterId(), new Callback<Integer>() {
-////   
-////                           @Override
-////                           public void run(Integer i) {
-////   
-////                                   queryProvider2.schedule(i, callerThread, new Runnable() {
-////   
-////                                           @Override
-////                                           public void run() {
-////                                                   
-////                                                   try  {
-////                                                   
-////                                               ClusterI.CompleteTypeEnum type = cluster.getCompleteType(callerThread, subject, SessionImplSocket.this);
-////                                               if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {
-////                                                   int result = cluster.getCompleteObjectKey(callerThread, subject, SessionImplSocket.this);
-////                                                   assert(result > 0);
-////                                                   procedure.execute(graph, getResourceByKey(result));
-////                                               } else {
-////                                                   procedure.execute(graph, null);
-////                                               }
-////                                                           graph.state.barrier.dec();
-////                                                           
-////                                                   } catch (DatabaseException e) {
-////                                                           e.printStackTrace();
-////                                                   }
-////                                                   
-////                                           }
-////   
-////                                   });
-////   
-////                           }
-////   
-////                   });
-//                     
-//        } else {
-//
-//             try {
-//
-//                     ClusterI.CompleteTypeEnum type = cluster.getCompleteType(graph.callerThread, subject, clusterSupport);
-//                     if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {
-//                             int result = cluster.getCompleteObjectKey(graph.callerThread, subject, clusterSupport);
-//                             assert(result > 0);
-//                             procedure.execute(graph, new ResourceImpl(resourceSupport, result));
-//                     } else {
-//                             procedure.execute(graph, null);
-//                     }
-//                     graph.state.barrier.dec();
-//
-//             } catch (DatabaseException e) {
-//                     e.printStackTrace();
-//             }
-//                     
-//        }
-//        
-//        
-//    }
-
-//     @Override
-//    public void getObjects2(final int callerThread, final int subject, final int predicate, final IntProcedure procedure) {
-//             ensureLoaded(callerThread, subject, predicate, new Runnable() {
-//
-//                     @Override
-//                     public void run() {
-//                             safeGetObjects2(callerThread, subject, predicate, procedure);
-//                     }
-//                     
-//             });
-//     }
-
-//    public void safeGetObjects2(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) {
-//
-//        assert (subject != 0);
-//        assert (predicate != 0);
-////        System.out.println("getObjects2: s=" + subject + "p=" + predicate);
-//        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
-//        if (providers != null) {
-//
-//            final TIntHashSet result = new TIntHashSet(16);
-//
-//            for (VirtualGraph provider : providers) {
-//
-//                for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
-//
-//                    if (result.add(id)) {
-//                     procedure.execute(graph, id);
-//                    }
-//
-//                }
-//
-//            }
-//
-//            if (subject < 0)
-//                return;
-//
-//            final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
-//
-//            assert (testCluster(subject, cluster));
-//            
-//            // wheels within wheels
-//            final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
-//
-//                @Override
-//                public boolean execute(int callerThread, Object context, int object) {
-//
-//                    if (result.add(object)) {
-//                     procedure.execute(graph.newAsync(callerThread), object);
-//                    }
-//
-//                    return false; // continue looping
-//
-//                }
-//                
-//                             @Override
-//                             public boolean found() {
-//                                     throw new UnsupportedOperationException();
-//                             }
-//                
-//            };
-//
-//            try {
-//                cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
-//            } catch (DatabaseException e) {
-//                Logger.defaultLogError(e);
-//            } catch (Throwable t) {
-//                Logger.defaultLogError(t);
-//             t.printStackTrace();
-//            }
-//            return;
-//            
-//        }
-//        
-//        assert(subject > 0);
-//
-//        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
-//
-//        assert (testCluster(subject, cluster));
-//        
-//        try {
-//            cluster.forObjects(graph.callerThread, subject, predicate, new Wheels(procedure), null, clusterSupport);
-//        } catch (DatabaseException e) {
-//            Logger.defaultLogError(e);
-//        } catch (Throwable t) {
-//             t.printStackTrace();
-//            Logger.defaultLogError(t);
-//        }
-//        
-//    }
-
        @Override
-    public boolean getObjects(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) {
+    public boolean getObjects(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) throws DatabaseException {
                
                assert (subject != 0);
                assert (predicate != 0);
@@ -656,7 +521,11 @@ public class QuerySupportImpl implements QuerySupport {
 
                                found.set(true);
                                if (result.add(object)) {
-                                       procedure.execute(graph, object);
+                                       try {
+                                                       procedure.execute(graph, object);
+                                               } catch (DatabaseException e) {
+                                                       Logger.defaultLogError(e);
+                                               }
                                }
 
                                return false; // continue looping
@@ -685,12 +554,15 @@ public class QuerySupportImpl implements QuerySupport {
                        @Override
                        public boolean execute(Object context, int object) {
 
-                               found = true;
-                               procedure.execute(graph, object);
-
-                               return false; // continue looping
+                                       found = true;
+                                       try {
+                                               procedure.execute(graph, object);
+                                       } catch (DatabaseException e) {
+                                               Logger.defaultLogError(e);
+                                       }
+                                       return false; // continue looping
 
-                       }
+                               }
 
                                public boolean found() {
                                        return found;
@@ -704,7 +576,7 @@ public class QuerySupportImpl implements QuerySupport {
                        try {
                 cluster.forObjects(subject, predicate, proc, null, clusterSupport);
                        } catch (DatabaseException e) {
-                               e.printStackTrace();
+                               Logger.defaultLogError(e);
                        } 
                        // This happens if resource is bogus
                        catch (Throwable t) {
@@ -1041,15 +913,8 @@ public class QuerySupportImpl implements QuerySupport {
 
     }
 
-//    @Override
-//    public void getStatements(ReadGraphImpl graph, final int subject, final Procedure<DirectStatements> procedure) {
-//     
-//             procedure.exception(new DatabaseException("Not supported"));
-//             
-//    }
-
     @Override
-    public void getPredicates(final ReadGraphImpl graph, final int subject, final IntProcedure procedure) {
+    public void getPredicates(final ReadGraphImpl graph, final int subject, final IntProcedure procedure) throws DatabaseException {
 
         final TIntHashSet result = new TIntHashSet(16);
 
@@ -1077,19 +942,6 @@ public class QuerySupportImpl implements QuerySupport {
         }
 
         ClusterI proxy = clusterTable.getClusterByResourceKey(subject);
-//        if(!proxy.isLoaded()) {
-//             
-//             proxy.load(callerThread, session, new Runnable() {
-//
-//                             @Override
-//                             public void run() {
-//                                     getPredicates(callerThread, subject, procedure);
-//                             }
-//                     
-//             });
-//             return;
-//             
-//        }
         assert (proxy != null);
 
         final DataContainer<Integer> got = new DataContainer<Integer>(0);
@@ -1097,7 +949,11 @@ public class QuerySupportImpl implements QuerySupport {
             @Override
             public boolean execute(Object context, int predicate, int oi) {
                 if (result.add(predicate)) {
-                    procedure.execute(graph, predicate);
+                    try {
+                        procedure.execute(graph, predicate);
+                    } catch (DatabaseException e) {
+                        Logger.defaultLogError(e);
+                    }
                 }
                 got.set(got.get() + 1);
                 return false; // continue looping
@@ -1533,7 +1389,7 @@ public class QuerySupportImpl implements QuerySupport {
                        
                } else {
                        
-                               new Exception().printStackTrace();
+                               //new Exception().printStackTrace();
                        
                        cluster.load(session.clusterTranslator, new Runnable() {
 
@@ -1583,7 +1439,7 @@ public class QuerySupportImpl implements QuerySupport {
                } else {
                        
 //                     System.err.println("cluster not loaded " + subject);
-                               new Exception().printStackTrace();
+                               //new Exception().printStackTrace();
                        
                        cluster.load(session.clusterTranslator, new Runnable() {
 
@@ -1701,7 +1557,7 @@ public class QuerySupportImpl implements QuerySupport {
                        try {
                                ((ClusterSmall)cluster).check();
                        } catch (DatabaseException e) {
-                               e.printStackTrace();
+                               LOGGER.error("ClusterSmall.check failed", e);
                        }
        
     }
index d71a8bfc81c491d52dc7afe30cae65a5e8e95d60..f5b6611b7e72b53a1ae9fbe2c40095d5dbac1e5e 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -39,6 +39,7 @@ import org.simantics.db.ExternalValueSupport;
 import org.simantics.db.Metadata;
 import org.simantics.db.MonitorContext;
 import org.simantics.db.MonitorHandler;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.ResourceSerializer;
 import org.simantics.db.Session;
@@ -52,10 +53,13 @@ import org.simantics.db.common.Indexing;
 import org.simantics.db.common.TransactionPolicyRelease;
 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
+import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter;
 import org.simantics.db.common.procedure.wrapper.NoneToAsyncListener;
 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiListener;
 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiProcedure;
 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
+import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiListener;
+import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiProcedure;
 import org.simantics.db.common.procedure.wrapper.SyncToAsyncListener;
 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiListener;
 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiProcedure;
@@ -75,6 +79,7 @@ import org.simantics.db.exception.ResourceNotFoundException;
 import org.simantics.db.exception.RuntimeDatabaseException;
 import org.simantics.db.exception.ServiceException;
 import org.simantics.db.exception.ServiceNotFoundException;
+import org.simantics.db.impl.BlockingAsyncProcedure;
 import org.simantics.db.impl.ClusterBase;
 import org.simantics.db.impl.ClusterI;
 import org.simantics.db.impl.ClusterTraitsBase;
@@ -88,7 +93,9 @@ import org.simantics.db.impl.graph.WriteGraphImpl;
 import org.simantics.db.impl.graph.WriteSupport;
 import org.simantics.db.impl.internal.RandomAccessValueSupport;
 import org.simantics.db.impl.procedure.ResultCallWrappedQueryProcedure4;
-import org.simantics.db.impl.procedure.ResultCallWrappedSingleQueryProcedure4;
+import org.simantics.db.impl.procedure.ResultCallWrappedSyncQueryProcedure;
+import org.simantics.db.impl.query.QueryCache;
+import org.simantics.db.impl.query.QueryCacheBase;
 import org.simantics.db.impl.query.QueryProcessor;
 import org.simantics.db.impl.query.QueryProcessor.SessionRead;
 import org.simantics.db.impl.query.QueryProcessor.SessionTask;
@@ -409,7 +416,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
         int thread = request.hashCode() & queryProvider2.THREAD_MASK;
 
-        requestManager.scheduleWrite(new SessionTask(request, thread, thread) {
+        requestManager.scheduleWrite(new SessionTask(true) {
 
             @Override
             public void run(int thread) {
@@ -466,7 +473,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
                     }
 
 
-                    assert(!queryProvider2.dirty);
+                    assert(!queryProvider2.cache.dirty);
 
                 } catch (Throwable e) {
 
@@ -547,7 +554,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
         int thread = request.hashCode() & queryProvider2.THREAD_MASK;
 
-        requestManager.scheduleWrite(new SessionTask(request, thread) {
+        requestManager.scheduleWrite(new SessionTask(true) {
 
             @Override
             public void run(int thread) {
@@ -633,7 +640,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
         int thread = request.hashCode() & queryProvider2.THREAD_MASK;
 
-        requestManager.scheduleWrite(new SessionTask(request, thread) {
+        requestManager.scheduleWrite(new SessionTask(true) {
 
             @Override
             public void run(int thread) {
@@ -1372,7 +1379,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
         int thread = request.hashCode() & queryProvider2.THREAD_MASK;
 
-        requestManager.scheduleWrite(new SessionTask(request, thread, thread) {
+        requestManager.scheduleWrite(new SessionTask(true) {
 
             @Override
             public void run(int thread) {
@@ -1472,7 +1479,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
         int thread = request.hashCode() & queryProvider2.THREAD_MASK;
 
-        requestManager.scheduleWrite(new SessionTask(request, thread) {
+        requestManager.scheduleWrite(new SessionTask(true) {
 
             @Override
             public void run(int thread) {
@@ -1494,9 +1501,9 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
         assert (request != null);
         assert (procedure != null);
 
-        int thread = request.hashCode() & queryProvider2.THREAD_MASK;
+        //int thread = request.hashCode() & queryProvider2.THREAD_MASK;
 
-        requestManager.scheduleRead(new SessionRead(request, throwable, notify, thread, thread) {
+        requestManager.scheduleRead(new SessionRead(throwable, notify) {
 
             @Override
             public void run(int thread) {
@@ -1512,7 +1519,8 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
                     if (listener != null) {
 
                        try {
-                               newGraph.processor.queryRead(newGraph, request, null, new AsyncProcedure<T>() {
+                               
+                               AsyncProcedure ap = new AsyncProcedure<T>() {
 
                                        @Override
                                        public void exception(AsyncReadGraph graph, Throwable t) {
@@ -1530,7 +1538,10 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
                                                procedure.execute(graph, t);
                                        }
 
-                               }, listener);
+                               };
+                               
+                               QueryCache.runnerReadEntry(newGraph, request, null, listener, ap, true);
+                               
                        } catch (Throwable t) {
                            // This is handled by the AsyncProcedure
                                //Logger.defaultLogError("Internal error", t);
@@ -1610,13 +1621,77 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
         int thread = request.hashCode() & queryProvider2.THREAD_MASK;
 
-        requestManager.scheduleRead(new SessionRead(request, null, notify, thread) {
+        requestManager.scheduleRead(new SessionRead(null, notify) {
+
+            @Override
+            public void run(int thread) {
+
+                fireSessionVariableChange(SessionVariables.QUEUED_READS);
+
+                final ReadGraphImpl newGraph = ReadGraphImpl.create(getQueryProvider2());
+
+                try {
+
+                    if (listener != null) {
+
+                        try {
+                               QueryCacheBase.resultAsyncReadEntry(newGraph, request, null, listener, procedure);
+                               //QueryCache.runnerAsyncReadEntry(newGraph, request, null, listener, procedure, true);
+                                                       //newGraph.processor.query(newGraph, request, null, procedure, listener);
+                                               } catch (DatabaseException e) {
+                                                       Logger.defaultLogError(e);
+                                               }
+
+                    } else {
+
+//                        final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
+//                                procedure, "request");
+
+                       BlockingAsyncProcedure<T> wrap = new BlockingAsyncProcedure<T>(newGraph, procedure, request);
+
+                       try {
+
+                            request.perform(newGraph, wrap);
+                            wrap.get();
+
+                        } catch (DatabaseException e) {
+
+                                                       Logger.defaultLogError(e);
+
+                        }
+
+                    }
+
+                } finally {
+
+                    fireSessionVariableChange(SessionVariables.QUEUED_READS);
+
+                }
+
+            }
+
+        });
+
+    }
+
+    public <T> void scheduleRequest(final MultiRead<T> request, final SyncMultiProcedure<T> procedure, final Semaphore notify) {
+
+        assert (request != null);
+        assert (procedure != null);
+
+        int thread = request.hashCode() & queryProvider2.THREAD_MASK;
+
+        int sync = notify != null ? thread : -1;
+
+        requestManager.scheduleRead(new SessionRead(null, notify) {
 
             @Override
             public void run(int thread) {
 
                 fireSessionVariableChange(SessionVariables.QUEUED_READS);
 
+                ListenerBase listener = getListenerBase(procedure);
+
                 final ReadGraphImpl newGraph = ReadGraphImpl.create(getQueryProvider2());
 
                 try {
@@ -1629,22 +1704,15 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
                     } else {
 
-                        final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
-                                procedure, "request");
+                        final ResultCallWrappedSyncQueryProcedure<T> wrapper = new ResultCallWrappedSyncQueryProcedure<T>(procedure);
 
                         try {
 
-//                            newGraph.state.barrier.inc();
-
                             request.perform(newGraph, wrapper);
 
-//                            newGraph.waitAsync(request);
-
                         } catch (Throwable t) {
 
-                            wrapper.exception(newGraph, t);
-//                            newGraph.waitAsync(request);
-
+                            t.printStackTrace();
 
                         }
 
@@ -1661,7 +1729,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
         });
 
     }
-
+    
     public <T> void scheduleRequest(final AsyncMultiRead<T> request, final AsyncMultiProcedure<T> procedure, final Semaphore notify) {
 
         assert (request != null);
@@ -1671,7 +1739,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
         int sync = notify != null ? thread : -1;
 
-        requestManager.scheduleRead(new SessionRead(request, null, notify, thread, sync) {
+        requestManager.scheduleRead(new SessionRead(null, notify) {
 
             @Override
             public void run(int thread) {
@@ -1725,7 +1793,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
         int thread = request.hashCode() & queryProvider2.THREAD_MASK;
 
-        requestManager.scheduleRead(new SessionRead(request, throwable, notify, thread, thread) {
+        requestManager.scheduleRead(new SessionRead(throwable, notify) {
 
             @Override
             public void run(int thread) {
@@ -1740,25 +1808,11 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
                     if (listener != null) {
 
-                        newGraph.processor.query(newGraph, request, null, new Procedure<T>() {
-
-                            @Override
-                            public void exception(Throwable t) {
-                                procedure.exception(t);
-                                if(throwable != null) {
-                                    throwable.set(t);
-                                }
-                            }
-
-                            @Override
-                            public void execute(T t) {
-                                if(result != null) result.set(t);
-                                procedure.execute(t);
-                            }
-
-                        }, listener);
-
-//                        newGraph.waitAsync(request);
+                        try {
+                            QueryCacheBase.resultExternalReadEntry(newGraph, request, null, listener, procedure);
+                        } catch (DatabaseException e) {
+                            Logger.defaultLogError(e);
+                        }
 
                     } else {
 
@@ -3048,21 +3102,21 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
         final ArrayList<T> result = new ArrayList<T>();
         final DataContainer<Throwable> exception = new DataContainer<Throwable>();
 
-        syncRequest(request, new AsyncMultiProcedure<T>() {
+        syncRequest(request, new SyncMultiProcedure<T>() {
 
             @Override
-            public void execute(AsyncReadGraph graph, T t) {
+            public void execute(ReadGraph graph, T t) {
                 synchronized(result) {
                     result.add(t);
                 }
             }
 
             @Override
-            public void finished(AsyncReadGraph graph) {
+            public void finished(ReadGraph graph) {
             }
 
             @Override
-            public void exception(AsyncReadGraph graph, Throwable t) {
+            public void exception(ReadGraph graph, Throwable t) {
                 exception.set(t);
             }
 
@@ -3080,33 +3134,27 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
     }
 
     @Override
-    public <T> Collection<T> syncRequest(MultiRead<T> request, AsyncMultiListener<T> procedure) throws DatabaseException {
+    public <T> Collection<T> syncRequest(MultiRead<T> arg0, SyncMultiProcedure<T> arg1) throws DatabaseException {
         assertNotSession();
-        return syncRequest(request, (AsyncMultiProcedure<T>)procedure);
+        throw new Error("Not implemented!");
     }
 
     @Override
     public <T> Collection<T> syncRequest(MultiRead<T> request, SyncMultiListener<T> procedure) throws DatabaseException {
         assertNotSession();
-        return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
+        return syncRequest(request, (SyncMultiProcedure<T>)procedure);
     }
 
     @Override
     public <T> Collection<T> syncRequest(MultiRead<T> request, MultiListener<T> procedure) throws DatabaseException {
         assertNotSession();
-        return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
-    }
-
-    @Override
-    public <T> Collection<T> syncRequest(MultiRead<T> request, SyncMultiProcedure<T> procedure) throws DatabaseException {
-        assertNotSession();
-        return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
+        return syncRequest(request, new NoneToSyncMultiListener<T>(procedure));
     }
 
     @Override
     public <T> Collection<T> syncRequest(MultiRead<T> request, MultiProcedure<T> procedure) throws DatabaseException {
         assertNotSession();
-        return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
+        return syncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
     }
 
     @Override
@@ -3262,38 +3310,33 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
 
         assert(request != null);
 
-        asyncRequest(request, new AsyncMultiProcedureAdapter<T>() {
+        asyncRequest(request, new SyncMultiProcedureAdapter<T>() {
             @Override
-            public void exception(AsyncReadGraph graph, Throwable t) {
+            public void exception(ReadGraph graph, Throwable t) {
                 t.printStackTrace();
             }
         });
 
     }
 
-    @Override
-    public <T> void asyncRequest(MultiRead<T> request, AsyncMultiListener<T> procedure) {
-        asyncRequest(request, (AsyncMultiProcedure<T>)procedure);
-    }
-
     @Override
     public <T> void asyncRequest(MultiRead<T> request, SyncMultiListener<T> procedure) {
-        asyncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
+        asyncRequest(request, (SyncMultiProcedure<T>)procedure);
     }
 
     @Override
     public <T> void asyncRequest(MultiRead<T> request, MultiListener<T> procedure) {
-        asyncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
+        asyncRequest(request, new NoneToSyncMultiListener<T>(procedure));
     }
 
     @Override
     public <T> void asyncRequest(MultiRead<T> request, SyncMultiProcedure<T> procedure) {
-        asyncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
+       scheduleRequest(request, procedure, null);
     }
 
     @Override
     public <T> void asyncRequest(MultiRead<T> request, MultiProcedure<T> procedure) {
-        asyncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
+        asyncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
     }
 
     @Override
@@ -3335,17 +3378,6 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
         asyncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
     }
 
-    @Override
-    public <T> Collection<T> syncRequest(MultiRead<T> arg0, AsyncMultiProcedure<T> arg1) throws DatabaseException {
-        assertNotSession();
-        throw new Error("Not implemented!");
-    }
-
-    @Override
-    public <T> void asyncRequest(MultiRead<T> arg0, AsyncMultiProcedure<T> arg1) {
-        throw new Error("Not implemented!");
-    }
-
     @Override
     final public <T> void asyncRequest(final ExternalRead<T> request) {
 
index a29d6ce045bc619ceae803dfe7bf6d48cb03241a..2902274b94202c9c79610f006f5acbf91365338b 100644 (file)
@@ -118,7 +118,7 @@ public class SessionRequestManager {
        
        public synchronized void startRead(int thread, final SessionRead task) {
                
-               session.queryProvider2.scheduleAlways(thread, new SessionTask(task.object, task.thread, task.syncCaller) {
+               session.queryProvider2.schedule(new SessionTask(true) {
 
                        @Override
             public void run(int thread) {
@@ -142,7 +142,7 @@ public class SessionRequestManager {
        
        public synchronized void startReadUpdate(int thread) {
                
-               session.queryProvider2.scheduleAlways(thread, new SessionTask(null, thread) {
+               session.queryProvider2.schedule(new SessionTask(true) {
 
                        @Override
                        public void run(int thread) {
@@ -163,7 +163,7 @@ public class SessionRequestManager {
 
        public synchronized void startWrite(int thread, final SessionTask task) {
                
-               session.queryProvider2.scheduleAlways(thread, new SessionTask((WriteTraits)task.object, task.thread) {
+               session.queryProvider2.schedule(new SessionTask(true) {
 
                        @Override
                        public void run(int thread) {
@@ -184,7 +184,7 @@ public class SessionRequestManager {
 
        public synchronized void startWriteUpdate(int thread) {
                
-               session.queryProvider2.scheduleAlways(thread, new SessionTask(null, thread) {
+               session.queryProvider2.schedule(new SessionTask(true) {
 
                        @Override
                        public void run(int thread) {
@@ -216,6 +216,9 @@ public class SessionRequestManager {
                                if(!session.state.isAlive()) return;
 
                                WriteState<?> writeState = session.writeState;
+                               
+                               assert(writeState != null);
+                               
                                WriteGraphImpl graph = writeState.getGraph();
 
                                if(writeState.isExcepted()) {
@@ -268,7 +271,7 @@ public class SessionRequestManager {
                        if (!reads.isEmpty()) {
 
                                final SessionRead read = reads.poll();
-                               session.queryProvider2.scheduleAlways(thread, new SessionTask(read.object, read.thread, read.syncCaller) {
+                               session.queryProvider2.schedule(new SessionTask(true) {
 
                                        @Override
                                        public void run(int thread) {
@@ -296,7 +299,9 @@ public class SessionRequestManager {
                        
                } else {
 
-                   throw new IllegalStateException("State in ceased should be WRITE or READ or INIT (was " + state + ")"); 
+                       // Spurious wakeup
+                       
+                   //throw new IllegalStateException("State in ceased should be WRITE or READ or INIT (was " + state + ")"); 
                        
                }
                
@@ -307,7 +312,7 @@ public class SessionRequestManager {
                assert(State.INIT != state);
                
                if(State.READ == state) {
-                       session.queryProvider2.schedule(Integer.MIN_VALUE, new SessionTask(task.object, task.thread, task.syncCaller) {
+                       session.queryProvider2.schedule(new SessionTask(true) {
 
                                @Override
                                public void run(int thread) {
@@ -349,6 +354,8 @@ public class SessionRequestManager {
 
                boolean inUpdate = state == State.WRITE_UPDATE;
 
+               //System.err.println("schedule write " + task);
+               
                assert(State.INIT != state);
                //task.combine = combine != null ? combine : inUpdate;
                if(State.IDLE == state) {
index 0f8d9706c6814d089120f71996a5ebcd10fd3b62..9a0097b114138b30c767f7c32953ff6f5903ee06 100644 (file)
@@ -44,7 +44,7 @@ public class UndoRedoSupportImpl implements UndoRedoSupport {
         final Operation fop = (Operation)ops.toArray()[0];
         final DataContainer<Long> id = new DataContainer<Long>(0L);
         final TaskHelper th = new TaskHelper("Undo");
-        session.requestManager.scheduleWrite(new SessionTask(null, 0) {
+        session.requestManager.scheduleWrite(new SessionTask(true) {
             @Override
             public void run(int thread) {
                 session.flushCounter = 0;
index 29f34b45f9904527412db0817c0dfeb6702b2c0e..4cedb79470d93a18abadb846296f04dd40041cc3 100644 (file)
@@ -31,8 +31,8 @@ import org.simantics.db.impl.Table;
 import org.simantics.db.impl.TableHeader;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.query.QueryProcessor;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.service.ClusterUID;
 
 import fi.vtt.simantics.procore.DebugPolicy;
@@ -250,7 +250,7 @@ final public class ClusterBig extends ClusterImpl {
         return objectTable.getSingleObject(objectIndex, support, this);
     }
 
-    public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure,
+    public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, SyncMultiProcedure<Resource> procedure,
             ClusterSupport support) throws DatabaseException {
         if (DEBUG)
             System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
@@ -263,7 +263,7 @@ final public class ClusterBig extends ClusterImpl {
         }
         objectTable.foreachObject(graph, objectIndex, procedure, this);
     }
-    public <C> void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, AsyncContextMultiProcedure<C, Resource> procedure,
+    public <C> void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, SyncContextMultiProcedure<C, Resource> procedure,
             ClusterSupport support) throws DatabaseException {
         if (DEBUG)
             System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
@@ -342,7 +342,7 @@ final public class ClusterBig extends ClusterImpl {
 
     @Override
     public void forObjects(ReadGraphImpl graph, int resourceKey,
-            int predicateKey, AsyncMultiProcedure<Resource> procedure)
+            int predicateKey, SyncMultiProcedure<Resource> procedure)
             throws DatabaseException {
 
         SessionImplSocket session = (SessionImplSocket)graph.getSession();
index c8309c6bf5303a2909564de1a2f29637a8a34534..6063dc8d5dde24a8026ae742d20b573553973367 100644 (file)
@@ -29,8 +29,8 @@ import org.simantics.db.impl.ForPossibleRelatedValueProcedure;
 import org.simantics.db.impl.Table;
 import org.simantics.db.impl.TableHeader;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.service.ClusterUID;
 import org.simantics.db.service.ResourceUID;
 import org.slf4j.Logger;
@@ -272,7 +272,7 @@ final public class ClusterSmall extends ClusterImpl {
         return objectTable.getSingleObject(objectIndex, support, this);
     }
 
-    public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, AsyncMultiProcedure<Resource> procedure,
+    public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, SyncMultiProcedure<Resource> procedure,
             ClusterSupport support) throws DatabaseException {
         if (deleted) return;
         if (DEBUG)
@@ -287,7 +287,7 @@ final public class ClusterSmall extends ClusterImpl {
         objectTable.foreachObject(graph, objectIndex, procedure, this);
     }
 
-    public <C> void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, C context, AsyncContextMultiProcedure<C, Resource> procedure,
+    public <C> void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, C context, SyncContextMultiProcedure<C, Resource> procedure,
             ClusterSupport support) throws DatabaseException {
         if (DEBUG)
             System.out.println("ClusterSmall.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
@@ -386,7 +386,7 @@ final public class ClusterSmall extends ClusterImpl {
 
     @Override
     public void forObjects(ReadGraphImpl graph, int resourceKey,
-            int predicateKey, AsyncMultiProcedure<Resource> procedure) throws DatabaseException {
+            int predicateKey, SyncMultiProcedure<Resource> procedure) throws DatabaseException {
         if (deleted) return;
         SessionImplSocket session = (SessionImplSocket)graph.getSession();
         ClusterSupport support = session.clusterTranslator;
@@ -908,8 +908,11 @@ final public class ClusterSmall extends ClusterImpl {
         if (ClusterTraitsSmall.resourceRefIsLocal(resourceRef)) {
             key = clusterBits | resourceRef;
         } else {
-            foreignTable.fillResourceUID(ClusterTraitsSmall.resourceRefGetForeignIndex((short)resourceRef), this);
-            key = ClusterTraitsBase.createResourceKey(clusterSupport.getClusterKeyByClusterUIDOrMake(clusterUID1, clusterUID2), executeIndex);
+            // TODO: not so nice
+            synchronized(this) {
+                foreignTable.fillResourceUID(ClusterTraitsSmall.resourceRefGetForeignIndex((short)resourceRef), this);
+                key = ClusterTraitsBase.createResourceKey(clusterSupport.getClusterKeyByClusterUIDOrMake(clusterUID1, clusterUID2), executeIndex);
+            }
         }
         if (DEBUG)
             System.out.println("ClusterSmall.execute key=" + key);
index c0ead5d073744444305acdf0247903c5f2593337..48f46bb07321267278ab761807bb2f575f1381d2 100644 (file)
@@ -18,8 +18,8 @@ import org.simantics.db.impl.IntAllocatorI;
 import org.simantics.db.impl.Modifier;
 import org.simantics.db.impl.ResourceImpl;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 
 import gnu.trove.impl.PrimeFinder;
 
@@ -208,7 +208,7 @@ public class IntHash extends IntHashTrait {
     }
 
     
-    static void foreachInt(final ReadGraphImpl graph, int[] table, int base, final AsyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {
+    static void foreachInt(final ReadGraphImpl graph, int[] table, int base, final SyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {
 
        int capacity = getRealSize(table, base);
         final int size = getUsedSize(table, base);
@@ -285,7 +285,7 @@ public class IntHash extends IntHashTrait {
         assert(size == count);
     }
 
-    static <C> void foreachInt(final ReadGraphImpl graph, int[] table, int base, C context, final AsyncContextMultiProcedure<C, Resource> procedure, Modifier modifier) throws DatabaseException {
+    static <C> void foreachInt(final ReadGraphImpl graph, int[] table, int base, C context, final SyncContextMultiProcedure<C, Resource> procedure, Modifier modifier) throws DatabaseException {
 
        int capacity = getRealSize(table, base);
        final int size = getUsedSize(table, base);
index da3b7903e7e270f2f1f6f5885ba12a3900700690..458f7b04abd2c94eba1552f4d72e07d7b93cf9cb 100644 (file)
@@ -26,8 +26,8 @@ import org.simantics.db.impl.TableFactory;
 import org.simantics.db.impl.TableIntAllocatorAdapter;
 import org.simantics.db.impl.TableSizeListener;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.procore.cluster.TableIntArraySet.Ints;
 
 import gnu.trove.map.hash.TIntIntHashMap;
@@ -146,7 +146,7 @@ public final class ObjectTable extends Table<int[]> {
     }
 
     final public void foreachObject( ReadGraphImpl graph, final int objectIndex, 
-            final AsyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {
+            final SyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {
        if (ClusterTraits.statementIndexIsDirect(objectIndex)) {
                int key = modifier.execute(objectIndex);
             procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), key));
@@ -163,7 +163,7 @@ public final class ObjectTable extends Table<int[]> {
     }
 
     final public <C> void foreachObject( ReadGraphImpl graph, final int objectIndex, C context, 
-            final AsyncContextMultiProcedure<C, Resource> procedure, Modifier modifier) throws DatabaseException {
+            final SyncContextMultiProcedure<C, Resource> procedure, Modifier modifier) throws DatabaseException {
        if (ClusterTraits.statementIndexIsDirect(objectIndex)) {
                int key = modifier.execute(objectIndex);
             procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), key));
index 90519a36c3f6cb5916c7429c5af8e8ca41414deb..d7f6abc49a39642279b30d20fb050bd7420c1954 100644 (file)
@@ -9,8 +9,8 @@ import org.simantics.db.impl.ClusterTraitsBase;
 import org.simantics.db.impl.Modifier;
 import org.simantics.db.impl.ResourceImpl;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 
 
 public final class ResourceElementSmall {
@@ -394,7 +394,7 @@ public final class ResourceElementSmall {
     }
 
     public static void foreachObject(long[] table, int index,
-            final ReadGraphImpl graph, final AsyncMultiProcedure<Resource> procedure,
+            final ReadGraphImpl graph, final SyncMultiProcedure<Resource> procedure,
             ClusterSupport support, final int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier)
     throws DatabaseException {
         if (DEBUG)
@@ -469,7 +469,7 @@ public final class ResourceElementSmall {
     }
     
     public static <C> void foreachObject(long[] table, int index,
-            final ReadGraphImpl graph, final C context, final AsyncContextMultiProcedure<C, Resource> procedure,
+            final ReadGraphImpl graph, final C context, final SyncContextMultiProcedure<C, Resource> procedure,
             ClusterSupport support, final int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier)
     throws DatabaseException {
         if (DEBUG)
index e997b731870159486a38cfebab9a2b7eb64f7c36..d0619976d4775421d4bd5b915d4dbe23b6063081 100644 (file)
@@ -33,7 +33,8 @@ import org.simantics.db.impl.TableFactory;
 import org.simantics.db.impl.TableSizeListener;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.procore.cluster.PredicateTable.Status;
 
 
@@ -413,7 +414,7 @@ final class ResourceElement {
     }
     
     public static void foreachObject(long[] table, int index,
-               final ReadGraphImpl graph, final AsyncMultiProcedure<Resource> procedure,
+               final ReadGraphImpl graph, final SyncMultiProcedure<Resource> procedure,
                final ClusterSupport support, final int pRef, final ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier)
     throws DatabaseException {
         if (DEBUG)
@@ -506,7 +507,7 @@ final class ResourceElement {
     }
 
     public static <C> void foreachObject(long[] table, int index,
-               final ReadGraphImpl graph, final C context, final AsyncContextMultiProcedure<C, Resource> procedure,
+               final ReadGraphImpl graph, final C context, final SyncContextMultiProcedure<C, Resource> procedure,
                final ClusterSupport support, final int pRef, final ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier)
     throws DatabaseException {
         if (DEBUG)
@@ -1021,14 +1022,14 @@ public final class ResourceTable extends Table<long[]> {
     }
 
     public void foreachObject(int resourceIndex, ReadGraphImpl graph,
-               AsyncMultiProcedure<Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) throws DatabaseException {
+               SyncMultiProcedure<Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) throws DatabaseException {
         int realIndex = checkIndexAndGetRealIndex(resourceIndex);
         ResourceElement.foreachObject(table, realIndex, graph, procedure, support,
                        pRef, pCompleteType, ct, modifier);
     }
 
     public <C> void foreachObject(int resourceIndex, ReadGraphImpl graph, C context,
-               AsyncContextMultiProcedure<C, Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) throws DatabaseException {
+               SyncContextMultiProcedure<C, Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) throws DatabaseException {
         int realIndex = checkIndexAndGetRealIndex(resourceIndex);
         ResourceElement.foreachObject(table, realIndex, graph, context, procedure, support,
                        pRef, pCompleteType, ct, modifier);
index d72b79aa567d5d582e23e90f132c9c45edee7599..0278b15312540dd42d88bf580056e3e1c3a748c9 100644 (file)
@@ -28,8 +28,8 @@ import org.simantics.db.impl.Table;
 import org.simantics.db.impl.TableFactory;
 import org.simantics.db.impl.TableSizeListener;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.procore.cluster.PredicateTable.Status;
 
 
@@ -201,14 +201,14 @@ public final class ResourceTableSmall extends Table<long[]> {
     }
 
     public void foreachObject(int resourceIndex, ReadGraphImpl graph,
-            AsyncMultiProcedure<Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException {
+            SyncMultiProcedure<Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException {
         int realIndex = checkIndexAndGetRealIndex(resourceIndex);
         ResourceElementSmall.foreachObject(table, realIndex, graph, procedure, support,
                 pRef, completeType, ct, modifier);
     }
 
     public <C> void foreachObject(int resourceIndex, ReadGraphImpl graph, C context,
-            AsyncContextMultiProcedure<C, Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException {
+            SyncContextMultiProcedure<C, Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException {
         int realIndex = checkIndexAndGetRealIndex(resourceIndex);
         ResourceElementSmall.foreachObject(table, realIndex, graph, context, procedure, support,
                 pRef, completeType, ct, modifier);
index 2c57f3627323ebdfcb88d050df524c32fd09fcf3..c0ba6ec61a0344e3abce91d05611231490a64605 100644 (file)
@@ -18,8 +18,8 @@ import org.simantics.db.impl.IntAllocatorI;
 import org.simantics.db.impl.Modifier;
 import org.simantics.db.impl.ResourceImpl;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 
 final class TableIntArraySet {
     public static final int HeaderSize = 1; 
@@ -151,7 +151,7 @@ final class TableIntArraySet {
         return size + HeaderSize;
     }
     
-    static void foreachInt(final int[] table, final int base, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {
+    static void foreachInt(final int[] table, final int base, ReadGraphImpl graph, SyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {
        
         final int size = -table[base + SIZE_OFFSET];
         assert(size>0);
@@ -170,7 +170,7 @@ final class TableIntArraySet {
         
     }
 
-    static <C> void foreachInt(final int[] table, final int base, ReadGraphImpl graph, C context, AsyncContextMultiProcedure<C, Resource> procedure, Modifier modifier) throws DatabaseException {
+    static <C> void foreachInt(final int[] table, final int base, ReadGraphImpl graph, C context, SyncContextMultiProcedure<C, Resource> procedure, Modifier modifier) throws DatabaseException {
        
         final int size = -table[base + SIZE_OFFSET];
         assert(size>0);
index f13042faa0a39ecdc21f5fa532c6f958d55ad707..a0e0eb14bb813de23b83ecb43362571ddd0c1898 100644 (file)
@@ -18,7 +18,7 @@ import org.simantics.db.impl.IntAllocatorI;
 import org.simantics.db.impl.Modifier;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.query.QueryProcessor;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 
 final class TableIntSet {
     public static final int HeaderSize = IntHash.HeaderSize;
@@ -57,7 +57,7 @@ final class TableIntSet {
         return IntHash.getAllocatedSize(table, base);
     }
     
-    static void foreachInt(int[] table, int base, QueryProcessor processor, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {
+    static void foreachInt(int[] table, int base, QueryProcessor processor, ReadGraphImpl graph, SyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {
         IntHash.foreachInt(graph, table, base, procedure, modifier);
     }
 
index 47a14ddbcbccc7424bec9fe1ea059c588dffc24d..879eec03410e3737d4b2e8561e8110d184dca843 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.db.services.adaption;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectObjectProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.adaption.Adapter;
 import org.simantics.db.adaption.AdaptionService;
 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
-import org.simantics.db.common.procedure.single.SyncReadProcedure;
 import org.simantics.db.common.request.BinaryRead;
 import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.common.request.TernaryRead;
@@ -37,6 +32,10 @@ import org.simantics.db.request.Read;
 import org.simantics.layer0.Layer0;
 import org.simantics.utils.datastructures.Pair;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
 public class AdaptionService2 implements AdaptionService {
 
     THashMap<Pair<Class<?>,Class<?>>, AdapterDeclaration<?>> adapters =
@@ -366,24 +365,9 @@ public class AdaptionService2 implements AdaptionService {
 
                 final Adapter<T,C> adapter = (Adapter<T, C>)findAdapter(resource, g);
                 if(adapter == null) return null;
-                else return g.syncRequest(new AsyncRead<T>() {
-
-                    @Override
-                    public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
-//                      System.out.println("adapter=" + adapter);
-                        adapter.adapt(graph, resource, context, procedure);
-                    }
-
-                    @Override
-                           public int threadHash() {
-                               return hashCode();
-                           }
-
-                    @Override
-                    public int getFlags() {
-                        return 0;
-                    }
-
+                else return g.syncRequest((AsyncRead<T>)(graph, procedure) -> {
+                    //System.out.println("adapter=" + adapter);
+                    adapter.adapt(graph, resource, context, procedure);
                 });
 
             }
@@ -583,11 +567,9 @@ public class AdaptionService2 implements AdaptionService {
     public <T, C> T adapt(ReadGraph g, Resource r, C context, Class<C> contextClass, Class<T> targetClass, boolean possible) throws DatabaseException {
 
        Adapter<T,C> adapter = getAdapter(g, r, context, contextClass, targetClass, possible);
+       if(adapter == null) return null;
        
-               SyncReadProcedure<T> procedure = new SyncReadProcedure<T>();
-       adapter.adapt(g, r, context, procedure);
-               procedure.checkAndThrow();
-               return procedure.result;
+       return g.syncRequest((AsyncRead<T>)(graph, procedure) -> adapter.adapt(graph, r, context, procedure));
        
     }
     
@@ -865,23 +847,23 @@ public class AdaptionService2 implements AdaptionService {
 
                 if(decl == null) {
                     if(possible) {
-                        procedure.execute(graph, null);
+                        procedure.execute(g, null);
                     } else {
-                        procedure.exception(graph, new AdaptionException("There are no adapters declared or defined for class " + clazz + "."));
+                        procedure.exception(g, new AdaptionException("There are no adapters declared or defined for class " + clazz + "."));
                     }
                 } else {
                     try {
-                        procedure.execute(graph, decl.adaptNew(graph, r, possible));
+                        procedure.execute(g, decl.adaptNew(graph, r, possible));
                     } catch (AdaptionException e) {
                         if(possible) {
-                            procedure.execute(graph, null);
+                            procedure.execute(g, null);
                         } else {
-                            procedure.exception(graph, e);
+                            procedure.exception(g, e);
                         }
                     } catch (ValidationException e) {
-                        procedure.exception(graph, e);
+                        procedure.exception(g, e);
                     } catch (DatabaseException e2) {
-                        procedure.exception(graph, new ServiceException(e2));
+                        procedure.exception(g, new ServiceException(e2));
                     }
                 }
 
index bfef0a95ac823adbc455a495a9471461222fa485..e281a02944a4b50a3578afb3641d98b5379ab3c0 100644 (file)
@@ -41,7 +41,7 @@ public abstract class AbstractReflectionAdapter<T> implements Adapter<T,Resource
                     Object[] args = new Object[parameters.length];
                     for(int i=0;i<parameters.length;++i)
                         args[i] = parameters[i].adapt(graph, r);
-                    construct(graph, procedure, args);
+                    construct(g, procedure, args);
                 }
                 
             });
index 251cb764296ca486421cd51a4f300056f4a8ab69..ed750f538f615140b893d3ece55f3711d670226d 100644 (file)
@@ -88,24 +88,24 @@ public class ReflectionAdapter2<T> implements Adapter<T, Resource> {
                     try {
                        for(int i=0;i<parameters.length;++i)
                                args[i] = parameters[i].adapt(graph, r);
-                       procedure.execute(graph, constructor.newInstance(args));
+                       procedure.execute(g, constructor.newInstance(args));
                                } catch (IllegalArgumentException e) {
-                                   procedure.exception(graph, e);
+                                   procedure.exception(g, e);
                                        e.printStackTrace();
                                } catch (InstantiationException e) {
-                        procedure.exception(graph, e);
+                        procedure.exception(g, e);
                                        e.printStackTrace();
                                } catch (IllegalAccessException e) {
-                        procedure.exception(graph, e);
+                        procedure.exception(g, e);
                                        e.printStackTrace();
                                } catch (InvocationTargetException e) {
-                        procedure.exception(graph, e.getCause());
+                        procedure.exception(g, e.getCause());
                                        e.getCause().printStackTrace();
                                } catch (DatabaseException e) {
-                        procedure.exception(graph, e);
+                        procedure.exception(g, e);
                                        e.printStackTrace();
                                } catch (Throwable t) {
-                                   procedure.exception(graph, t);
+                                   procedure.exception(g, t);
                                    t.printStackTrace();
                                }
                 }
index 574ab95f6ab7a09b876ba7098a5f4027f0a05156..1068fc2f50366ae19a72f8a3029534b86f2c7993 100644 (file)
@@ -20,6 +20,7 @@ import org.eclipse.core.runtime.Platform;
 import org.junit.After;
 import org.junit.Before;
 import org.simantics.SimanticsPlatform;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
@@ -30,6 +31,8 @@ import org.simantics.db.common.utils.Logger;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.ServiceNotFoundException;
 import org.simantics.db.management.SessionContext;
+import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.request.AsyncRead;
 import org.simantics.db.request.Read;
 import org.simantics.db.service.LifecycleSupport;
 import org.simantics.db.testing.impl.Configuration;
@@ -145,9 +148,46 @@ abstract public class TestBase /*extends TestCase*/ {
 
     }
 
+    protected abstract class AsyncReadQuery<Result> implements AsyncRead<Result> {
+        protected Result result = null;
+
+        public abstract void run(AsyncReadGraph graph) throws Throwable;
+
+        @Override
+        public void perform(AsyncReadGraph graph, AsyncProcedure<Result> procedure) {
+            try {
+                run(graph);
+            } catch(Throwable t) {
+                if (DEBUG) {
+                    new Exception().printStackTrace();
+                    t.printStackTrace();
+                }
+                if (null == exception2)
+                    exception2 = t;
+            }
+        }
+
+    }
+
     protected abstract class TestReadRequest extends ReadQuery<Object> {
     }
 
+    protected abstract class TestAsyncReadRequest extends AsyncReadQuery<Object> {
+
+               @Override
+               public int getFlags() {
+                       // TODO Auto-generated method stub
+                       return 0;
+               }
+
+               @Override
+               public int threadHash() {
+                       // TODO Auto-generated method stub
+                       return 0;
+               }
+
+    }
+
     protected abstract class WriteOnlyQuery
     extends WriteOnlyRequest
     {
index 088c10daa645c05b832ae4d6d0a1ffc895352f14..97f489f8bf6474020ef86339e152d8c21bfa8843 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -55,7 +55,7 @@ import org.simantics.db.request.Read;
  * @see Resource
  * @see Statement
  */
-public interface AsyncReadGraph extends AsyncRequestProcessor {
+public interface AsyncReadGraph extends ReadGraph, AsyncRequestProcessor {
 
     /**
      * @see ReadGraph#getURI(Resource)
@@ -355,15 +355,15 @@ public interface AsyncReadGraph extends AsyncRequestProcessor {
     /**
      * @see ReadGraph#getObjects(Resource, Resource)
      */
-    void forEachDirectPredicate(Resource subject, AsyncMultiProcedure<Resource> procedure);
+    void forEachDirectPredicate(Resource subject, AsyncProcedure<Set<Resource>> procedure);
     /**
      * @see ReadGraph#getObjects(Resource, Resource)
      */
-    void forEachDirectPredicate(Resource subject, SyncMultiProcedure<Resource> procedure);
+    void forEachDirectPredicate(Resource subject, SyncProcedure<Set<Resource>> procedure);
     /**
      * @see ReadGraph#getObjects(Resource, Resource)
      */
-    void forEachDirectPredicate(Resource subject, MultiProcedure<Resource> procedure);
+    void forEachDirectPredicate(Resource subject, Procedure<Set<Resource>> procedure);
 
     /**
      * @see ReadGraph#getObjects(Resource, Resource)
@@ -1129,10 +1129,9 @@ public interface AsyncReadGraph extends AsyncRequestProcessor {
      */
     void forOrderedSet(Resource subject, MultiProcedure<Resource> procedure);
 
-    int thread();
 //    void inc();
 //    void dec();
     
-    boolean isImmutable(Resource resource) throws DatabaseException;
+    boolean performPending();
     
 }
index 3f17927e223693752142a51645fdf7565412765a..ded8292faab41b102d8ef09484975ee620f077fd 100644 (file)
@@ -64,14 +64,7 @@ import org.simantics.db.request.WriteOnly;
  * @see MergingGraphRequestProcessor
  * @see RequestProcessor
  */
-public interface AsyncRequestProcessor extends ServiceLocator, AsyncRequestProcessorSpecific {
-
-       Resource getRootLibrary();
-       
-    /**
-     * @return the {@link Session} for which this processor is based on.
-     */
-    Session getSession();
+public interface AsyncRequestProcessor extends RequestProcessor, AsyncRequestProcessorSpecific {
     
     <T> void async(ReadInterface<T> r, Procedure<T> procedure);
     <T> void async(ReadInterface<T> r, AsyncProcedure<T> procedure);
@@ -80,9 +73,4 @@ public interface AsyncRequestProcessor extends ServiceLocator, AsyncRequestProce
     <T> void async(ReadInterface<T> r, AsyncListener<T> procedure);
     <T> void async(ReadInterface<T> r, SyncListener<T> procedure);
     
-    <T> void async(WriteInterface<T> r);
-    <T> void async(WriteInterface<T> r, Procedure<T> procedure);
-    
-    Object getModificationCounter();
-    
 }
index 429696cda867a078c72ade8baef22733b2786be5..254174917cea5ebb7affb46069f94a6401645df1 100644 (file)
@@ -289,7 +289,7 @@ public interface AsyncRequestProcessorSpecific extends ServiceLocator {
      * @param request an instance of {@link MultiRead}.
      * @param procedure an instance of {@link AsyncMultiListener}.
      */
-    <T> void asyncRequest(MultiRead<T> request, AsyncMultiListener<T> procedure);
+    //<T> void asyncRequest(MultiRead<T> request, AsyncMultiListener<T> procedure);
 
     /**
      * Asynchronously registers the given {@link SyncMultiListener} (as
@@ -329,7 +329,7 @@ public interface AsyncRequestProcessorSpecific extends ServiceLocator {
      * @param request an instance of {@link MultiRead}.
      * @param procedure an instance of {@link AsyncMultiProcedure}.
      */
-    <T> void asyncRequest(MultiRead<T> request, AsyncMultiProcedure<T> procedure);
+    //<T> void asyncRequest(MultiRead<T> request, AsyncMultiProcedure<T> procedure);
 
     /**
      * Asynchronously supplies the result determined from the given
@@ -463,65 +463,5 @@ public interface AsyncRequestProcessorSpecific extends ServiceLocator {
     <T> void asyncRequest(ExternalRead<T> request, Listener<T> procedure);
     <T> void asyncRequest(ExternalRead<T> request, Procedure<T> procedure);
     
-    /**
-     * Asynchronously performs the given {@link Write}. The outcome of the
-     * request will be lost.
-     * 
-     * @param request an instance of {@link Write}.
-     */
-    void asyncRequest(Write request);
-
-    /**
-     * Asynchronously performs the given {@link Write}. The outcome of the
-     * request will be reported to given {@link Consumer} in the form of a
-     * DatabaseException raised during request processing or null upon success.
-     * 
-     * @param request an instance of {@link Write}.
-     * @param request an instance of {@link Consumer}.
-     */
-    void asyncRequest(Write request, Consumer<DatabaseException> callback);
-    
-    <T> void asyncRequest(WriteResult<T> r, Procedure<T> procedure);
-    
-
-    /**
-     * Asynchronously performs the given {@link WriteOnly}. The outcome of the
-     * request will be lost.
-     * 
-     * @param request an instance of {@link Write}.
-     */
-    void asyncRequest(DelayedWrite request);
-
-    /**
-     * Asynchronously performs the given {@link WriteOnly}. The outcome of the
-     * request will be reported to given {@link Consumer} in the form of a
-     * DatabaseException raised during request processing or null upon success.
-     * 
-     * @param request an instance of {@link WriteOnly}.
-     * @param request an instance of {@link Consumer}.
-     */
-    void asyncRequest(DelayedWrite request, Consumer<DatabaseException> callback);
-
-    <T> void asyncRequest(DelayedWriteResult<T> r, Procedure<T> procedure);
-
-    /**
-     * Asynchronously performs the given {@link WriteOnly}. The outcome of the
-     * request will be lost.
-     * 
-     * @param request an instance of {@link Write}.
-     */
-    void asyncRequest(WriteOnly r);
-
-    /**
-     * Asynchronously performs the given {@link WriteOnly}. The outcome of the
-     * request will be reported to given {@link Consumer} in the form of a
-     * DatabaseException raised during request processing or null upon success.
-     * 
-     * @param request an instance of {@link WriteOnly}.
-     * @param request an instance of {@link Consumer}.
-     */
-    void asyncRequest(WriteOnly r, Consumer<DatabaseException> callback);
-    
-    <T> void asyncRequest(WriteOnlyResult<T> r, Procedure<T> procedure);
     
 }
diff --git a/bundles/org.simantics.db/src/org/simantics/db/ObjectResourceIdMap.java b/bundles/org.simantics.db/src/org/simantics/db/ObjectResourceIdMap.java
new file mode 100644 (file)
index 0000000..7585bdf
--- /dev/null
@@ -0,0 +1,10 @@
+package org.simantics.db;
+
+import java.util.Map;
+
+public interface ObjectResourceIdMap<T> extends Map<T, Resource> {
+
+       void putId(T t, int r);
+       int getId(T t);
+
+}
index bead66644ff103a67c6a3ad4db713457f068c2fd..36081c3a802276bd8ec81f7a974b9b9617d90958 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -12,6 +12,7 @@
 package org.simantics.db;
 
 import java.util.Collection;
+import java.util.Map;
 import java.util.Set;
 
 import org.simantics.databoard.accessor.Accessor;
@@ -36,7 +37,6 @@ import org.simantics.db.procedure.SyncMultiListener;
 import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.procedure.SyncProcedure;
 import org.simantics.db.procedure.SyncSetListener;
-import org.simantics.db.request.MultiRead;
 import org.simantics.db.request.Read;
 import org.simantics.scl.compiler.types.Type;
 
@@ -67,7 +67,7 @@ import org.simantics.scl.compiler.types.Type;
  * @see Statement
  * @noimplement
  */
-public interface ReadGraph extends AsyncReadGraph, RequestProcessor {
+public interface ReadGraph extends RequestProcessor {
 
     /**
      * 
@@ -108,6 +108,18 @@ public interface ReadGraph extends AsyncReadGraph, RequestProcessor {
      */
     Resource getPossibleResource(String uri) throws ResourceNotFoundException, ValidationException, ServiceException;
 
+    /**
+     * Computes a map of objects related to resource with L0.ConsistsOf that also contain a L0.HasName property
+     * 
+     * @param resource the resource
+     * @return the children
+     * @throws ValidationException if a resource could not be produced due to
+     *         invalid semantics
+     * @throws ServiceException on connection and database failures
+     * @see AsyncReadGraph#forResourceByURI
+     */
+    Map<String,Resource> getChildren(Resource resource) throws ValidationException, ServiceException;
+
     /**
      * Gets a builtin resource. For a list of builtin resources see TODO Wiki
      * 
@@ -1071,4 +1083,9 @@ public interface ReadGraph extends AsyncReadGraph, RequestProcessor {
     
     boolean setSynchronous(boolean value);
     boolean getSynchronous();
+
+    boolean isImmutable(Resource resource) throws DatabaseException;
+
+    int thread();
+
 }
index 68af4664b856442d0b1c7e38ed27d17cb5f74293..5e818cb995c32408a9f04377c0b0885767d95513 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -12,6 +12,7 @@
 package org.simantics.db;
 
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.Procedure;
 import org.simantics.db.request.ReadInterface;
 import org.simantics.db.request.WriteInterface;
 
@@ -61,9 +62,21 @@ import org.simantics.db.request.WriteInterface;
  * @see MergingGraphRequestProcessor
  * @see AsyncRequestProcessor
  */
-public interface RequestProcessor extends AsyncRequestProcessor, RequestProcessorSpecific {
+public interface RequestProcessor extends RequestProcessorSpecific, ServiceLocator {
+
+    Resource getRootLibrary();
+
+    /**
+     * @return the {@link Session} for which this processor is based on.
+     */
+    Session getSession();
 
     <T> T sync(ReadInterface<T> r) throws DatabaseException;
     <T> T sync(WriteInterface<T> r) throws DatabaseException;
-    
+
+    <T> void async(WriteInterface<T> r);
+    <T> void async(WriteInterface<T> r, Procedure<T> procedure);
+
+    Object getModificationCounter();
+
 }
index 523d410137a1341bec5e5b3e23f554a338b5c019..b121c0829be16e422439bf69425eea38c6a4f1b6 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -12,6 +12,7 @@
 package org.simantics.db;
 
 import java.util.Collection;
+import java.util.function.Consumer;
 
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.AsyncListener;
@@ -82,7 +83,7 @@ import org.simantics.db.request.WriteResult;
  * @see MergingGraphRequestProcessor
  * @see AsyncRequestProcessor
  */
-public interface RequestProcessorSpecific extends AsyncRequestProcessor {
+public interface RequestProcessorSpecific {
 
     /**
      * Synchronously determines and returns the result of the given {@link Read}
@@ -288,7 +289,7 @@ public interface RequestProcessorSpecific extends AsyncRequestProcessor {
      * @param request an instance of {@link MultiRead}.
      * @param procedure an instance of {@link AsyncMultiListener}.
      */
-    <T> Collection<T> syncRequest(MultiRead<T> request, AsyncMultiListener<T> procedure) throws DatabaseException;
+    //<T> Collection<T> syncRequest(MultiRead<T> request, AsyncMultiListener<T> procedure) throws DatabaseException;
 
     /**
      * Synchronously registers the given {@link SyncMultiListener} (as
@@ -328,7 +329,7 @@ public interface RequestProcessorSpecific extends AsyncRequestProcessor {
      * @param request an instance of {@link MultiRead}.
      * @param procedure an instance of {@link AsyncMultiProcedure}.
      */
-    <T> Collection<T> syncRequest(MultiRead<T> request, AsyncMultiProcedure<T> procedure) throws DatabaseException;
+    //<T> Collection<T> syncRequest(MultiRead<T> request, AsyncMultiProcedure<T> procedure) throws DatabaseException;
 
     /**
      * Synchronously supplies the result determined from the given
@@ -496,5 +497,66 @@ public interface RequestProcessorSpecific extends AsyncRequestProcessor {
      * @param request an instance of {@link Write}.
      */
     <T> T syncRequest(WriteOnlyResult<T> r) throws DatabaseException;
-    
+
+    /**
+     * Asynchronously performs the given {@link Write}. The outcome of the
+     * request will be lost.
+     * 
+     * @param request an instance of {@link Write}.
+     */
+    void asyncRequest(Write request);
+
+    /**
+     * Asynchronously performs the given {@link Write}. The outcome of the
+     * request will be reported to given {@link Consumer} in the form of a
+     * DatabaseException raised during request processing or null upon success.
+     * 
+     * @param request an instance of {@link Write}.
+     * @param request an instance of {@link Consumer}.
+     */
+    void asyncRequest(Write request, Consumer<DatabaseException> callback);
+
+    <T> void asyncRequest(WriteResult<T> r, Procedure<T> procedure);
+
+
+    /**
+     * Asynchronously performs the given {@link WriteOnly}. The outcome of the
+     * request will be lost.
+     * 
+     * @param request an instance of {@link Write}.
+     */
+    void asyncRequest(DelayedWrite request);
+
+    /**
+     * Asynchronously performs the given {@link WriteOnly}. The outcome of the
+     * request will be reported to given {@link Consumer} in the form of a
+     * DatabaseException raised during request processing or null upon success.
+     * 
+     * @param request an instance of {@link WriteOnly}.
+     * @param request an instance of {@link Consumer}.
+     */
+    void asyncRequest(DelayedWrite request, Consumer<DatabaseException> callback);
+
+    <T> void asyncRequest(DelayedWriteResult<T> r, Procedure<T> procedure);
+
+    /**
+     * Asynchronously performs the given {@link WriteOnly}. The outcome of the
+     * request will be lost.
+     * 
+     * @param request an instance of {@link Write}.
+     */
+    void asyncRequest(WriteOnly r);
+
+    /**
+     * Asynchronously performs the given {@link WriteOnly}. The outcome of the
+     * request will be reported to given {@link Consumer} in the form of a
+     * DatabaseException raised during request processing or null upon success.
+     * 
+     * @param request an instance of {@link WriteOnly}.
+     * @param request an instance of {@link Consumer}.
+     */
+    void asyncRequest(WriteOnly r, Consumer<DatabaseException> callback);
+
+    <T> void asyncRequest(WriteOnlyResult<T> r, Procedure<T> procedure);
+
 }
index 8e8b2d9bc7149121c46e87c9c4633b972f606c98..22a747b7ff0836ec83c293cd281891c40e07f9e1 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -23,7 +23,7 @@ package org.simantics.db;
  * @see SessionManager
  * @see Session
  */
-public interface Session extends RequestProcessor {    
+public interface Session extends AsyncRequestProcessor {
     /**
      * Marks the current database state or the beginning of the current ongoing
      * write transaction as an undo point. Calling this method several times
diff --git a/bundles/org.simantics.db/src/org/simantics/db/procedure/SyncContextMultiProcedure.java b/bundles/org.simantics.db/src/org/simantics/db/procedure/SyncContextMultiProcedure.java
new file mode 100644 (file)
index 0000000..cdbfc2a
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2018 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:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.procedure;
+
+import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.exception.DatabaseException;
+
+/**
+ * @author Antti Villberg
+ * 
+ * First execute is called k times. After this finished or exception is called exactly once.
+ *
+ * @param <Result> the result object type accepted by the procedure
+ */
+public interface SyncContextMultiProcedure<Context, Result> {
+
+    /**
+     * Invoked once for each separate result of the request with potentially
+     * multiple results. It shall be guaranteed that all <code>execute</code>
+     * invocations have been completed when either
+     * {@link #finished(AsyncReadGraph)} or
+     * {@link #exception(AsyncReadGraph, Throwable)} are called and that no
+     * <code>execute</code> invocations will follow afterwards.
+     * 
+     * @param graph asynchronous graph access
+     * @param result a single result of the multiresult procedure
+     */
+    void execute(ReadGraph graph, Context context, Result result) throws DatabaseException;
+
+    /**
+     * Invoked after all {@link #execute(AsyncReadGraph, Object)} calls have
+     * been finished successfully. This method will not be invoked if case of
+     * errors in {@link #execute(AsyncReadGraph, Object)} or the performed
+     * request that provides the results to this procedure.
+     * 
+     * @param graph asynchronous graph access
+     */
+    void finished(ReadGraph graph, Context context) throws DatabaseException;
+
+    /**
+     * If an error occurs in the processing of the database request that
+     * produces the results for this procedure.
+     * 
+     * @param graph asynchronous graph access
+     * @param throwable the exception that occurred
+     */
+    void exception(ReadGraph graph, Throwable throwable) throws DatabaseException;
+
+}
diff --git a/bundles/org.simantics.db/src/org/simantics/db/procedure/SyncContextProcedure.java b/bundles/org.simantics.db/src/org/simantics/db/procedure/SyncContextProcedure.java
new file mode 100644 (file)
index 0000000..93c745f
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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.procedure;
+
+import org.simantics.db.ReadGraph;
+
+/*
+ * 
+ * Execute or exception is called exactly once.
+ * 
+ */
+public interface SyncContextProcedure<Context, Result> {
+    
+    void execute(ReadGraph graph, Context context, Result result);
+    void exception(ReadGraph graph, Throwable throwable);
+       
+}
index cb191f6471bee1fd3930eb518cdbdc64067f4b8e..a8e2f2b61d316e747a84fed61e6da7a54c1723bf 100644 (file)
@@ -50,7 +50,7 @@ import org.simantics.db.procedure.AsyncMultiProcedure;
  * @see AsyncMultiProcedure
  * @see Session
  */
-public interface AsyncMultiRead<Result> extends Request {
+public interface AsyncMultiRead<Result> {
 
     /**
      * When a <code>GraphRequest</code> is serviced by the database session
index a197a5f2169edeac7a501ee042d71b377be9f704..f0856a7967fc6b12553239dbe4b1db7ddfa30287 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -50,7 +50,8 @@ import org.simantics.db.procedure.AsyncProcedure;
  * @see AsyncProcedure
  * @see Session
  */
-public interface AsyncRead<Result> extends Request {
+@FunctionalInterface
+public interface AsyncRead<Result> {
 
     /**
      * When a <code>GraphRequest</code> is serviced by the database session
@@ -76,6 +77,13 @@ public interface AsyncRead<Result> extends Request {
      *         be cancelled and any changes rolled back
      */
     void perform(AsyncReadGraph graph, AsyncProcedure<Result> procedure);
-    int getFlags();
-    
- }
+
+    default int getFlags() {
+        return 0;
+    }
+
+    default int threadHash() {
+        return hashCode();
+    }
+
+}
index b8a4c201277d6c5cbd7cf119d5a619538900c019..0754ac73f77ded327440c062d855a63ba85fa712 100644 (file)
@@ -16,6 +16,7 @@ import org.simantics.db.Session;
 import org.simantics.db.exception.CancelTransactionException;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 
 /**
  * The <code>GraphRequest</code> interface is used to create transaction
@@ -91,6 +92,6 @@ public interface MultiRead<Result> {
      * @throws CancelTransactionException to indicate that the request needs to
      *         be cancelled and any changes rolled back
      */
-    void perform(ReadGraph graph, AsyncMultiProcedure<Result> callback) throws DatabaseException;
+    void perform(ReadGraph graph, SyncMultiProcedure<Result> callback) throws DatabaseException;
     
  }
diff --git a/bundles/org.simantics.db/src/org/simantics/db/request/Request.java b/bundles/org.simantics.db/src/org/simantics/db/request/Request.java
deleted file mode 100644 (file)
index ef605a5..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.simantics.db.request;
-
-public interface Request {
-
-       /*
-        * The integer value obtained from this method can be used to determine
-        * the evaluation thread of the request.
-        * 
-        * @return A non-negative integer value
-        * 
-        */
-       int threadHash();
-       
-}
index 472eb9eee9dac914c0ce7cc5af9b1adaeea1a4a7..7b932f3dea1c361248c87850c84a6625b4b3161f 100644 (file)
  *******************************************************************************/
 package org.simantics.db.service;
 
-import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.DirectStatements;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.RelationInfo;
 import org.simantics.db.Resource;
-import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.procedure.AsyncContextProcedure;
-import org.simantics.db.procedure.AsyncMultiProcedure;
-import org.simantics.db.procedure.AsyncProcedure;
-import org.simantics.db.procedure.Procedure;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncContextProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.procedure.SyncProcedure;
 
 public interface DirectQuerySupport {
 
-    void forEachDirectPersistentStatement(AsyncReadGraph graph, Resource subject, AsyncProcedure<DirectStatements> procedure);
+    DirectStatements getDirectPersistentStatements(ReadGraph graph, Resource subject);
+    DirectStatements getDirectStatements(ReadGraph graph, Resource subject);
 
-    void forEachDirectStatement(AsyncReadGraph graph, Resource subject, AsyncProcedure<DirectStatements> procedure);
-    void forEachDirectStatement(AsyncReadGraph graph, Resource subject, SyncProcedure<DirectStatements> procedure);
-    void forEachDirectStatement(AsyncReadGraph graph, Resource subject, Procedure<DirectStatements> procedure);
+//     void forEachDirectPersistentStatement(ReadGraph graph, Resource subject, AsyncProcedure<DirectStatements> procedure);
+//    void forEachDirectStatement(ReadGraph graph, Resource subject, AsyncProcedure<DirectStatements> procedure);
+//    void forEachDirectStatement(ReadGraph graph, Resource subject, SyncProcedure<DirectStatements> procedure);
+//    void forEachDirectStatement(ReadGraph graph, Resource subject, Procedure<DirectStatements> procedure);
 
-    void forRelationInfo(AsyncReadGraph graph, Resource subject, AsyncProcedure<RelationInfo> procedure);
-    void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure<RelationInfo> procedure);
-    void forRelationInfo(AsyncReadGraph graph, Resource subject, Procedure<RelationInfo> procedure);
+    RelationInfo getRelationInfo(ReadGraph graph, Resource subject) throws DatabaseException;
     
-    <T> void forPossibleType(AsyncReadGraph graph, Resource subject, AsyncProcedure<Resource> procedure);
+//    void forRelationInfo(AsyncReadGraph graph, Resource subject, AsyncProcedure<RelationInfo> procedure);
+//    void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure<RelationInfo> procedure);
+//    void forRelationInfo(AsyncReadGraph graph, Resource subject, Procedure<RelationInfo> procedure);
     
-    AsyncMultiProcedure<Resource> compileForEachObject(ReadGraph graph, Resource relation, AsyncMultiProcedure<Resource> user);
-    <C> AsyncContextMultiProcedure<C, Resource> compileForEachObject(ReadGraph graph, Resource relation, AsyncContextMultiProcedure<C, Resource> user);
-    <T> AsyncProcedure<T> compilePossibleRelatedValue(ReadGraph graph, Resource relation, AsyncProcedure<T> user);
-    <C,T> AsyncContextProcedure<C,T> compilePossibleRelatedValue(ReadGraph graph, Resource relation, AsyncContextProcedure<C,T> user);
+    //<T> void forPossibleType(AsyncReadGraph graph, Resource subject, AsyncProcedure<Resource> procedure);
     
-    void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, AsyncMultiProcedure<Resource> procedure);
-    <C> void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, C context, AsyncContextMultiProcedure<C, Resource> procedure);
-    <T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, AsyncProcedure<T> procedure);
-    <C,T> void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, C context, AsyncContextProcedure<C,T> procedure);
-    <C> void forPossibleDirectType(AsyncReadGraph graph, Resource subject, C context, AsyncContextProcedure<C,Resource> procedure);
+    SyncMultiProcedure<Resource> compileForEachObject(ReadGraph graph, Resource relation, SyncMultiProcedure<Resource> user) throws DatabaseException;
+    <C> SyncContextMultiProcedure<C, Resource> compileForEachObject(ReadGraph graph, Resource relation, SyncContextMultiProcedure<C, Resource> user) throws DatabaseException;
+    <T> SyncProcedure<T> compilePossibleRelatedValue(ReadGraph graph, Resource relation, SyncProcedure<T> user) throws DatabaseException;
+    <C,T> SyncContextProcedure<C,T> compilePossibleRelatedValue(ReadGraph graph, Resource relation, SyncContextProcedure<C,T> user) throws DatabaseException;
+    
+    void forEachObjectCompiled(ReadGraph graph, Resource subject, SyncMultiProcedure<Resource> procedure);
+    <C> void forEachObjectCompiled(ReadGraph graph, Resource subject, C context, SyncContextMultiProcedure<C, Resource> procedure);
+    <T> void forPossibleRelatedValueCompiled(ReadGraph graph, Resource subject, SyncProcedure<T> procedure);
+    <C,T> void forPossibleRelatedValueCompiled(ReadGraph graph, Resource subject, C context, SyncContextProcedure<C,T> procedure);
+    <C> void forPossibleDirectType(ReadGraph graph, Resource subject, C context, SyncContextProcedure<C,Resource> procedure);
     
 }
index 5cc3fa65589cadbd71ade1236e4db2899cf8e28c..3da3c5aa3baa8f71e50bb1615939dcc8ef8a7fae 100644 (file)
@@ -74,7 +74,7 @@ public interface QueryControl {
 
     int getGraphThread(AsyncReadGraph graph);
     
-    boolean resume(AsyncReadGraph graph);
+    boolean resume(ReadGraph graph);
 
     void schedule(AsyncReadGraph graph, int targetThread, ControlProcedure procedure);
 
index 428acc6863952455759b9c3ddd6f2ad2b470afa5..4a59f4b3c8e96268a2097746cfc7accbeb452e56 100644 (file)
@@ -72,7 +72,7 @@ public class ConstantStyle implements Style {
     }
 
     @Override
-    public void activate(RequestProcessor backend, Resource diagram, Resource entry, Group group, final EvaluationContext observer) {
+    public void activate(RequestProcessor backend, Resource diagram, Resource entry, Group group, final EvaluationContext observer) throws DatabaseException {
 
         if (listener != null && !listener.isDisposed())
             return;
index 56063b990f71e771180a75acfd06db99b09877fa..9be72d29f53fabb6e8d2d906618a1fb0a2fb8f9f 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
  *******************************************************************************/
 package org.simantics.diagram.adapter;
 
-import gnu.trove.list.array.TIntArrayList;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TIntProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
+import org.simantics.db.common.utils.OrderedSetUtils;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.procedure.AsyncMultiProcedure;
-import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.request.AsyncRead;
 import org.simantics.diagram.content.ConnectionPartData;
 import org.simantics.diagram.content.ConnectionPartRequest;
 import org.simantics.diagram.content.DiagramContents;
@@ -37,6 +32,11 @@ import org.simantics.diagram.stubs.DiagramResource;
 import org.simantics.diagram.synchronization.ErrorHandler;
 import org.simantics.g2d.canvas.ICanvasContext;
 
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.set.hash.THashSet;
+
 /**
  * @author Tuukka Lehtonen
  */
@@ -54,92 +54,91 @@ public class DiagramContentRequest extends BaseRequest<Resource, DiagramContents
     public DiagramContents perform(ReadGraph g) throws DatabaseException {
 
         final DiagramResource DIA = DiagramResource.getInstance(g);
-        final DiagramContents result = new DiagramContents();
-
-        result.elements =   new ArrayList<Resource>(previousElementCount);
-        result.nodeSet = new THashSet<Resource>();
-        result.connectionSet = new THashSet<Resource>();
-        result.connectionSegments = new THashSet<EdgeResource>();
-        result.branchPoints = new THashSet<Resource>();
-        result.routeGraphConnectionSet = new THashSet<Resource>();
-        result.routeLinks = new THashSet<EdgeResource>();
-        result.routeLines = new THashSet<Resource>();
-        result.routePoints = new THashSet<Resource>();
-
-        result.partToConnection = new THashMap<Object, Resource>();
 
         // These help loading result.elements in the correct order.
         final AtomicInteger index = new AtomicInteger();
         final TIntArrayList unrecognizedElementIndices = new TIntArrayList();
 
-        g.forOrderedSet(data, new AsyncMultiProcedure<Resource>() {
+        Collection<Resource> components = OrderedSetUtils.toList(g, data);
+        DiagramContents res = g.syncRequest((AsyncRead<DiagramContents>)(graph, procedure) -> {
 
-            @Override
-            public void execute(AsyncReadGraph graph, final Resource component) {
+            DiagramContents result = new DiagramContents();
+            procedure.execute(graph, result);
+
+            result.elements =   new ArrayList<Resource>(previousElementCount);
+            result.nodeSet = new THashSet<Resource>();
+            result.connectionSet = new THashSet<Resource>();
+            result.connectionSegments = new THashSet<EdgeResource>();
+            result.branchPoints = new THashSet<Resource>();
+            result.routeGraphConnectionSet = new THashSet<Resource>();
+            result.routeLinks = new THashSet<EdgeResource>();
+            result.routeLines = new THashSet<Resource>();
+            result.routePoints = new THashSet<Resource>();
+
+            result.partToConnection = new THashMap<Object, Resource>();
+
+            for (Resource component : components) {
 
                 // Must add the elements to the result set here in order to
                 // keep their order the same as in the ordered set.
                 final int elementIndex = index.getAndIncrement();
                 result.elements.add(component);
 
-                graph.forTypes(component, new AsyncProcedure<Set<Resource>>() {
+                graph.forTypes(component, new ProcedureAdapter<Set<Resource>>() {
 
                     @Override
-                    public void exception(AsyncReadGraph graph, Throwable t) {
-                        if (errorHandler != null)
-                            errorHandler.error(t.getMessage(), t);
-                    }
+                    public void execute(Set<Resource> types) {
 
-                    @Override
-                    public void execute(AsyncReadGraph graph, Set<Resource> types) {
                         if (types.contains(DIA.Connection)) {
                             if (types.contains(DIA.RouteGraphConnection)) {
-                                graph.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
+                                graph.asyncRequest(
+                                        new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
                                         new ProcedureAdapter<RouteGraphConnectionPartData>() {
-                                    @Override
-                                    public void execute(RouteGraphConnectionPartData partData) {
-                                        synchronized (result) {
-                                            for (EdgeResource link : partData.links) {
-                                                result.routeLinks.add(link);
-                                                result.partToConnection.put(link, component);
-                                                result.connectionToParts.add(component, link);
-                                            }
-                                            for (Resource line : partData.routeLines) {
-                                                result.routeLines.add(line);
-                                                result.connectionToParts.add(component, line);
-                                                result.partToConnection.put(line, component);
-                                            }
-                                            for (Resource point : partData.routePoints) {
-                                                result.routePoints.add(point);
-                                                result.connectionToParts.add(component, point);
-                                                result.partToConnection.put(point, component);
+                                            @Override
+                                            public void execute(RouteGraphConnectionPartData partData) {
+                                                synchronized (result) {
+                                                    for (EdgeResource link : partData.links) {
+                                                        result.routeLinks.add(link);
+                                                        result.partToConnection.put(link, component);
+                                                        result.connectionToParts.add(component, link);
+                                                    }
+                                                    for (Resource line : partData.routeLines) {
+                                                        result.routeLines.add(line);
+                                                        result.connectionToParts.add(component, line);
+                                                        result.partToConnection.put(line, component);
+                                                    }
+                                                    for (Resource point : partData.routePoints) {
+                                                        result.routePoints.add(point);
+                                                        result.connectionToParts.add(component, point);
+                                                        result.partToConnection.put(point, component);
+                                                    }
+                                                }
                                             }
-                                        }
-                                    }
-                                });
+                                        });
 
                                 synchronized (result.routeGraphConnectionSet) {
                                     result.routeGraphConnectionSet.add(component);
                                 }
                             } else {
-                                graph.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component),
+                                graph.asyncRequest(
+                                        new ConnectionPartRequest(errorHandler, DIA, component),
                                         new ProcedureAdapter<ConnectionPartData>() {
-                                    @Override
-                                    public void execute(ConnectionPartData partData) {
-                                        synchronized (result) {
-                                            for (EdgeResource er : partData.edges) {
-                                                result.connectionSegments.add(er);
-                                                result.partToConnection.put(er, component);
-                                                result.connectionToParts.add(component, er);
+                                            @Override
+                                            public void execute(ConnectionPartData partData) {
+                                                synchronized (result) {
+                                                    for (EdgeResource er : partData.edges) {
+                                                        result.connectionSegments.add(er);
+                                                        result.partToConnection.put(er, component);
+                                                        result.connectionToParts.add(component, er);
+                                                    }
+                                                    for (Resource bp : partData.branchPoints) {
+                                                        result.branchPoints.add(bp);
+                                                        result.connectionToParts.add(component, bp);
+                                                        result.partToConnection.put(bp, component);
+                                                    }
+                                                }
                                             }
-                                            for (Resource bp : partData.branchPoints) {
-                                                result.branchPoints.add(bp);
-                                                result.connectionToParts.add(component, bp);
-                                                result.partToConnection.put(bp, component);
-                                            }
-                                        }
-                                    }
-                                });
+                                        });
 
                                 synchronized (result.connectionSet) {
                                     result.connectionSet.add(component);
@@ -159,36 +158,25 @@ public class DiagramContentRequest extends BaseRequest<Resource, DiagramContents
                             }
                         }
                     }
-
-                });
-
-            }
-
-            @Override
-            public void finished(AsyncReadGraph graph) {
-                // Remove elements that were not recognized in descending order.
-                unrecognizedElementIndices.sort();
-                unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
-                    @Override
-                    public boolean execute(int index) {
-                        result.elements.remove(index);
-                        return true;
-                    }
                 });
-
-                // Help successive request executions by remembering the previous
-                // element count. This will relieve some ArrayList reallocation
-                // strain down the road.
-                previousElementCount = result.elements.size();
             }
+        });
 
+        // Remove elements that were not recognized in descending order.
+        unrecognizedElementIndices.sort();
+        unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
             @Override
-            public void exception(AsyncReadGraph graph, Throwable t) {
-                if (errorHandler != null)
-                    errorHandler.error(t.getMessage(), t);
+            public boolean execute(int index) {
+                res.elements.remove(index);
+                return true;
             }
         });
 
-        return result;
+        // Help successive request executions by remembering the previous
+        // element count. This will relieve some ArrayList reallocation
+        // strain down the road.
+        previousElementCount = res.elements.size();
+
+        return res;
     }
 }
\ No newline at end of file
index dd6c9b7d10f7e7e916264a30bc3f24af71180627..9be80c34e9c1d8c611a762e851a866dea62e0c3d 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -1302,6 +1302,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     // ITask task5 = ThreadLogger.getInstance().begin("DiagramContentRequest2");
                     ITask task42 = ThreadLogger.getInstance().begin("DiagramContentRequest2");
                     DiagramContents contents = g.syncRequest(query);
+                    //System.err.println("contents: " + contents);
                     task42.finish();
                     // task5.finish();
                     monitor.worked(10);
@@ -1338,7 +1339,12 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                             ArrayMap.keys(ProfileKeys.DIAGRAM, ProfileKeys.CANVAS, ProfileKeys.NODE_MAP).values(GraphToDiagramSynchronizer.this.diagram, canvas, dn),
                             new CanvasNotification(canvas));
 
-                    profileObserver.listen(g, GraphToDiagramSynchronizer.this);
+                    g.getSession().asyncRequest(new AsyncReadRequest() {
+                        @Override
+                        public void run(AsyncReadGraph graph) {
+                            profileObserver.listen(graph, GraphToDiagramSynchronizer.this);
+                        }
+                    });
 
                     return d;
 
@@ -1623,7 +1629,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             this.removedRouteGraphConnections.clear();
         }
 
-        void processNodes(AsyncReadGraph graph) {
+        void processNodes(ReadGraph graph) throws DatabaseException {
 
             for (Map.Entry<Resource, Change> entry : changes.elements.entrySet()) {
 
@@ -1635,7 +1641,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(element);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_NODE_LOAD)
-                                graph.asyncRequest(new ReadRequest() {
+                                graph.syncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED ELEMENT: "
@@ -1699,7 +1705,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     }
                                 };
 
-                                graph.asyncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure<IElement>() {
+                                graph.syncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure<IElement>() {
                                     @Override
                                     public void execute(AsyncReadGraph graph, final IElement e) {
                                         if (e == null)
@@ -1792,7 +1798,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                 };
 
                                 //System.out.println("NODE REQUEST: " + element);
-                                graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
+                                graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
                                     @Override
                                     public void execute(AsyncReadGraph graph, IElement e) {
                                         if (e == null)
@@ -1826,7 +1832,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         IElement e = getMappedElement(element);
                         if (DebugPolicy.DEBUG_NODE_LOAD)
-                            graph.asyncRequest(new ReadRequest() {
+                            graph.syncRequest(new ReadRequest() {
                                 @Override
                                 public void run(ReadGraph graph) throws DatabaseException {
                                     System.out.println("    EXTERNALLY REMOVED ELEMENT: "
@@ -1839,6 +1845,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         }
                         break;
                     }
+                    default:
                 }
             }
         }
@@ -1872,6 +1879,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         }
                         break;
                     }
+                    default:
                 }
             }
         }
@@ -1915,6 +1923,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         removedConnectionEntities.add(ce);
                     }
+                    default:
                 }
             }
 
@@ -1932,7 +1941,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             }
         }
 
-        void processRouteGraphConnections(AsyncReadGraph graph) {
+        void processRouteGraphConnections(ReadGraph graph) throws DatabaseException {
             for (Map.Entry<Resource, Change> entry : changes.routeGraphConnections.entrySet()) {
                 final Resource connection = entry.getKey();
 
@@ -2010,7 +2019,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                             }
                         };
 
-                        graph.asyncRequest(new ConnectionRequest(canvas, diagram, connection, errorHandler, loadListener), new Procedure<IElement>() {
+                        graph.syncRequest(new ConnectionRequest(canvas, diagram, connection, errorHandler, loadListener), new Procedure<IElement>() {
                             @Override
                             public void execute(final IElement e) {
                                 if (e == null)
@@ -2039,6 +2048,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                             removedRouteGraphConnections.add(e);
                         break;
                     }
+                    default:
                 }
             }
         }
@@ -2052,7 +2062,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             return assertMappedConnection(connection);
         }
 
-        void processBranchPoints(AsyncReadGraph graph) {
+        void processBranchPoints(ReadGraph graph) throws DatabaseException {
             for (Map.Entry<Resource, Change> entry : changes.branchPoints.entrySet()) {
 
                 final Resource element = entry.getKey();
@@ -2063,7 +2073,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(element);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_NODE_LOAD)
-                                graph.asyncRequest(new ReadRequest() {
+                                graph.syncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED BRANCH POINT: "
@@ -2115,7 +2125,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                 }
                             };
 
-                            graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
+                            graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
                                 @Override
                                 public void execute(AsyncReadGraph graph, IElement e) {
                                     if (e != null) {
@@ -2141,7 +2151,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         IElement e = getMappedElement(element);
                         if (DebugPolicy.DEBUG_NODE_LOAD)
-                            graph.asyncRequest(new ReadRequest() {
+                            graph.syncRequest(new ReadRequest() {
                                 @Override
                                 public void run(ReadGraph graph) throws DatabaseException {
                                     System.out.println("    EXTERNALLY REMOVED BRANCH POINT: "
@@ -2154,11 +2164,12 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         }
                         break;
                     }
+                    default:
                 }
             }
         }
 
-        void processConnectionSegments(AsyncReadGraph graph) {
+        void processConnectionSegments(ReadGraph graph) throws DatabaseException {
             ConnectionSegmentAdapter adapter = connectionSegmentAdapter;
 
             for (Map.Entry<EdgeResource, Change> entry : changes.connectionSegments.entrySet()) {
@@ -2170,7 +2181,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(seg);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_EDGE_LOAD)
-                                graph.asyncRequest(new ReadRequest() {
+                                graph.syncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED CONNECTION SEGMENT: " + seg.toString()
@@ -2178,7 +2189,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     }
                                 });
 
-                            graph.asyncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure<IElement>() {
+                            graph.syncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure<IElement>() {
                                 @Override
                                 public void execute(AsyncReadGraph graph, IElement e) {
                                     if (DebugPolicy.DEBUG_EDGE_LOAD)
@@ -2206,7 +2217,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         final IElement e = getMappedElement(seg);
                         if (DebugPolicy.DEBUG_EDGE_LOAD)
-                            graph.asyncRequest(new ReadRequest() {
+                            graph.syncRequest(new ReadRequest() {
                                 @Override
                                 public void run(ReadGraph graph) throws DatabaseException {
                                     System.out.println("    EXTERNALLY REMOVED CONNECTION SEGMENT: " + seg.toString() + " - "
@@ -2218,6 +2229,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         }
                         break;
                     }
+                    default:
                 }
             }
         }
@@ -2260,9 +2272,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             Object task = Timing.BEGIN("processNodesConnections");
             //System.out.println("---- PROCESS NODES & CONNECTIONS BEGIN");
             if (!changes.elements.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processNodes(graph);
                     }
                     @Override
@@ -2277,9 +2289,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
             //System.out.println("---- PROCESS BRANCH POINTS BEGIN");
             if (!changes.branchPoints.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processBranchPoints(graph);
                     }
                     @Override
@@ -2295,9 +2307,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
             //System.out.println("---- PROCESS CONNECTION SEGMENTS BEGIN");
             if (!changes.connectionSegments.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processConnectionSegments(graph);
                     }
                     @Override
@@ -2312,9 +2324,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
             task = Timing.BEGIN("processRouteGraphConnections");
             if (!changes.routeGraphConnections.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processRouteGraphConnections(graph);
                     }
                     @Override
@@ -2474,13 +2486,18 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     return;
                 }
 
-                // NOTICE: Layer information is loaded from the connection entity resource
-                // that is shared by all segments of the same connection.
-                ElementFactoryUtil.loadLayersForElement(graph, layerManager, diagram, edge, info.connection,
-                        new AsyncProcedureAdapter<IElement>() {
+                graph.syncRequest(new AsyncReadRequest() {
                     @Override
-                    public void exception(AsyncReadGraph graph, Throwable t) {
-                        error("failed to load layers for connection segment", t);
+                    public void run(AsyncReadGraph graph) {
+                        // NOTICE: Layer information is loaded from the connection entity resource
+                        // that is shared by all segments of the same connection.
+                        ElementFactoryUtil.loadLayersForElement(graph, layerManager, diagram, edge, info.connection,
+                                new AsyncProcedureAdapter<IElement>() {
+                            @Override
+                            public void exception(AsyncReadGraph graph, Throwable t) {
+                                error("failed to load layers for connection segment", t);
+                            }
+                        });
                     }
                 });
 
index 856631fa22d4105c32e0549997dfe0d09b890a34..6e7d368b58d61629015f080237a07e5f3205ec17 100644 (file)
@@ -68,13 +68,13 @@ public class MappedTypeGroup implements Group {
     }
 
     @Override
-    public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener<Resource> listener) {
+    public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener<Resource> listener) throws DatabaseException {
         if (types.isEmpty()) {
             System.out.println("MappedTypeGroup has no types!");
             return;
         }
 
-        processor.asyncRequest(new BinaryRead<Resource, Collection<Resource>, Collection<Resource>>(runtimeDiagram, types) {
+        processor.syncRequest(new BinaryRead<Resource, Collection<Resource>, Collection<Resource>>(runtimeDiagram, types) {
 
             @Override
             public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
index 8e2db2488381c4caf6dbb137f34e6425b080ecc5..e025fb2ddf16927783a2fc353817b87c9c068155 100644 (file)
@@ -63,13 +63,13 @@ public class TypeGroup implements Group {
     }
 
     @Override
-    public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener<Resource> listener) {
+    public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener<Resource> listener) throws DatabaseException {
         if (types.isEmpty()) {
             System.out.println("TypeGroup has no types!");
             return;
         }
 
-        processor.asyncRequest(new BinaryRead<Resource, Collection<Resource>, Collection<Resource>>(runtimeDiagram, types) {
+        processor.syncRequest(new BinaryRead<Resource, Collection<Resource>, Collection<Resource>>(runtimeDiagram, types) {
 
             @Override
             public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
index 059bb55fbec0aed9c89a3ffbb2c9305bfdd12891..cc04927f6ef7249c7cb5a33a0620db04f48b22d5 100644 (file)
@@ -38,8 +38,8 @@ public abstract class DiagramElementGroup implements Group {
     }
 
     @Override
-    public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener<Resource> listener) {
-        processor.asyncRequest(new BinaryRead<Class<?>, Resource, Collection<Resource>>(getClass(), runtimeDiagram) {
+    public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener<Resource> listener) throws DatabaseException {
+        processor.syncRequest(new BinaryRead<Class<?>, Resource, Collection<Resource>>(getClass(), runtimeDiagram) {
 
             @Override
             public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
index ee203616da950f31d0fa1f1abbfae793de988f2d..21071ba74bd9453e9c3bdf166c0240bd46156c54 100644 (file)
@@ -47,7 +47,6 @@ import org.simantics.scenegraph.profile.impl.DebugPolicy;
 import org.simantics.scl.runtime.tuple.Tuple;
 import org.simantics.scl.runtime.tuple.Tuple2;
 import org.simantics.utils.datastructures.Pair;
-import org.simantics.utils.threads.AWTThread;
 
 /**
  * For most style implementations it should be enough to override the following
@@ -298,7 +297,7 @@ public abstract class StyleBase<Result> implements Style {
      * @see org.simantics.diagram.profile.Style#activate(org.simantics.db.RequestProcessor, org.simantics.db.Resource, org.simantics.db.layer0.variable.Variable, org.simantics.diagram.profile.Group, org.simantics.diagram.profile.Observer)
      */
     @Override
-    public final void activate(RequestProcessor backend, final Resource runtimeDiagram, final Resource entry, final Group group, final EvaluationContext observer) {
+    public final void activate(RequestProcessor backend, final Resource runtimeDiagram, final Resource entry, final Group group, final EvaluationContext observer) throws DatabaseException {
 
         ObserverGroupListener listener = getListener(runtimeDiagram, group);
 
index bfc439101a81593c895d29da41a6183c0bbfec5c..04e30f70d44621e0c9b7e025ff5aba228e09631b 100644 (file)
@@ -276,8 +276,8 @@ public class RuntimeDiagramManager {
         return createRuntimeDiagram(graph, diagram, desc);
     }
 
-    private void listenRequest(RequestProcessor processor, final Resource diagram) {
-        processor.asyncRequest(new RuntimeVariableForInput(getResourceInput()), new AsyncListener<RuntimeDiagramDesc>() {
+    private void listenRequest(RequestProcessor processor, final Resource diagram) throws DatabaseException {
+        processor.syncRequest(new RuntimeVariableForInput(getResourceInput()), new AsyncListener<RuntimeDiagramDesc>() {
 
             @Override
             public void exception(AsyncReadGraph graph, Throwable throwable) {
index 66cc0047c3389fe4e559486c76f8eb52bf50a8ab..aabe7b29ffd04dbcdff684dc899f11f2bde8c19f 100644 (file)
@@ -72,8 +72,6 @@ import org.simantics.document.server.state.StateNodeManager;
 import org.simantics.document.server.state.StateRealm;
 import org.simantics.document.server.state.StateSessionManager;
 import org.simantics.modeling.ModelingResources;
-import org.simantics.modeling.scl.SCLRealm;
-import org.simantics.modeling.scl.SCLSessionManager;
 import org.simantics.modeling.services.CaseInsensitiveComponentFunctionNamingStrategy;
 import org.simantics.modeling.services.ComponentNamingStrategy;
 import org.simantics.operation.Layer0X;
@@ -204,11 +202,11 @@ public class Functions {
                 }
                 
                 DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
-                PrimitivePropertyStatementsProcedure foo = new PrimitivePropertyStatementsProcedure();
+                //PrimitivePropertyStatementsProcedure foo = new PrimitivePropertyStatementsProcedure();
 
-                dqs.forEachDirectPersistentStatement(graph, parentRes, foo);
+                DirectStatements ds = dqs.getDirectPersistentStatements(graph, parentRes);
 
-                for(Statement stm : foo.result) {
+                for(Statement stm : ds) {
                     Resource predicate = stm.getPredicate();
                     PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(predicate));
 
index bb0c8a5b189c1ee5f0b11905f18e3cad4bae1183..ecc6b20cc9c517b6e04a8e0691821466b4961478 100644 (file)
@@ -184,7 +184,7 @@ public class IssueUtils {
         public void add(ReadGraph graph, final Resource issue) throws DatabaseException {
             IssueValidityListener listener = new IssueValidityListener(issue);
 
-            graph.asyncRequest(new ResourceRead3<Boolean>(issue, model, source) {
+            graph.syncRequest(new ResourceRead3<Boolean>(issue, model, source) {
 
                 @Override
                 public Boolean perform(ReadGraph graph) throws DatabaseException {
@@ -250,7 +250,7 @@ public class IssueUtils {
             sources.put(source, Pair.make(is, listener));
 
             if (isListeningTracker) {
-                graph.asyncRequest(
+                graph.syncRequest(
                         new Objects(source, ISSUE.IssueSource_Manages),
                         new IssueSourceManagedIssuesListener(disposed, source, model));
             }
index 9814925e3715daba6e0efcc16451d5d59a76b0e3..8608fc4d595559c91cc4c682bc1c62838c5b70d2 100644 (file)
@@ -47,11 +47,6 @@ public abstract class QueryExecutor2 extends ReadRequest implements AsyncListene
        public void execute(RequestProcessor processor) throws DatabaseException {
                
                AsyncMultiRead<Object> request = new AsyncMultiRead<Object>() {
-
-                       @Override
-                       public int threadHash() {
-                               return hashCode();
-                       }
                        
                        @Override
                        public void perform(AsyncReadGraph graph,
@@ -72,7 +67,7 @@ public abstract class QueryExecutor2 extends ReadRequest implements AsyncListene
                }; 
                
                if(processor instanceof WriteGraph) processor.syncRequest(request, procedure);
-               else processor.asyncRequest(request, procedure);
+               else processor.syncRequest(request, procedure);
                
        }
 
index 17c26f48386e6455ae85301da8506b0fcd4b35d2..597a125a896594690d392394faa64c19acd9c18a 100644 (file)
@@ -219,7 +219,7 @@ public class MonitorClassFactory2 extends SyncElementFactory {
             }
 
             if(monitorVariable != null)
-               graph.asyncRequest(new MonitorVariableValueRequest(diagramRuntime, element), monitorListener);
+               graph.syncRequest(new MonitorVariableValueRequest(diagramRuntime, element), monitorListener);
             
         }
     }
index 7e480d4ffa1218276448b00fbcf8a64e48cebdec..46142247f47855efcb3a78ca351568a3404d89da 100644 (file)
@@ -12,12 +12,13 @@ import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.simantics.Simantics;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.Disposable;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.AsyncListenerAdapter;
 import org.simantics.db.common.procedure.adapter.DisposableListener;
 import org.simantics.db.common.procedure.adapter.DisposableSyncListener;
-import org.simantics.db.common.procedure.adapter.SyncListenerAdapter;
 import org.simantics.db.common.request.TernaryRead;
 import org.simantics.db.common.request.UnaryRead;
 import org.simantics.db.common.request.UniqueRead;
@@ -184,7 +185,7 @@ public class SCLExpressionIssueProvider implements SCLIssueProvider {
         }
     }
     
-    private static class ComponentSyncListenerAdapter extends SyncListenerAdapter<Set<Resource>> implements Disposable {
+    private static class ComponentSyncListenerAdapter extends AsyncListenerAdapter<Set<Resource>> implements Disposable {
 
         private ConcurrentHashMap<Resource, SCLValueDisposableSyncListener> currentlyListening = new ConcurrentHashMap<>();
         private boolean disposed;
@@ -195,7 +196,7 @@ public class SCLExpressionIssueProvider implements SCLIssueProvider {
         }
         
         @Override
-        public void execute(ReadGraph graph, Set<Resource> newComponents) {
+        public void execute(AsyncReadGraph graph, Set<Resource> newComponents) {
             if (currentlyListening.isEmpty() && newComponents.isEmpty()) {
                 // we can stop here as nothing will change
                 return;
index 27c840467a96a9d56bbf17968b2d136cc848de7c..a18fa7b4625f42f3a3218914691a96a5f97bdce3 100644 (file)
@@ -324,7 +324,7 @@ public class ModelHistoryCollector {
             if (variableListener == null) {
                 variableListener = new VariableSetListener(this);
                 initMutex = new Semaphore(0);
-                processor.asyncRequest( subscriptionFunction.get(), variableListener );
+                processor.syncRequest( subscriptionFunction.get(), variableListener );
                 // Force synchronous initialization.
                 initMutex.acquire();
             }
index 8d1a111244aea56b2caf6a63d0629882870b7411..27d6a0dbcb79331a529d962970f7241c186f1411 100644 (file)
@@ -13,6 +13,7 @@ package org.simantics.scenegraph.profile;
 
 import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.SetListener;
 
 
@@ -37,6 +38,6 @@ public interface Group {
      *        objects. Usually one just delegates normal database listener
      *        events to this listener.
      */
-    void trackItems(RequestProcessor processor, Resource runtimeDiagram, SetListener<Resource> listener);
+    void trackItems(RequestProcessor processor, Resource runtimeDiagram, SetListener<Resource> listener) throws DatabaseException;
 
 }
index d18e623d049eda44b5e7b113024741f22233544e..c719df2d7aaf862afa12b9dee67aeee6b7b3fa2b 100644 (file)
@@ -13,6 +13,7 @@ package org.simantics.scenegraph.profile;
 
 import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
 
 /**
  * This interface is not intended to be implemented directly. Extend
@@ -36,7 +37,7 @@ public interface Style {
      * @param group
      * @param observer
      */
-    void activate(RequestProcessor backend, Resource runtimeDiagram, Resource entry, Group group, EvaluationContext observer);
+    void activate(RequestProcessor backend, Resource runtimeDiagram, Resource entry, Group group, EvaluationContext observer) throws DatabaseException;
 
     /**
      * Deactivates this style. Intended to stop tracking the currently tracked
index 23c1ad508ef09d68b10d0ac22649c7d3004d17cb..f3d4c34306d71a7bce5c9779ddee01added2ec60 100644 (file)
@@ -36,6 +36,7 @@ import org.simantics.scl.osgi.SCLOsgi;
 import org.simantics.scl.runtime.SCLContext;
 import org.simantics.scl.runtime.function.Function;
 import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
 import org.simantics.scl.runtime.tuple.Tuple;
 import org.simantics.scl.runtime.tuple.Tuple0;
 import org.simantics.utils.DataContainer;
@@ -122,15 +123,18 @@ public class SCLFunctions {
         if (graph != null) {
             return (T)f.apply(Tuple0.INSTANCE);
         } else {
+            final SCLReportingHandler printer = (SCLReportingHandler)SCLContext.getCurrent().get(SCLReportingHandler.REPORTING_HANDLER);
             return Simantics.getSession().syncRequest(new WriteResultRequest<T>() {
                 @Override
                 public T perform(WriteGraph graph) throws DatabaseException {
                     SCLContext.push(context);
+                    SCLReportingHandler oldPrinter = (SCLReportingHandler)context.put(SCLReportingHandler.REPORTING_HANDLER, printer);
                     ReadGraph oldGraph = (ReadGraph)context.put(GRAPH, graph);
                     try {
                         return (T)f.apply(Tuple0.INSTANCE);
                     } finally {
                         context.put(GRAPH, oldGraph);
+                        context.put(SCLReportingHandler.REPORTING_HANDLER, oldPrinter);
                         SCLContext.pop();
                     }
                 }
@@ -295,7 +299,7 @@ public class SCLFunctions {
     }
     
     public static void subqueryL(ReadGraph graph, Function query, Function executeCallback, Function1<Throwable, Tuple> exceptionCallback, Function1<Tuple0, Boolean> isDisposedCallback) throws DatabaseException {
-        graph.asyncRequest(new Subquery(query), new SyncListenerAdapter<Object>() {
+        graph.syncRequest(new Subquery(query), new SyncListenerAdapter<Object>() {
             @Override
             public void execute(ReadGraph graph, Object result) throws DatabaseException {
                 Simantics.applySCLRead(graph, executeCallback, result);
index 607661163f5f138701da9e08acf46ea61d48cb46..03df2dd0a8eb8f99af62ee7d6cfb31b012dfd660 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -135,7 +135,7 @@ public class GraphUI implements Adaptable, ListenerSupport, AsyncListenerSupport
                    listener = propertyListener(client, childName);
                    listenerCache.put(child.first, listener);
            }
-               graph.asyncRequest(new FilteredVariableProperties(child.second), listener);
+               graph.syncRequest(new FilteredVariableProperties(child.second), listener);
        }
 
     }
@@ -347,7 +347,7 @@ public class GraphUI implements Adaptable, ListenerSupport, AsyncListenerSupport
         private String childName;
         private boolean listenerDisposed;
 
-        public PropertyListener(AsyncListenerSupport support, ClientModel client, String childName) {
+        public PropertyListener(SyncListenerSupport support, ClientModel client, String childName) {
             super(support);
             this.client = client;
             this.childName = childName;
@@ -359,7 +359,7 @@ public class GraphUI implements Adaptable, ListenerSupport, AsyncListenerSupport
             if(DEBUG)
                 System.out.println("GraphUI adds property  " + property.second.getURI(graph));
 
-            graph.asyncRequest(new CellValue(property.second), new SyncListener<Object>() {
+            graph.syncRequest(new CellValue(property.second), new SyncListener<Object>() {
 
                 @Override
                 public void execute(ReadGraph graph, final Object value) throws DatabaseException {
@@ -456,37 +456,41 @@ public class GraphUI implements Adaptable, ListenerSupport, AsyncListenerSupport
                                @Override
                                public void handle(final String location) {
                                        
-                               processor.asyncRequest(new ReadRequest() {
-
-                                   @Override
-                                   public void run(ReadGraph graph) throws DatabaseException {
-                                       
-                                                       Variable cellVariable = run.getPossibleChild(graph, location);
-                                                       if(cellVariable != null) {
-                                                               final Resource config = cellVariable.getPossiblePropertyValue(graph, "Represents");
-                                                               if(config != null) {
-                                                                       
-                                                                       graph.asyncRequest(new WriteRequest() {
+                                       try {
+                                               processor.syncRequest(new ReadRequest() {
 
-                                                                               @Override
-                                                                               public void perform(WriteGraph graph) throws DatabaseException {
-                                                                                       
-                                                                                       Layer0 l0 = Layer0.getInstance(graph);
+                                                       @Override
+                                                       public void run(ReadGraph graph) throws DatabaseException {
+
+                                                               Variable cellVariable = run.getPossibleChild(graph, location);
+                                                               if(cellVariable != null) {
+                                                                       final Resource config = cellVariable.getPossiblePropertyValue(graph, "Represents");
+                                                                       if(config != null) {
+
+                                                                               graph.asyncRequest(new WriteRequest() {
+
+                                                                                       @Override
+                                                                                       public void perform(WriteGraph graph) throws DatabaseException {
+
+                                                                                               Layer0 l0 = Layer0.getInstance(graph);
 //                                                                                     SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
-                                                                                       graph.deny(config, l0.PartOf);
+                                                                                               graph.deny(config, l0.PartOf);
 //                                                                                     graph.deny(config, sr.RowOf);
 //                                                                                     graph.deny(config, sr.ColumnOf);
-                                                                                       
-                                                                               }
-                                                                               
-                                                                       });
-                                                                       
+
+                                                                                       }
+
+                                                                               });
+
+                                                                       }
                                                                }
+
                                                        }
-                                                       
-                                   }
-                                   
-                               });
+
+                                               });
+                                       } catch (DatabaseException e) {
+                                               LOGGER.error("Unexpected exception while removing cell", e);
+                                       }
                                        
                                }
                
@@ -791,7 +795,7 @@ public class GraphUI implements Adaptable, ListenerSupport, AsyncListenerSupport
 
     @Override
     public void exception(Throwable t) {
-        t.printStackTrace();
+        LOGGER.error("Failed to read properties.", t);
     }
 
     @Override
index 4669fdf4da1d4078372665d510a0f35effd354da..7edd2e81661c80c741f8162074b9f56ac572d890 100644 (file)
@@ -76,11 +76,11 @@ public class SheetFactory implements ElementFactory {
             }
 
             @Override
-            public void execute(AsyncReadGraph graph, final Resource sheet) {
+            public void execute(AsyncReadGraph g, final Resource sheet) {
 
                 if (sheet != null) {
 
-                    graph.asyncRequest(new ReadRequest() {
+                    g.asyncRequest(new ReadRequest() {
 
                         @Override
                         public void run(ReadGraph graph) throws DatabaseException {
@@ -138,7 +138,7 @@ public class SheetFactory implements ElementFactory {
                             // This is called too early as backend.load is
                             // definitely not complete at this time, but right now that is
                             // acceptable from the implementation point-of-view.
-                            procedure.execute(graph, element);
+                            procedure.execute(g, element);
 
                         }
 
index b33137b529b41def27aaad61d836301d8cdf361c..6b5a0355268c983faf3c2db6348dc1359ae9cc6b 100644 (file)
@@ -20,8 +20,8 @@ import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.ui.IMemento;
 import org.eclipse.ui.IPersistableElement;
 import org.simantics.Simantics;
+import org.simantics.db.AsyncRequestProcessor;
 import org.simantics.db.ReadGraph;
-import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.common.ResourceArray;
@@ -384,7 +384,7 @@ public class ResourceEditorInput2 extends PlatformObject implements IResourceEdi
         return true;
     }
 
-    private void updateCaches(RequestProcessor processor, boolean sync) throws DatabaseException {
+    private void updateCaches(AsyncRequestProcessor processor, boolean sync) throws DatabaseException {
         ReadRequest req = new ReadRequest() {
             @Override
             public void run(ReadGraph g) throws DatabaseException {
index 9b2c1e06ccebf16650796d94b20c2ba768219e45..1fd5a16207e3d8e29e526ff7b4d626c830c833c0 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -20,7 +20,6 @@ import org.simantics.db.common.request.Queries;
 import org.simantics.db.common.request.UnaryRead;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.request.combinations.Combinators;
-import org.simantics.db.layer0.request.combinations.Combinators.SynchronizationProcedure;
 import org.simantics.db.request.Read;
 import org.simantics.ui.workbench.IResourceEditorInput;
 
@@ -208,10 +207,8 @@ public final class InputValidationCombinators {
         }
         @Override
         public Resource perform(ReadGraph graph) throws DatabaseException {
-            SynchronizationProcedure<Resource> procedure = new SynchronizationProcedure<Resource>();
             Resource relation = graph.getResource(relationURI);
-            graph.forPossibleObject(subject, relation, procedure);
-            return procedure.getResult();
+            return graph.getPossibleObject(subject, relation);
         }
         @Override
         public int hashCode() {
@@ -270,10 +267,8 @@ public final class InputValidationCombinators {
         }
         @Override
         public Resource perform(ReadGraph graph) throws DatabaseException {
-            SynchronizationProcedure<Resource> procedure = new SynchronizationProcedure<Resource>();
             Resource relation = graph.getResource(relationURI);
-            graph.forSingleObject(subject, relation, procedure);
-            return procedure.getResult();
+            return graph.getSingleObject(subject, relation);
         }
         @Override
         public int hashCode() {
index 1a6a3a0b44a01604c301b73b6f899af061dcd527..dc492e20cfa1af451cd2d2cc3808806f87c3239d 100644 (file)
@@ -45,33 +45,43 @@ public class ForObjectSetTest1 extends ExistingDatabaseTest {
                                graph.claim(relation, b.SubrelationOf, b.IsRelatedTo);
                                graph.claim(relation, b.InverseOf, relation);
                                
-                               graph.forObjectSet(graph.getRootLibrary(), relation, new AsyncSetListener<Resource>() {
-
-                                       @Override
-                                       public void add(AsyncReadGraph graph, Resource result) {
-                                               synchronized(this) {
-                                                       adds++;
-                                               }
-                                       }
-
-                                       @Override
-                                       public void remove(AsyncReadGraph graph, Resource result) {
-                                               synchronized(this) {
-                                                       removes++;
-                                               }
-                                       }
-
-                                       @Override
-                                       public void exception(AsyncReadGraph graph, Throwable t) {
-                                               exception = t;
-                                       }
-
-                                       @Override
-                                       public boolean isDisposed() {
-                                               return false;
-                                       }
-                                       
-                               });
+                       session.syncRequest(new TestAsyncReadRequest() {
+
+                           @Override
+                           public void run(AsyncReadGraph graph) throws Throwable {
+
+                                               graph.forObjectSet(graph.getRootLibrary(), relation, new AsyncSetListener<Resource>() {
+
+                                                       @Override
+                                                       public void add(AsyncReadGraph graph, Resource result) {
+                                                               synchronized(this) {
+                                                                       adds++;
+                                                               }
+                                                       }
+
+                                                       @Override
+                                                       public void remove(AsyncReadGraph graph, Resource result) {
+                                                               synchronized(this) {
+                                                                       removes++;
+                                                               }
+                                                       }
+
+                                                       @Override
+                                                       public void exception(AsyncReadGraph graph, Throwable t) {
+                                                               exception = t;
+                                                       }
+
+                                                       @Override
+                                                       public boolean isDisposed() {
+                                                               return false;
+                                                       }
+                                                       
+                                               });
+                               
+                           }
+                           
+                       });
+                       
                        }
                        
                });
index 749fbeb768f278f4a40d5a8b86371fd24288931b..b4137a43a0179b16f319bb0882966f9e614932f8 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -13,15 +13,14 @@ package org.simantics.db.tests.api.request.misc;
 
 import org.junit.Test;
 import org.simantics.db.AsyncReadGraph;
-import org.simantics.db.ReadGraph;
 import org.simantics.db.Session;
 import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.AsyncReadRequest;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.AsyncListener;
 import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.request.AsyncRead;
-import org.simantics.db.request.Read;
 import org.simantics.db.testing.base.ExistingDatabaseTest;
 
 /**
@@ -89,12 +88,11 @@ public class AsyncTransactionTest extends ExistingDatabaseTest {
     public void testAsyncTransactions() throws DatabaseException {
         Session session = getSession();
 
-        session.asyncRequest(new Read<Object>() {
+        session.asyncRequest(new AsyncReadRequest() {
 
             @Override
-            public Object perform(ReadGraph graph) throws DatabaseException {
+            public void run(AsyncReadGraph graph) {
                 AsyncTransactionTest.this.perform(graph);
-                return null;
             }
 
         });
index 2bec7c21eb3666dedbf9a68a573daee4c77354c6..8181e08fb9d2bf1a4a9fc4646e099f30f9e54fdf 100644 (file)
@@ -33,11 +33,6 @@ public class RequestParentTest3 extends ExistingDatabaseTest {
                QueryDebug debug = session.getService(QueryDebug.class);
                
                class Request implements AsyncMultiRead<Object> {
-
-                       @Override
-                       public int threadHash() {
-                               return hashCode();
-                       }
                        
             @Override
             public void perform(AsyncReadGraph graph, AsyncMultiProcedure<Object> callback) {
index 7ae1a8491bb7188ee2649fc42d6b4674d8171ab7..8bdad204ba698caf8110f0f34f411d8d039f136b 100644 (file)
@@ -20,8 +20,8 @@ import org.simantics.db.Session;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.query.CacheEntry;
 import org.simantics.db.impl.service.QueryDebug;
-import org.simantics.db.procedure.AsyncMultiListener;
-import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.SyncMultiListener;
+import org.simantics.db.procedure.SyncMultiProcedure;
 import org.simantics.db.request.MultiRead;
 import org.simantics.db.testing.annotation.Fails;
 import org.simantics.db.testing.base.ExistingDatabaseTest;
@@ -39,7 +39,7 @@ public class RequestParentTest4 extends ExistingDatabaseTest {
         class Request implements MultiRead<Object> {
 
             @Override
-            public void perform(ReadGraph graph, AsyncMultiProcedure<Object> callback) throws DatabaseException {
+            public void perform(ReadGraph graph, SyncMultiProcedure<Object> callback) throws DatabaseException {
                 callback.execute(graph, new Object());
                 callback.finished(graph);
             }
@@ -49,15 +49,15 @@ public class RequestParentTest4 extends ExistingDatabaseTest {
         final Request request1 = new Request();
         final Request request2 = new Request();
         
-        session.syncRequest(request1, new AsyncMultiListener<Object>() {
+        session.syncRequest(request1, new SyncMultiListener<Object>() {
 
             @Override
-            public void exception(AsyncReadGraph graph, Throwable t) {
+            public void exception(ReadGraph graph, Throwable t) {
             }
 
             @Override
-            public void execute(AsyncReadGraph graph, Object result) {
-                graph.asyncRequest(request2);
+            public void execute(ReadGraph graph, Object result) throws DatabaseException {
+                graph.syncRequest(request2);
             }
 
             @Override
@@ -66,7 +66,7 @@ public class RequestParentTest4 extends ExistingDatabaseTest {
             }
 
             @Override
-            public void finished(AsyncReadGraph graph) {
+            public void finished(ReadGraph graph) {
             }
 
         });
index 5b261c75cd2f0acf7baff0da3f39ef917c00114e..1e63dc4871578288b3ccd03072394dd41ad01035 100644 (file)
@@ -46,10 +46,10 @@ public class RequestParentTest5 extends SimpleBase {
                
         final Request request = new Request();
         
-        session.syncRequest(new TestReadRequest() {
+        session.syncRequest(new TestAsyncReadRequest() {
 
             @Override
-            public void run(ReadGraph graph) throws Throwable {
+            public void run(AsyncReadGraph graph) throws Throwable {
                 Layer0 l0 = Layer0.getInstance(graph);
                 graph.forEachObject(rl, l0.InstanceOf, new AsyncMultiListener<Resource>() {
 
index 34c73424cb6571478a409a9fb3280c489f79bb6f..1b3d112e0d593dfef8e4951293dfc359b61eae99 100644 (file)
@@ -46,10 +46,10 @@ public class RequestParentTest6 extends SimpleBase {
                
         final Request request = new Request();
         
-        session.syncRequest(new TestReadRequest() {
+        session.syncRequest(new TestAsyncReadRequest() {
 
             @Override
-            public void run(ReadGraph graph) throws Throwable {
+            public void run(AsyncReadGraph graph) throws Throwable {
                 Layer0 l0 = Layer0.getInstance(graph);
                 graph.forEachObject(rl, l0.InstanceOf, new AsyncMultiListener<Resource>() {
 
index 2c89c1ecc11bed2f654ca575cb9d1d7701536f5f..4466f733d8fa128cc2034d3c1087642f418113ed 100644 (file)
@@ -17,7 +17,7 @@ import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.procedure.adapter.ListenerAdapter;
-import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.AsyncReadRequest;
 import org.simantics.db.common.request.ResourceAsyncRead;
 import org.simantics.db.common.request.ResourceRead;
 import org.simantics.db.common.request.UnaryAsyncRead;
@@ -117,10 +117,10 @@ public class RequestProcessorTest1 extends WriteReadTest {
                assertEquals(Layer0.URIs.ConsistsOf, graph.sync(new R4(L0.ConsistsOf)));
                assertEquals("http:/", graph.sync(new R5()));
 
-               graph.sync(new ReadRequest() {
+               graph.syncRequest(new AsyncReadRequest() {
 
                        @Override
-                       public void run(ReadGraph graph) throws DatabaseException {
+                       public void run(AsyncReadGraph graph) {
                                
                                graph.async(new R1(L0.ConsistsOf), listener);
                                graph.async(new R2(L0.ConsistsOf), listener);
index c17e35797c71cc3f7aa3190c0fff0923e14de5ef..188ab6db92f0419b195918adfced238f94664f99 100644 (file)
@@ -17,6 +17,7 @@ import org.junit.Test;
 import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Session;
+import org.simantics.db.common.request.AsyncReadRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.AsyncListener;
 import org.simantics.db.procedure.AsyncProcedure;
@@ -168,10 +169,10 @@ public class RequestQueuingTest extends ExistingDatabaseTest {
                
                Session session = getSession();
                
-               session.syncRequest(new Read<Object>() {
+               session.syncRequest(new AsyncReadRequest() {
 
                        @Override
-                       public Object perform(ReadGraph graph) throws DatabaseException {
+                       public void run(AsyncReadGraph graph) {
 
                                A a = new A();
                                B b = new B();
@@ -182,8 +183,6 @@ public class RequestQueuingTest extends ExistingDatabaseTest {
                                for(int i=0;i<LOOPS;i++) graph.asyncRequest(b, new C());
                                for(int i=0;i<LOOPS;i++) graph.asyncRequest(b2, new C());
 
-                               return null;
-
                        }
 
                });
index 44176e0284d1c1946389016e54ed8d176d946822..5ed3f1482bfb8da5b96a412ae2b06f054e6d13cd 100644 (file)
@@ -39,10 +39,10 @@ public class SyncAsyncSyncTest extends ExistingDatabaseTest {
                final ArrayList<Resource> resources = new ArrayList<Resource>();
                final Resource root = SyncAsyncSyncUtils.createNames(session, names, resources);
 
-               session.syncRequest(new TestReadRequest() {
+               session.syncRequest(new TestAsyncReadRequest() {
 
             @Override
-            public void run(ReadGraph graph) throws Throwable {
+            public void run(AsyncReadGraph graph) throws Throwable {
                 
                 final Layer0 b = Layer0.getInstance(graph);
                 Collection<Resource> rs = graph.getObjects(root, b.ConsistsOf);
index 971a35dd50b71c845377df2ec2c098756e382615..7f79a58fb630e66b7d3f87336290119a8bf556c6 100644 (file)
@@ -40,10 +40,10 @@ public class SyncAsyncSyncTest2 extends ExistingDatabaseTest {
                final ArrayList<Resource> resources = new ArrayList<Resource>();
                final Resource root = SyncAsyncSyncUtils.createNames(session, names, resources);
 
-               session.syncRequest(new TestReadRequest() {
+               session.syncRequest(new TestAsyncReadRequest() {
 
             @Override
-            public void run(ReadGraph graph) throws Throwable {
+            public void run(AsyncReadGraph graph) throws Throwable {
                 
                 final Layer0 b = Layer0.getInstance(graph);
                 Collection<Resource> rs = graph.getObjects(root, b.ConsistsOf);
index 29b682119d8816620cd08a8b354f22002780ccb6..7e50d9a0866fb947c06c9e81d833f1b5a33516cb 100644 (file)
@@ -15,6 +15,7 @@ import java.util.ArrayList;
 import java.util.concurrent.ConcurrentSkipListSet;
 
 import org.junit.Test;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
@@ -34,10 +35,10 @@ public class SyncAsyncSyncTest5 extends ExistingDatabaseTest {
                final ArrayList<Resource> resources = new ArrayList<Resource>();
                final Resource root = SyncAsyncSyncUtils.createNames(session, names, resources);
 
-        session.syncRequest(new TestReadRequest() {
+        session.syncRequest(new TestAsyncReadRequest() {
 
             @Override
-            public void run(ReadGraph graph) {
+            public void run(AsyncReadGraph graph) {
                 
                 Layer0 b = Layer0.getInstance(graph);
                 graph.forObjectSet(root, b.ConsistsOf, new SyncSetListener<Resource>() {
@@ -45,10 +46,10 @@ public class SyncAsyncSyncTest5 extends ExistingDatabaseTest {
                     @Override
                     public void add(ReadGraph graph, final Resource resource) throws DatabaseException {
 
-                        graph.asyncRequest(new TestReadRequest() {
+                        graph.syncRequest(new TestAsyncReadRequest() {
 
                             @Override
-                            public void run(ReadGraph graph) throws DatabaseException {
+                            public void run(AsyncReadGraph graph) throws DatabaseException {
                                 Layer0 b = Layer0.getInstance(graph);
                                 graph.forObjectSet(resource, b.HasName, new SyncSetListener<Resource>() {
                                     
index 3e1d3ff1fc9b6ed5bbee8c1c63aded9d25dd65a8..208062f20dd14a4ece8fb4d36c5b8adf0edf9dd8 100644 (file)
@@ -15,6 +15,7 @@ import java.util.ArrayList;
 import java.util.concurrent.ConcurrentSkipListSet;
 
 import org.junit.Test;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
@@ -34,10 +35,10 @@ public class SyncAsyncSyncTest6 extends ExistingDatabaseTest {
                final ArrayList<Resource> resources = new ArrayList<Resource>();
                final Resource root = SyncAsyncSyncUtils.createNames(session, names, resources);
 
-        session.syncRequest(new TestReadRequest() {
+        session.syncRequest(new TestAsyncReadRequest() {
 
             @Override
-            public void run(ReadGraph graph) {
+            public void run(AsyncReadGraph graph) {
                 Layer0 b = Layer0.getInstance(graph);
                 graph.forObjectSet(root, b.ConsistsOf, new SyncSetListener<Resource>() {
                     
index 4d6b1fb46bab7e51732b3b55639c37343edf1270..9deff6d3431720fbcc07379fcde71e91d5aea01a 100644 (file)
 package org.simantics.db.tests.api.request.misc;
 
 import org.junit.Test;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.Statement;
 import org.simantics.db.common.primitiverequest.PossibleStatement;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.AsyncListener;
 import org.simantics.db.procedure.SyncListener;
 import org.simantics.db.testing.base.ExistingDatabaseTest;
 import org.simantics.layer0.Layer0;
@@ -29,17 +31,17 @@ public class SyncAsyncSyncTest9 extends ExistingDatabaseTest {
                
                Session session = getSession();
                
-        session.syncRequest(new TestReadRequest() {
+        session.syncRequest(new TestAsyncReadRequest() {
 
             @Override
-            public void run(ReadGraph g) throws DatabaseException {
+            public void run(AsyncReadGraph g) throws Throwable {
 
                 final Layer0 b = Layer0.getInstance(g);
 
-                g.forPossibleObject(g.getRootLibrary(), b.InstanceOf, new SyncListener<Resource>() {
+                g.forPossibleObject(g.getRootLibrary(), b.InstanceOf, new AsyncListener<Resource>() {
 
                     @Override
-                    public void execute(ReadGraph graph, Resource type) throws DatabaseException {
+                    public void execute(AsyncReadGraph graph, Resource type) {
 
                         graph.asyncRequest(new PossibleStatement(type, b.InstanceOf), new SyncListener<Statement>() {
 
@@ -104,7 +106,7 @@ public class SyncAsyncSyncTest9 extends ExistingDatabaseTest {
                     }
 
                     @Override
-                    public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException {
+                    public void exception(AsyncReadGraph graph, Throwable throwable) {
                         throwable.printStackTrace();
                         assert(false);
                     }
index 18d6ce537940607764bf3b291b2606d323feb64a..088f15667d6044d344985c66afe24b3a356f1bba 100644 (file)
@@ -21,6 +21,7 @@ import org.simantics.db.Session;
 import org.simantics.db.VirtualGraph;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.WriteOnlyGraph;
+import org.simantics.db.common.request.AsyncReadRequest;
 import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.common.request.WriteOnlyResultRequest;
 import org.simantics.db.common.request.WriteResultRequest;
@@ -28,6 +29,9 @@ import org.simantics.db.exception.AssumptionException;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.AsyncMultiProcedure;
 import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.procedure.SyncContextProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
+import org.simantics.db.procedure.SyncProcedure;
 import org.simantics.db.request.AsyncRead;
 import org.simantics.db.request.Read;
 import org.simantics.db.service.ClusterBuilder;
@@ -688,7 +692,7 @@ public class HierarchicalNames {
                }
        }
        
-       public static Read<Object> readAsync(final Resource resource) {
+       public static AsyncRead<Object> readAsync(final Resource resource) {
                
                if(VALIDATE) {
                        for(int i=0;i<244*64*64;i++) criteria.add("name");
@@ -697,46 +701,46 @@ public class HierarchicalNames {
 
                class Process {
 
-                       final AsyncMultiProcedure<Resource> structure;
-                       final AsyncProcedure<String> names;
+                       final SyncMultiProcedure<Resource> structure;
+                       final SyncProcedure<String> names;
                        
-                       Process(ReadGraph graph, Resource resource) {
+                       Process(ReadGraph graph, Resource resource) throws DatabaseException {
 
                                final Layer0 L0 = Layer0.getInstance(graph);
                                final DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
                                final QueryControl control = graph.getService(QueryControl.class);
                                
-                               names = dqs.compilePossibleRelatedValue(graph, L0.HasName, new AsyncProcedure<String>() {
+                               names = dqs.compilePossibleRelatedValue(graph, L0.HasName, new SyncProcedure<String>() {
 
                                        @Override
-                                       public void execute(AsyncReadGraph graph, String name) {
+                                       public void execute(ReadGraph graph, String name) {
                                                if(VALIDATE) validation.add(name);
 //                                             System.err.println("af=" + name);
                                        }
 
                                        @Override
-                                       public void exception(AsyncReadGraph graph, Throwable throwable) {
+                                       public void exception(ReadGraph graph, Throwable throwable) {
                                                throwable.printStackTrace();
                                        }
 
                                });
                                
-                               structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new AsyncMultiProcedure<Resource>() {
+                               structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new SyncMultiProcedure<Resource>() {
 
                                        @Override
-                                       public void execute(AsyncReadGraph graph, Resource child) {
-                                               if(control.scheduleByCluster(graph, child, this)) {
+                                       public void execute(ReadGraph graph, Resource child) {
+                                               //if(control.scheduleByCluster(graph, child, this)) {
                                                        dqs.forEachObjectCompiled(graph, child, structure);
                                                        dqs.forPossibleRelatedValueCompiled(graph, child, names);
-                                               }
+                                               //}
                                        }
 
                                        @Override
-                                       public void finished(AsyncReadGraph graph) {
+                                       public void finished(ReadGraph graph) {
                                        }
 
                                        @Override
-                                       public void exception(AsyncReadGraph graph, Throwable throwable) {
+                                       public void exception(ReadGraph graph, Throwable throwable) {
                                                throwable.printStackTrace();
                                        }
 
@@ -749,12 +753,16 @@ public class HierarchicalNames {
                        
                }
                
-               return new ReadRequest() {
+               return new AsyncReadRequest() {
                        
                        @Override
-                       public void run(ReadGraph graph) {
+                       public void run(AsyncReadGraph graph) {
 
-                               new Process(graph, resource);
+                               try {
+                                       new Process(graph, resource);
+                               } catch (DatabaseException e) {
+                                       e.printStackTrace();
+                               }
 
                        }
                        
@@ -767,12 +775,12 @@ public class HierarchicalNames {
                graph.forPossibleRelatedValue(resource, L0.HasName, FastStringBinding.INSTANCE, procedure2);
        }
 
-       public static ReadRequest readAsync2(final Resource resource) {
+       public static AsyncReadRequest readAsync2(final Resource resource) {
 
-               return new ReadRequest() {
+               return new AsyncReadRequest() {
 
                        @Override
-                       public void run(ReadGraph graph) {
+                       public void run(AsyncReadGraph graph) {
 
                                final Layer0 L0 = Layer0.getInstance(graph);
                                
@@ -825,21 +833,22 @@ public class HierarchicalNames {
        
        public static void readAsyncTypesLoop(final DirectQuerySupport dqs, final Layer0 L0, AsyncReadGraph graph, final Resource resource, final RelationInfo consistsOf, final AsyncMultiProcedure<Resource> procedure, final RelationInfo name, final Serializer serializer, final AsyncProcedure<String> procedure2) {
                
-               dqs.forPossibleType(graph, resource, new AsyncProcedure<Resource>() {
+               dqs.forPossibleDirectType(graph, resource, dqs, new SyncContextProcedure<DirectQuerySupport, Resource>() {
 
                        @Override
-                       public void execute(AsyncReadGraph graph, Resource type) {
+                       public void execute(ReadGraph graph, DirectQuerySupport dqs, Resource type) {
                                
 //                             System.err.println("affa");
                                
-                               graph.asyncRequest(new TypeSetAndString(type), new AsyncProcedure<Pair<Set<Resource>, String>>() {
+                               try {
+                                       graph.syncRequest(new TypeSetAndString(type), new SyncProcedure<Pair<Set<Resource>, String>>() {
 
-                                       @Override
-                                       public void execute(AsyncReadGraph graph, Pair<Set<Resource>, String> typeInfo) {
-                                               
-                                               Set<Resource> types = typeInfo.first;
-                                               if(types.contains(L0.Ontology)) {
+                                               @Override
+                                               public void execute(ReadGraph graph, Pair<Set<Resource>, String> typeInfo) {
                                                        
+                                                       Set<Resource> types = typeInfo.first;
+                                                       if(types.contains(L0.Ontology)) {
+                                                               
 //                                                     dqs.forPossibleRelatedValue(graph, resource, name, serializer, new AsyncProcedure<String>() {
 //
 //                                                             @Override
@@ -852,25 +861,28 @@ public class HierarchicalNames {
 //                                                             }
 //                                                             
 //                                                     });
+                                                               
+                                                       } else if (types.contains(L0.Library)) {
+                                                               //dqs.forEachObject(graph, resource, consistsOf, procedure);
+                                                       }
                                                        
-                                               } else if (types.contains(L0.Library)) {
-                                                       //dqs.forEachObject(graph, resource, consistsOf, procedure);
                                                }
-                                               
-                                       }
 
-                                       @Override
-                                       public void exception(AsyncReadGraph graph, Throwable throwable) {
-                                       }
-                                       
-                               });
+                                               @Override
+                                               public void exception(ReadGraph graph, Throwable throwable) {
+                                               }
+                                               
+                                       });
+                               } catch (DatabaseException e) {
+                                       e.printStackTrace();
+                               }
                                
                        }
 
                        @Override
-                       public void exception(AsyncReadGraph graph, Throwable throwable) {
+                       public void exception(ReadGraph graph, Throwable throwable) {
                        }
-                       
+
                });
                
                
@@ -895,7 +907,12 @@ public class HierarchicalNames {
 
                                                @Override
                                                public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
-                                                       dqs.forRelationInfo(graph, L0.ConsistsOf, procedure);
+                                                       try {
+                                                               RelationInfo ri = dqs.getRelationInfo(graph, L0.ConsistsOf);
+                                                               procedure.execute(graph, ri);
+                                                       } catch (DatabaseException e) {
+                                                               procedure.exception(graph, e);
+                                                       }
                                                }
 
                                @Override
@@ -913,7 +930,12 @@ public class HierarchicalNames {
 
                                                @Override
                                                public void perform(AsyncReadGraph graph, AsyncProcedure<RelationInfo> procedure) {
-                                                       dqs.forRelationInfo(graph, L0.HasName, procedure);
+                                                       try {
+                                                               RelationInfo ri = dqs.getRelationInfo(graph, L0.HasName);
+                                                               procedure.execute(graph, ri);
+                                                       } catch (DatabaseException e) {
+                                                               procedure.exception(graph, e);
+                                                       }
                                                }
 
                                @Override
index 66e3842e0df12305071307a8891875f27605d588..6e2231fb5d04aa052020945a6d3db52fc8814b30 100644 (file)
@@ -17,6 +17,7 @@ import org.simantics.db.Session;
 import org.simantics.db.common.TransactionPolicyKeep;
 import org.simantics.db.common.procedure.adapter.ListenerAdapter;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.AsyncRead;
 import org.simantics.db.request.Read;
 import org.simantics.db.request.WriteOnlyResult;
 import org.simantics.db.service.ClusterControl;
@@ -80,6 +81,17 @@ public class ReadHierarchicalNames extends ExistingDatabaseTest {
 
        }
 
+       private void time(String label, AsyncRead<Object> request) throws DatabaseException {
+
+               long start = System.nanoTime();
+               getSession().syncRequest(request);
+               long duration = System.nanoTime() - start;
+               System.out.println(label + " = " + 1e-9*duration);
+
+               HierarchicalNames.validate();
+
+       }
+
        private void time(String label, Read<Object> request) throws DatabaseException {
 
                long start = System.nanoTime();
index 768ebf73a8256dbb5629bd0acc432a6139edfca8..1673c89f16f606335d211f39a2193811bd6290aa 100644 (file)
@@ -1,12 +1,13 @@
 package org.simantics.db.tests.regression.bugs;
 
 import org.junit.Test;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.primitiverequest.PossibleObject;
-import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.AsyncReadRequest;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.SyncListener;
@@ -103,51 +104,55 @@ public class SimanticsBug1659Test1 extends ExistingDatabaseTest {
             }
         }
     }
-    class Query extends ReadRequest {
+    class Query extends AsyncReadRequest {
         @Override
-        public void run(ReadGraph g) throws DatabaseException {
-            Layer0 l0 = Layer0.getInstance(g);
-            for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) {
-                if (DEBUG)
-                    System.out.println("Resource " + r);
-                for (Resource rr : g.getObjects(r, l0.ConsistsOf)) {
-//                    if (DEBUG)
-//                        System.out.println("Resource " + rr);
-                       if (!g.isInstanceOf(rr, type))
-                               fail("Resource " + rr + " is not instance of type.");
-                       if (!g.isInstanceOf(rr, l0.Entity))
-                               fail("Resource " + rr + " is not instance of Entity.");
-                       if (USE_LISTENER)
-                           g.forPossibleObject(rr, l0.InstanceOf, new SyncListener<Resource>() {
-       
-                               @Override
-                               public void execute(ReadGraph graph, Resource resource) throws DatabaseException {
-                                       if (DEBUG_LISTENER)
-                                               System.out.println("change " + resource);
-                               }
-       
-                                               @Override
-                                               public void exception(ReadGraph graph, Throwable t)
-                                                               throws DatabaseException {
-                                                       t.printStackTrace();
-                                       fail("Listener got exception: " + t);
-                                               }
-       
-                                               @Override
-                                               public boolean isDisposed() {
-                                                       if (DEBUG_LISTENER)
-                                                               System.out.println("Asked if disposed.");
-                                                       return true;
-                                               }
-                           });
-                    if (USE_LISTENER2) {
-                        g.forPossibleObject(rr, l0.InstanceOf, new Listener(loopCount, listenerCount));
-                    }
-                    if (USE_LISTENER3) {
-                       g.syncRequest(new PossibleObject(rr, l0.InstanceOf), new Listener(loopCount, listenerCount));
-                    }
-                }
-            }
+        public void run(AsyncReadGraph g) {
+               try {
+                       Layer0 l0 = Layer0.getInstance(g);
+                       for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) {
+                               if (DEBUG)
+                                       System.out.println("Resource " + r);
+                               for (Resource rr : g.getObjects(r, l0.ConsistsOf)) {
+                                       //                    if (DEBUG)
+                                       //                        System.out.println("Resource " + rr);
+                                       if (!g.isInstanceOf(rr, type))
+                                               fail("Resource " + rr + " is not instance of type.");
+                                       if (!g.isInstanceOf(rr, l0.Entity))
+                                               fail("Resource " + rr + " is not instance of Entity.");
+                                       if (USE_LISTENER)
+                                               g.forPossibleObject(rr, l0.InstanceOf, new SyncListener<Resource>() {
+
+                                                       @Override
+                                                       public void execute(ReadGraph graph, Resource resource) throws DatabaseException {
+                                                               if (DEBUG_LISTENER)
+                                                                       System.out.println("change " + resource);
+                                                       }
+
+                                                       @Override
+                                                       public void exception(ReadGraph graph, Throwable t)
+                                                                       throws DatabaseException {
+                                                               t.printStackTrace();
+                                                               fail("Listener got exception: " + t);
+                                                       }
+
+                                                       @Override
+                                                       public boolean isDisposed() {
+                                                               if (DEBUG_LISTENER)
+                                                                       System.out.println("Asked if disposed.");
+                                                               return true;
+                                                       }
+                                               });
+                                       if (USE_LISTENER2) {
+                                               g.forPossibleObject(rr, l0.InstanceOf, new Listener(loopCount, listenerCount));
+                                       }
+                                       if (USE_LISTENER3) {
+                                               g.syncRequest(new PossibleObject(rr, l0.InstanceOf), new Listener(loopCount, listenerCount));
+                                       }
+                               }
+                       }
+               } catch (DatabaseException e) {
+                       e.printStackTrace();
+               }
         }
     }
     class Listener implements SyncListener<Resource> {
index 5c44a694c843d09740d4de1e5c5e0ca7847f503b..b7595baed2e78fbf8e7ec03c2b801819677c402d 100644 (file)
@@ -4,13 +4,14 @@ import java.util.UUID;
 
 import org.junit.Test;
 import org.simantics.databoard.Bindings;
+import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.WriteOnlyGraph;
 import org.simantics.db.common.primitiverequest.PossibleObject;
-import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.AsyncReadRequest;
 import org.simantics.db.common.request.WriteOnlyRequest;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.exception.DatabaseException;
@@ -99,9 +100,10 @@ public class SimanticsBug1659Test2 extends ExistingDatabaseTest {
             }
         }
     }
-    class Query extends ReadRequest {
+    class Query extends AsyncReadRequest {
         @Override
-        public void run(ReadGraph g) throws DatabaseException {
+        public void run(AsyncReadGraph g) {
+               try {
             Layer0 l0 = Layer0.getInstance(g);
             for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) {
                 if (DEBUG)
@@ -142,6 +144,9 @@ public class SimanticsBug1659Test2 extends ExistingDatabaseTest {
                     }
                 }
             }
+               } catch (DatabaseException e) {
+                       e.printStackTrace();
+               }
         }
     }
     class Listener implements SyncListener<Resource> {