From 0d9b90834ce56b292c00b1a39850ed842c3e4d42 Mon Sep 17 00:00:00 2001 From: Antti Villberg Date: Fri, 27 Jul 2018 23:33:59 +0300 Subject: [PATCH] Multiple reader thread support for db client gitlab #5 Change-Id: Ia5c189525f2f8277bfc10234c41a1ae47082bb15 --- .../simantics/acorn/cluster/ClusterBig.java | 92 +- .../simantics/acorn/cluster/ClusterSmall.java | 52 +- .../ui/graph/impl/LazyGraphLabeler.java | 3 +- .../graph/impl/LazyParametrizedViewpoint.java | 15 +- .../impl/LazyResourceQueryContainer.java | 16 +- .../browsing/ui/graph/impl/LazyViewpoint.java | 12 +- .../CallbackViewpointContributionImpl.java | 2 +- .../FinalCheckedStateContributionImpl.java | 3 +- .../FinalImageDecoratorContributionImpl.java | 3 +- .../FinalImagerContributionImpl.java | 3 +- .../FinalLabelDecoratorContributionImpl.java | 3 +- .../FinalLabelerContributionImpl.java | 3 +- .../FinalViewpointContributionImpl.java | 2 +- .../ForEachAssertedObject.java | 2 +- .../common/primitiverequest/IsInstanceOf.java | 14 +- .../primitiverequest/PossibleAdapter.java | 51 +- .../primitiverequest/RelationInfoRequest.java | 24 +- .../single/SingleSetSyncListenerDelegate.java | 10 +- .../wrapper/NoneToSyncMultiListener.java | 51 + .../wrapper/NoneToSyncMultiProcedure.java | 46 + .../MergingGraphRequestProcessor.java | 84 +- .../db/common/processor/ProcessorBase.java | 26 +- .../common/request/PossibleTypedParent.java | 60 +- .../request/ResourceAsyncMultiRead.java | 5 - .../db/common/request/ResourceAsyncRead2.java | 3 +- .../uri/UnescapedChildMapOfResource.java | 36 +- .../db/common/utils/CommonDBUtils.java | 6 +- .../db/common/utils/OrderedSetUtils.java | 18 +- .../db/common/utils/Transaction.java | 5 +- .../db/impl/BlockingAsyncMultiProcedure.java | 95 + .../db/impl/BlockingAsyncProcedure.java | 89 + .../src/org/simantics/db/impl/ClusterI.java | 4 +- .../impl/ForEachObjectContextProcedure.java | 17 +- .../db/impl/ForEachObjectProcedure.java | 17 +- ...rPossibleRelatedValueContextProcedure.java | 14 +- .../ForPossibleRelatedValueProcedure.java | 15 +- .../org/simantics/db/impl/TransientGraph.java | 9 +- .../db/impl/graph/AsyncBarrierImpl.java | 30 +- .../db/impl/graph/MultiIntProcedure.java | 6 +- .../db/impl/graph/ReadGraphImpl.java | 702 +--- .../db/impl/graph/ReadGraphSupport.java | 27 +- .../db/impl/graph/WriteGraphImpl.java | 9 +- .../db/impl/procedure/InternalProcedure.java | 5 +- .../ResultCallWrappedSyncQueryProcedure.java | 88 + .../procedure/TripleIntProcedureAdapter.java | 5 +- .../db/impl/query/AssertedPredicates.java | 185 +- .../db/impl/query/AssertedStatements.java | 284 +- .../db/impl/query/AsyncMultiReadEntry.java | 126 +- .../db/impl/query/AsyncReadEntry.java | 255 +- .../simantics/db/impl/query/BinaryQuery.java | 22 +- .../db/impl/query/BinaryQueryHash.java | 48 +- .../simantics/db/impl/query/CacheEntry.java | 11 +- .../db/impl/query/CacheEntryBase.java | 58 +- .../org/simantics/db/impl/query/ChildMap.java | 150 + .../org/simantics/db/impl/query/CodeGen.java | 216 ++ .../db/impl/query/CollectionUnaryQuery.java | 74 +- .../db/impl/query/DirectObjects.java | 230 +- .../db/impl/query/DirectPredicates.java | 159 +- .../db/impl/query/DirectSuperRelations.java | 98 +- .../db/impl/query/DoubleKeyQueryHashMap.java | 4 +- .../db/impl/query/ExternalReadEntry.java | 123 +- .../simantics/db/impl/query/IntProcedure.java | 7 +- .../org/simantics/db/impl/query/IntSet.java | 25 +- .../db/impl/query/MultiReadEntry.java | 95 +- .../db/impl/query/NamespaceIndex.java | 320 -- .../org/simantics/db/impl/query/Objects.java | 481 +-- .../simantics/db/impl/query/OrderedSet.java | 209 +- .../db/impl/query/PossibleSuperRelation.java | 51 +- .../simantics/db/impl/query/Predicates.java | 306 +- .../db/impl/query/PrincipalTypes.java | 304 +- .../org/simantics/db/impl/query/Query.java | 12 +- .../simantics/db/impl/query/QueryCache.java | 1048 ++++++ .../db/impl/query/QueryCacheBase.java | 1215 +++++++ .../db/impl/query/QueryCollectorImpl2.java | 9 +- .../db/impl/query/QueryIdentityHash.java | 25 +- .../db/impl/query/QueryProcessor.java | 2974 ++++++----------- .../simantics/db/impl/query/QuerySupport.java | 5 +- .../simantics/db/impl/query/QueryThread.java | 185 +- .../simantics/db/impl/query/ReadEntry.java | 248 +- .../db/impl/query/RelationInfoQuery.java | 330 +- .../simantics/db/impl/query/Statements.java | 444 +-- .../simantics/db/impl/query/StringQuery.java | 48 +- .../db/impl/query/SuperRelations.java | 307 +- .../simantics/db/impl/query/SuperTypes.java | 230 +- .../db/impl/query/SyncIntProcedure.java | 36 +- .../db/impl/query/ThreadRunnable.java | 7 +- .../db/impl/query/TripleIntProcedure.java | 11 +- .../db/impl/query/TypeHierarchy.java | 200 +- .../org/simantics/db/impl/query/Types.java | 390 +-- .../db/impl/query/URIToResource.java | 267 +- .../simantics/db/impl/query/UnaryQuery.java | 25 +- .../db/impl/query/UnaryQueryHash.java | 26 +- .../simantics/db/impl/query/UnaryQueryP.java | 76 + .../simantics/db/impl/query/ValueQuery.java | 152 +- .../db/layer0/adapter/impl/TGRemover.java | 4 +- .../genericrelation/DependenciesRelation.java | 32 +- .../genericrelation/ExternalRequest.java | 11 +- .../layer0/request/NamespaceRequirements.java | 4 +- .../db/layer0/request/OntologiesForModel.java | 6 +- .../request/combinations/Combinators.java | 48 +- .../db/layer0/util/ConsistsOfProcess.java | 56 +- .../ModelTransferableGraphSourceRequest.java | 6 +- .../procore/internal/ClusterTable.java | 4 +- .../procore/internal/ClusterWriteOnly.java | 4 +- .../internal/CollectionSupportImpl.java | 193 -- .../internal/DirectQuerySupportImpl.java | 538 +-- .../procore/internal/ObjectResourceMap.java | 218 ++ .../procore/internal/QueryControlImpl.java | 2 +- .../procore/internal/QueryDebugImpl.java | 8 +- .../procore/internal/QuerySupportImpl.java | 298 +- .../procore/internal/SessionImplSocket.java | 194 +- .../internal/SessionRequestManager.java | 21 +- .../procore/internal/UndoRedoSupportImpl.java | 2 +- .../db/procore/cluster/ClusterBig.java | 10 +- .../db/procore/cluster/ClusterSmall.java | 17 +- .../simantics/db/procore/cluster/IntHash.java | 8 +- .../db/procore/cluster/ObjectTable.java | 8 +- .../procore/cluster/ResourceElementSmall.java | 8 +- .../db/procore/cluster/ResourceTable.java | 11 +- .../procore/cluster/ResourceTableSmall.java | 8 +- .../db/procore/cluster/TableIntArraySet.java | 8 +- .../db/procore/cluster/TableIntSet.java | 4 +- .../services/adaption/AdaptionService2.java | 52 +- .../reflection/AbstractReflectionAdapter.java | 2 +- .../reflection/ReflectionAdapter2.java | 14 +- .../simantics/db/testing/common/TestBase.java | 40 + .../src/org/simantics/db/AsyncReadGraph.java | 13 +- .../simantics/db/AsyncRequestProcessor.java | 14 +- .../db/AsyncRequestProcessorSpecific.java | 64 +- .../org/simantics/db/ObjectResourceIdMap.java | 10 + .../src/org/simantics/db/ReadGraph.java | 23 +- .../org/simantics/db/RequestProcessor.java | 19 +- .../db/RequestProcessorSpecific.java | 72 +- .../src/org/simantics/db/Session.java | 4 +- .../procedure/SyncContextMultiProcedure.java | 59 + .../db/procedure/SyncContextProcedure.java | 26 + .../simantics/db/request/AsyncMultiRead.java | 2 +- .../org/simantics/db/request/AsyncRead.java | 18 +- .../org/simantics/db/request/MultiRead.java | 3 +- .../src/org/simantics/db/request/Request.java | 14 - .../db/service/DirectQuerySupport.java | 48 +- .../simantics/db/service/QueryControl.java | 2 +- .../diagram/adapter/ConstantStyle.java | 2 +- .../adapter/DiagramContentRequest.java | 174 +- .../adapter/GraphToDiagramSynchronizer.java | 79 +- .../diagram/adapter/MappedTypeGroup.java | 4 +- .../simantics/diagram/adapter/TypeGroup.java | 4 +- .../diagram/profile/DiagramElementGroup.java | 4 +- .../simantics/diagram/profile/StyleBase.java | 3 +- .../runtime/RuntimeDiagramManager.java | 4 +- .../simantics/document/server/Functions.java | 8 +- .../simantics/issues/common/IssueUtils.java | 4 +- .../layer0/utils/queries/QueryExecutor2.java | 7 +- .../diagram/monitor/MonitorClassFactory2.java | 2 +- .../scl/issue/SCLExpressionIssueProvider.java | 7 +- .../subscription/ModelHistoryCollector.java | 2 +- .../simantics/scenegraph/profile/Group.java | 3 +- .../simantics/scenegraph/profile/Style.java | 3 +- .../org/simantics/scl/db/SCLFunctions.java | 6 +- .../simantics/spreadsheet/graph/GraphUI.java | 64 +- .../spreadsheet/ui/SheetFactory.java | 6 +- .../ui/workbench/ResourceEditorInput2.java | 4 +- .../input/InputValidationCombinators.java | 11 +- .../forObjectSet/ForObjectSetTest1.java | 64 +- .../request/misc/AsyncTransactionTest.java | 10 +- .../api/request/misc/RequestParentTest3.java | 5 - .../api/request/misc/RequestParentTest4.java | 16 +- .../api/request/misc/RequestParentTest5.java | 4 +- .../api/request/misc/RequestParentTest6.java | 4 +- .../request/misc/RequestProcessorTest1.java | 6 +- .../api/request/misc/RequestQueuingTest.java | 7 +- .../api/request/misc/SyncAsyncSyncTest.java | 4 +- .../api/request/misc/SyncAsyncSyncTest2.java | 4 +- .../api/request/misc/SyncAsyncSyncTest5.java | 9 +- .../api/request/misc/SyncAsyncSyncTest6.java | 5 +- .../api/request/misc/SyncAsyncSyncTest9.java | 12 +- .../performance/read/HierarchicalNames.java | 102 +- .../read/ReadHierarchicalNames.java | 12 + .../bugs/SimanticsBug1659Test1.java | 95 +- .../bugs/SimanticsBug1659Test2.java | 11 +- 180 files changed, 7844 insertions(+), 9050 deletions(-) create mode 100644 bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/wrapper/NoneToSyncMultiListener.java create mode 100644 bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/wrapper/NoneToSyncMultiProcedure.java create mode 100644 bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncMultiProcedure.java create mode 100644 bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java create mode 100644 bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/ResultCallWrappedSyncQueryProcedure.java create mode 100644 bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java create mode 100644 bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java delete mode 100644 bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/NamespaceIndex.java create mode 100644 bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java create mode 100644 bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java create mode 100644 bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryP.java create mode 100644 bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ObjectResourceMap.java create mode 100644 bundles/org.simantics.db/src/org/simantics/db/ObjectResourceIdMap.java create mode 100644 bundles/org.simantics.db/src/org/simantics/db/procedure/SyncContextMultiProcedure.java create mode 100644 bundles/org.simantics.db/src/org/simantics/db/procedure/SyncContextProcedure.java delete mode 100644 bundles/org.simantics.db/src/org/simantics/db/request/Request.java diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/cluster/ClusterBig.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/cluster/ClusterBig.java index 1de4006a7..063bcf548 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/cluster/ClusterBig.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/cluster/ClusterBig.java @@ -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 procedure, + public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, SyncMultiProcedure 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 void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, AsyncContextMultiProcedure procedure, + public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, SyncContextMultiProcedure 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 procedure) + int predicateKey, SyncMultiProcedure 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 diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/cluster/ClusterSmall.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/cluster/ClusterSmall.java index 117ab75a3..a964c90c9 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/cluster/ClusterSmall.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/cluster/ClusterSmall.java @@ -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 procedure, + public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, SyncMultiProcedure 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 void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, C context, AsyncContextMultiProcedure procedure, + public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, C context, SyncContextMultiProcedure 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 procedure) throws DatabaseException { + int predicateKey, SyncMultiProcedure 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 { diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyGraphLabeler.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyGraphLabeler.java index a7635bedf..639c90391 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyGraphLabeler.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyGraphLabeler.java @@ -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 source = updater.getDataSource(ReadGraph.class); + final DataSource source = updater.getDataSource(AsyncReadGraph.class); assert(source != null); source.schedule(graph -> graph.asyncRequest(labelQuery, procedure)); diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyParametrizedViewpoint.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyParametrizedViewpoint.java index 91aeb9c5d..c5d96a90a 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyParametrizedViewpoint.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyParametrizedViewpoint.java @@ -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 source = updater.getDataSource(ReadGraph.class); + DataSource 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 source = updater.getDataSource(ReadGraph.class); + DataSource source = updater.getDataSource(AsyncReadGraph.class); if (source != null) { - source.schedule(new Consumer() { - @Override - public void accept(ReadGraph source) { - source.asyncRequest(hasChildQuery, hasChildQueryProcedure); - } - }); + source.schedule(graph -> graph.asyncRequest(hasChildQuery, hasChildQueryProcedure)); } } - return hasChildren; } diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyResourceQueryContainer.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyResourceQueryContainer.java index c694ba2e8..808193a18 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyResourceQueryContainer.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyResourceQueryContainer.java @@ -11,14 +11,13 @@ *******************************************************************************/ 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 implements Container source = updater.getDataSource(ReadGraph.class); + final DataSource source = updater.getDataSource(AsyncReadGraph.class); assert(source != null); - source.schedule(new Consumer() { - - @Override - public void accept(ReadGraph source) { - - source.asyncRequest(query, procedure); - - } - - }); + source.schedule(graph -> graph.asyncRequest(query, procedure)); } diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyViewpoint.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyViewpoint.java index a760c848a..a86a172d8 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyViewpoint.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyViewpoint.java @@ -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 source = updater.getDataSource(ReadGraph.class); + DataSource source = updater.getDataSource(AsyncReadGraph.class); final Listener childProcedure = createListener(); - source.schedule(new Consumer() { - @Override - public void accept(ReadGraph source) { - source.asyncRequest(childQuery, childProcedure); - } - }); + source.schedule(graph -> graph.asyncRequest(childQuery, childProcedure)); } return children; diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/CallbackViewpointContributionImpl.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/CallbackViewpointContributionImpl.java index 68bf68913..d6813edbb 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/CallbackViewpointContributionImpl.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/CallbackViewpointContributionImpl.java @@ -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 source = updater.getDataSource(ReadGraph.class); + DataSource source = updater.getDataSource(AsyncReadGraph.class); if (source != null) { source.schedule(graph -> { ReadRequest childQuery = new ReadRequest() { diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalCheckedStateContributionImpl.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalCheckedStateContributionImpl.java index 4c28fae2b..9754fc806 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalCheckedStateContributionImpl.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalCheckedStateContributionImpl.java @@ -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 source = updater.getDataSource(ReadGraph.class); + final DataSource source = updater.getDataSource(AsyncReadGraph.class); assert(source != null); source.schedule(graph -> { diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalImageDecoratorContributionImpl.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalImageDecoratorContributionImpl.java index 6acaffa43..833db059c 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalImageDecoratorContributionImpl.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalImageDecoratorContributionImpl.java @@ -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 source = updater.getDataSource(ReadGraph.class); + final DataSource source = updater.getDataSource(AsyncReadGraph.class); assert(source != null); final Procedure procedure = createProcedure(); diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalImagerContributionImpl.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalImagerContributionImpl.java index b4d233e08..833e6ef19 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalImagerContributionImpl.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalImagerContributionImpl.java @@ -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 source = updater.getDataSource(ReadGraph.class); + final DataSource source = updater.getDataSource(AsyncReadGraph.class); assert(source != null); final Procedure> procedure = createProcedure(); diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalLabelDecoratorContributionImpl.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalLabelDecoratorContributionImpl.java index 345999000..fa1945dff 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalLabelDecoratorContributionImpl.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalLabelDecoratorContributionImpl.java @@ -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 source = updater.getDataSource(ReadGraph.class); + final DataSource source = updater.getDataSource(AsyncReadGraph.class); assert(source != null); final Procedure procedure = createProcedure(); diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalLabelerContributionImpl.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalLabelerContributionImpl.java index b283d662e..ed5688694 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalLabelerContributionImpl.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalLabelerContributionImpl.java @@ -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 source = updater.getDataSource(ReadGraph.class); + final DataSource source = updater.getDataSource(AsyncReadGraph.class); assert(source != null); final Procedure procedure = createProcedure(); diff --git a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalViewpointContributionImpl.java b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalViewpointContributionImpl.java index f514fa48c..e1dbd4f52 100644 --- a/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalViewpointContributionImpl.java +++ b/bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/contribution/FinalViewpointContributionImpl.java @@ -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 source = updater.getDataSource(ReadGraph.class); + DataSource source = updater.getDataSource(AsyncReadGraph.class); if (source != null) { source.schedule(graph -> { if(childProcedure instanceof Listener) diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/ForEachAssertedObject.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/ForEachAssertedObject.java index a71fd1ba6..6e0a3c0b5 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/ForEachAssertedObject.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/ForEachAssertedObject.java @@ -24,7 +24,7 @@ final public class ForEachAssertedObject extends ResourceAsyncMultiRead2 procedure) { - graph.forEachAssertedObject(resource, resource2, procedure); + graph.forEachAssertedObject(resource, resource2, procedure); } } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/IsInstanceOf.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/IsInstanceOf.java index 63a5ddcb3..84e6fdc34 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/IsInstanceOf.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/IsInstanceOf.java @@ -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,20 +11,20 @@ *******************************************************************************/ 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 { +public final class IsInstanceOf extends ResourceRead2 { public IsInstanceOf(Resource resource, Resource resource2) { super(resource, resource2); } @Override - public void perform(AsyncReadGraph graph, AsyncProcedure procedure) { - graph.forIsInstanceOf(resource, resource2, procedure); + public Boolean perform(ReadGraph graph) throws DatabaseException { + return graph.isInstanceOf(resource, resource2); } } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/PossibleAdapter.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/PossibleAdapter.java index 61a47ecb1..81d0f3895 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/PossibleAdapter.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/PossibleAdapter.java @@ -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,53 +11,22 @@ *******************************************************************************/ 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 implements AsyncRead { +public final class PossibleAdapter extends BinaryRead, T> { - final private Resource resource; - final private Class 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 clazz) { - this.resource = resource; - this.clazz = clazz; + super(resource, clazz); } @Override - public void perform(AsyncReadGraph graph, AsyncProcedure 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); } } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/RelationInfoRequest.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/RelationInfoRequest.java index 59a66aeaa..5fbe50113 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/RelationInfoRequest.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/RelationInfoRequest.java @@ -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 { +public final class RelationInfoRequest extends ResourceAsyncRead { public RelationInfoRequest(Resource resource) { super(resource); } - @Override - public void perform(AsyncReadGraph graph, AsyncProcedure 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 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 diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/single/SingleSetSyncListenerDelegate.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/single/SingleSetSyncListenerDelegate.java index 0628507d9..19f1ec42b 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/single/SingleSetSyncListenerDelegate.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/single/SingleSetSyncListenerDelegate.java @@ -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,13 +12,13 @@ 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 extends SingleSetSyncListener { +public abstract class SingleSetSyncListenerDelegate extends SingleSetSyncListener { - 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 index 000000000..9e3178eaa --- /dev/null +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/wrapper/NoneToSyncMultiListener.java @@ -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 implements SyncMultiListener { + + private final MultiListener procedure; + + public NoneToSyncMultiListener(MultiListener 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 index 000000000..7531f9712 --- /dev/null +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/wrapper/NoneToSyncMultiProcedure.java @@ -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 implements SyncMultiProcedure { + + private final MultiProcedure procedure; + + public NoneToSyncMultiProcedure(MultiProcedure 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; + } + +} diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java index bf72e0416..e9523c0c8 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java @@ -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> request, QueryProcedure4 procedure)"); - if (requestSet.contains(request)) + Pair pair = Pair.make(request, procedure); + if (requestSet.contains(pair)) return; - Pair pair = new Pair(request, procedure); requestQueue.add(pair); requestSet.add(pair); @@ -464,10 +464,10 @@ public class MergingGraphRequestProcessor implements RequestProcessor { // System.out.println(this + " asyncRequest(ReadGraphRequest> request, SingleQueryProcedure4 procedure) " + this); - if (requestSet.contains(request)) + Pair pair = Pair.make(request, procedure); + if (requestSet.contains(pair)) return; - Pair pair = new Pair(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 pair = Pair.make(request, callback); + if (requestSet.contains(pair)) return; - Pair pair = new Pair(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 pair = Pair.make(request, callback); + if (requestSet.contains(pair)) return; - Pair pair = new Pair(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 pair = Pair.make(request, callback); + if (requestSet.contains(pair)) return; - Pair pair = new Pair(request, callback); requestQueue.add(pair); requestSet.add(pair); @@ -889,10 +889,10 @@ public class MergingGraphRequestProcessor implements RequestProcessor { public synchronized void asyncRequest(Read request, AsyncProcedure procedure) { - if (requestSet.contains(request)) + Pair pair = Pair.make(request, procedure); + if (requestSet.contains(pair)) return; - Pair pair = new Pair(request, procedure); requestQueue.add(pair); requestSet.add(pair); @@ -917,17 +917,17 @@ public class MergingGraphRequestProcessor implements RequestProcessor { final ArrayList result = new ArrayList(); final DataContainer exception = new DataContainer(); - syncRequest(request, new AsyncMultiProcedureAdapter() { + syncRequest(request, new SyncMultiProcedureAdapter() { @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 Collection syncRequest(MultiRead request, AsyncMultiProcedure procedure) { - throw new UnsupportedOperationException("Not implemented"); - } - @Override public Collection syncRequest(MultiRead request, MultiProcedure procedure) { throw new UnsupportedOperationException("Not implemented"); @@ -967,11 +962,6 @@ public class MergingGraphRequestProcessor implements RequestProcessor { throw new UnsupportedOperationException("Not implemented"); } - @Override - public void asyncRequest(MultiRead request, AsyncMultiProcedure procedure) { - throw new UnsupportedOperationException("Not implemented"); - } - @Override public void asyncRequest(MultiRead request, MultiProcedure procedure) { throw new UnsupportedOperationException("Not implemented"); @@ -1103,12 +1093,6 @@ public class MergingGraphRequestProcessor implements RequestProcessor { } - @Override - public Collection syncRequest(MultiRead arg0, AsyncMultiListener arg1) { - throw new UnsupportedOperationException("Not implemented."); - - } - @Override public Collection syncRequest(MultiRead arg0, SyncMultiListener arg1) { throw new UnsupportedOperationException("Not implemented."); @@ -1153,12 +1137,6 @@ public class MergingGraphRequestProcessor implements RequestProcessor { } - @Override - public void asyncRequest(MultiRead arg0, AsyncMultiListener arg1) { - throw new UnsupportedOperationException("Not implemented."); - - } - @Override public void asyncRequest(MultiRead arg0, SyncMultiListener arg1) { throw new UnsupportedOperationException("Not implemented."); diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java index 6e1aeabaa..1f00ff008 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java @@ -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 void asyncRequest(AsyncMultiRead request, AsyncMultiProcedure procedure) { @@ -173,11 +173,6 @@ public class ProcessorBase implements RequestProcessor { throw new UnsupportedOperationException(); } - @Override - public Collection syncRequest(MultiRead request, AsyncMultiProcedure procedure) { - throw new UnsupportedOperationException(); - } - @Override public Collection syncRequest(MultiRead request, MultiProcedure procedure) { throw new UnsupportedOperationException(); @@ -193,11 +188,6 @@ public class ProcessorBase implements RequestProcessor { throw new UnsupportedOperationException(); } - @Override - public void asyncRequest(MultiRead request, AsyncMultiProcedure procedure) { - throw new UnsupportedOperationException(); - } - @Override public void asyncRequest(MultiRead request, MultiProcedure procedure) { throw new UnsupportedOperationException(); @@ -313,11 +303,6 @@ public class ProcessorBase implements RequestProcessor { throw new UnsupportedOperationException(); } - @Override - public Collection syncRequest(MultiRead arg0, AsyncMultiListener arg1) { - throw new UnsupportedOperationException(); - } - @Override public Collection syncRequest(MultiRead arg0, SyncMultiListener arg1) { throw new UnsupportedOperationException(); @@ -355,11 +340,6 @@ public class ProcessorBase implements RequestProcessor { throw new UnsupportedOperationException(); } - @Override - public void asyncRequest(MultiRead arg0, AsyncMultiListener arg1) { - throw new UnsupportedOperationException(); - } - @Override public void asyncRequest(MultiRead arg0, SyncMultiListener arg1) { throw new UnsupportedOperationException(); diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/PossibleTypedParent.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/PossibleTypedParent.java index 668791821..4a6d0b191 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/PossibleTypedParent.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/PossibleTypedParent.java @@ -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,60 +11,30 @@ *******************************************************************************/ 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 { +public class PossibleTypedParent extends ResourceRead2 { public PossibleTypedParent(Resource resource, Resource type) { super(resource, type); } @Override - public void perform(AsyncReadGraph graph, final AsyncProcedure procedure) { - - final Layer0 l0 = graph.getService(Layer0.class); - - graph.forIsInstanceOf(resource, resource2, new AsyncProcedure() { - - @Override - public void execute(AsyncReadGraph graph, Boolean isInstance) { - if(isInstance) { - procedure.execute(graph, resource); - } else { - - graph.forPossibleObject(resource, l0.PartOf, new AsyncProcedure() { - - @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; } - }); - - + } } } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceAsyncMultiRead.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceAsyncMultiRead.java index 4e51a0997..4d15bd5f3 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceAsyncMultiRead.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceAsyncMultiRead.java @@ -22,11 +22,6 @@ public abstract class ResourceAsyncMultiRead implements AsyncMultiRead { public int hashCode() { return resource.hashCode(); } - - @Override - final public int threadHash() { - return resource.getThreadHash(); - } @Override public boolean equals(Object object) { diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceAsyncRead2.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceAsyncRead2.java index ae40ad4ac..1b13285d8 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceAsyncRead2.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceAsyncRead2.java @@ -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 implements AsyncRead, Request, ReadInterface { +public abstract class ResourceAsyncRead2 implements AsyncRead, ReadInterface { final protected Resource resource; final protected Resource resource2; diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/uri/UnescapedChildMapOfResource.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/uri/UnescapedChildMapOfResource.java index f9517f7bb..7713535b5 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/uri/UnescapedChildMapOfResource.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/uri/UnescapedChildMapOfResource.java @@ -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,46 +11,22 @@ *******************************************************************************/ 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> { - private static final Logger LOGGER = LoggerFactory.getLogger(UnescapedChildMapOfResource.class); - public UnescapedChildMapOfResource(Resource resource) { - super(resource); + super(resource); } - + @Override public Map perform(ReadGraph graph) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - Collection objects = graph.getObjects(resource, L0.ConsistsOf); - CollectionSupport cs = graph.getService(CollectionSupport.class); - Map 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); + } + } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/CommonDBUtils.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/CommonDBUtils.java index 2e16b2849..77eacf205 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/CommonDBUtils.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/CommonDBUtils.java @@ -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(); } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java index eb0ca24b6..143d3e443 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java @@ -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 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. */ diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/Transaction.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/Transaction.java index 9e5d563a5..96d915482 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/Transaction.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/Transaction.java @@ -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 index 000000000..cc50ea9b8 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncMultiProcedure.java @@ -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 implements AsyncMultiProcedure { + + private static final Object NO_RESULT = new Object(); + + private final Object key; + private final ReadGraphImpl graph; + private final AsyncMultiProcedure procedure; + + private Object result = NO_RESULT; + private Throwable exception = null; + + public BlockingAsyncMultiProcedure(ReadGraphImpl graph, AsyncMultiProcedure 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 index 000000000..4ae530317 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java @@ -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 implements AsyncProcedure { + + private static final Object NO_RESULT = new Object(); + + private final Object key; + private final ReadGraphImpl graph; + private final AsyncProcedure procedure; + + private Object result = NO_RESULT; + private Throwable exception = null; + + public BlockingAsyncProcedure(ReadGraphImpl graph, AsyncProcedure 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; + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ClusterI.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ClusterI.java index 87acea43d..a82a7490f 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ClusterI.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ClusterI.java @@ -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 int getSingleObject(int resourceKey, ForPossibleRelatedValueContextProcedure procedure, ClusterSupport support) throws DatabaseException; - public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, AsyncMultiProcedure procedure) + public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, SyncMultiProcedure procedure) throws DatabaseException; public void forObjects(ReadGraphImpl graph, int resourceKey, ForEachObjectProcedure procedure) diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectContextProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectContextProcedure.java index 188917994..6bec3b707 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectContextProcedure.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectContextProcedure.java @@ -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 implements AsyncContextMultiProcedure { +public final class ForEachObjectContextProcedure implements SyncContextMultiProcedure { public final int predicateKey; public final int[] clusterKey; @@ -14,9 +15,9 @@ public final class ForEachObjectContextProcedure implements AsyncContextMulti public final RelationInfo info; public final QueryProcessor processor; public final ClusterI.CompleteTypeEnum completeType; - private final AsyncContextMultiProcedure user; + private final SyncContextMultiProcedure user; - public ForEachObjectContextProcedure(int predicateKey, RelationInfo info, QueryProcessor processor, AsyncContextMultiProcedure user) { + public ForEachObjectContextProcedure(int predicateKey, RelationInfo info, QueryProcessor processor, SyncContextMultiProcedure user) { this.predicateKey = predicateKey; this.completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); this.info = info; @@ -27,17 +28,17 @@ public final class ForEachObjectContextProcedure 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); } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectProcedure.java index 85790c4de..143d0a186 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectProcedure.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectProcedure.java @@ -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 { +public final class ForEachObjectProcedure implements SyncMultiProcedure { public final int predicateKey; public final int[] clusterKey; @@ -14,9 +15,9 @@ public final class ForEachObjectProcedure implements AsyncMultiProcedure user; + private final SyncMultiProcedure user; - public ForEachObjectProcedure(int predicateKey, RelationInfo info, QueryProcessor processor, AsyncMultiProcedure user) { + public ForEachObjectProcedure(int predicateKey, RelationInfo info, QueryProcessor processor, SyncMultiProcedure user) { this.predicateKey = predicateKey; this.completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); this.info = info; @@ -27,17 +28,17 @@ public final class ForEachObjectProcedure implements AsyncMultiProcedure implements AsyncContextProcedure { +public final class ForPossibleRelatedValueContextProcedure implements SyncContextProcedure { public final int predicateKey; public final int[] clusterKey; public final int[] predicateReference; public final RelationInfo info; public final ClusterI.CompleteTypeEnum completeType; - private final AsyncContextProcedure user; + private final SyncContextProcedure user; - public ForPossibleRelatedValueContextProcedure(int predicateKey, RelationInfo info, AsyncContextProcedure user) { + public ForPossibleRelatedValueContextProcedure(int predicateKey, RelationInfo info, SyncContextProcedure user) { this.predicateKey = predicateKey; this.completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); this.info = info; @@ -23,12 +23,12 @@ public final class ForPossibleRelatedValueContextProcedure 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); } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForPossibleRelatedValueProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForPossibleRelatedValueProcedure.java index 6dcb0ea10..bd5e0ccaa 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForPossibleRelatedValueProcedure.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForPossibleRelatedValueProcedure.java @@ -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 implements AsyncProcedure { +public final class ForPossibleRelatedValueProcedure implements SyncProcedure { public final int predicateKey; public final int[] clusterKey; public final int[] predicateReference; public final RelationInfo info; public final ClusterI.CompleteTypeEnum completeType; - private final AsyncProcedure user; + private final SyncProcedure user; - public ForPossibleRelatedValueProcedure(int predicateKey, RelationInfo info, AsyncProcedure user) { + public ForPossibleRelatedValueProcedure(int predicateKey, RelationInfo info, SyncProcedure user) { this.predicateKey = predicateKey; this.completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); this.info = info; @@ -23,12 +24,12 @@ public final class ForPossibleRelatedValueProcedure 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); } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/TransientGraph.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/TransientGraph.java index f4e722fe5..f48a64e58 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/TransientGraph.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/TransientGraph.java @@ -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; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java index 7184acbc5..229c3d6a9 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java @@ -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; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/MultiIntProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/MultiIntProcedure.java index 4695b8b33..0f0ad8319 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/MultiIntProcedure.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/MultiIntProcedure.java @@ -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 procedure; + final private SyncMultiProcedure procedure; final private ReadGraphImpl impl; final private QuerySupport support; - public MultiIntProcedure(AsyncMultiProcedure procedure, ReadGraphImpl impl, QuerySupport support) { + public MultiIntProcedure(SyncMultiProcedure procedure, ReadGraphImpl impl, QuerySupport support) { this.procedure = procedure; this.impl = impl; this.support = support; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java index 614a96df3..b5da0b92f 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java @@ -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 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 procedure = new AsyncReadProcedure(); - syncRequest(request, procedure); - procedure.checkAndThrow(); - return procedure.result; - -// return syncRequest(request, new AsyncProcedureAdapter()); + asyncBarrier = new AsyncBarrierImpl(null); + BlockingAsyncProcedure 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 wrapper = new ResultCallWrappedSingleQueryProcedure4( - 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 wrapper = new ResultCallWrappedSingleQueryProcedure4( - procedure, request); - - try { - - processor.tryQuery(this, request, wrapper); - - } catch (Throwable t) { - - wrapper.exception(this, t); - - } + BlockingAsyncProcedure 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 ap = new BlockingAsyncProcedure<>(this, procedure, request); -// final ReadGraphImpl newGraph = newSync(); - - final ResultCallWrappedSingleQueryProcedure4 wrapper = new ResultCallWrappedSingleQueryProcedure4( - 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.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 result = new ArrayList(); final DataContainer exception = new DataContainer(); - syncRequest(request, new AsyncMultiProcedure() { + syncRequest(request, new SyncMultiProcedure() { @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 Collection syncRequest(MultiRead request, - AsyncMultiListener procedure) { - return syncRequest(request, (AsyncMultiProcedure) procedure); - } - @Override public Collection syncRequest(MultiRead request, SyncMultiListener procedure) { - return syncRequest(request, new SyncToAsyncMultiListener(procedure)); + return syncRequest(request, (SyncMultiProcedure)procedure); } @Override public Collection syncRequest(MultiRead request, MultiListener procedure) { - return syncRequest(request, new NoneToAsyncMultiListener(procedure)); + return syncRequest(request, new NoneToSyncMultiListener(procedure)); } @Override public Collection syncRequest(MultiRead request, - AsyncMultiProcedure procedure) { + SyncMultiProcedure procedure) { assert (request != null); ListenerBase listener = getListenerBase(procedure); + final ResultCallWrappedSyncQueryProcedure wrapper = new ResultCallWrappedSyncQueryProcedure(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 wrapper = new ResultCallWrappedQueryProcedure4(procedure); - try { - request.perform(this, wrapper); - } catch (Throwable t) { - wrapper.exception(this, t); -// newGraph.waitAsync(syncParent); - } } - // TODO - return null; - - } + return wrapper.get(); - @Override - public Collection syncRequest(MultiRead request, - SyncMultiProcedure procedure) { - return syncRequest(request, new SyncToAsyncMultiProcedure(procedure)); } @Override public Collection syncRequest(MultiRead request, MultiProcedure procedure) { - return syncRequest(request, new NoneToAsyncMultiProcedure(procedure)); + return syncRequest(request, new NoneToSyncMultiProcedure(procedure)); } static class AsyncMultiReadProcedure extends ArrayList implements AsyncMultiProcedure { @@ -2542,70 +2412,10 @@ public class ReadGraphImpl implements ReadGraph { final public T syncRequest(final ExternalRead request, final Procedure procedure) throws DatabaseException { - assert (request != null); - - ListenerBase listener = getListenerBase(procedure); - - final DataContainer exception = new DataContainer(); - final DataContainer result = new DataContainer(); - - if (parent != null || listener != null) { - -// final ReadGraphImpl newGraph = newSync(); - - processor.query(this, request, parent, new Procedure() { - - @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 procedure) { -// -// processor.forEachDirectObject(this, subject, relation, procedure); -// -// } -// -// @Override -// public void forEachDirectObject(Resource subject, Resource relation, -// SyncMultiProcedure procedure) { -// forEachDirectObject(subject, relation, -// new SyncToAsyncMultiProcedure(procedure)); -// } -// -// @Override -// public void forEachDirectObject(Resource subject, Resource relation, -// MultiProcedure procedure) { -// forEachDirectObject(subject, relation, -// new NoneToAsyncMultiProcedure(procedure)); -// } - @Override - final public void forEachDirectPredicate(final Resource subject, final AsyncMultiProcedure procedure) { + final public void forEachDirectPredicate(final Resource subject, final AsyncProcedure> procedure) { processor.forEachDirectPredicate(this, subject, procedure); } @Override - public void forEachDirectPredicate(Resource subject, SyncMultiProcedure procedure) { - forEachDirectPredicate(subject, new SyncToAsyncMultiProcedure(procedure)); + final public void forEachDirectPredicate(final Resource subject, final SyncProcedure> procedure) { + forEachDirectPredicate(subject, new SyncToAsyncProcedure>(procedure)); } @Override - public void forEachDirectPredicate(Resource subject, MultiProcedure procedure) { - forEachDirectPredicate(subject, new NoneToAsyncMultiProcedure(procedure)); + public void forEachDirectPredicate(Resource subject, Procedure> procedure) { + forEachDirectPredicate(subject, new NoneToAsyncProcedure>(procedure)); } @Override @@ -4655,14 +4442,6 @@ public class ReadGraphImpl implements ReadGraph { listener); } -// @Override -// final public void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding, -// final AsyncProcedure procedure) { -// -// forPossibleRelatedValue(subject, relation, binding, procedure, false); -// -// } - final public void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding, final AsyncProcedure procedure) { @@ -5351,11 +5130,6 @@ public class ReadGraphImpl implements ReadGraph { return processor.getSession(); } -// @Override -// final public Builtins getBuiltins() { -// return processor.getSession().getBuiltins(); -// } - @Override public void asyncRequest(final Read 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 void asyncRequest(Read request, SyncProcedure procedure) { asyncRequest(request, new SyncToAsyncProcedure(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(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() { + asyncRequest(request, new SyncMultiProcedureAdapter() { @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 void asyncRequest(MultiRead request, - AsyncMultiListener procedure) { - asyncRequest(request, (AsyncMultiProcedure) procedure); - } - @Override public void asyncRequest(MultiRead request, SyncMultiListener procedure) { - asyncRequest(request, new SyncToAsyncMultiListener(procedure)); + asyncRequest(request, (SyncMultiProcedure)procedure); } @Override public void asyncRequest(MultiRead request, MultiListener procedure) { - asyncRequest(request, new NoneToAsyncMultiListener(procedure)); + asyncRequest(request, new NoneToSyncMultiListener(procedure)); } + @Override public void asyncRequest(final MultiRead request, - final AsyncMultiProcedure procedure) { + final SyncMultiProcedure 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 void asyncRequest(MultiRead request, - SyncMultiProcedure procedure) { - asyncRequest(request, new SyncToAsyncMultiProcedure(procedure)); - } - @Override public void asyncRequest(MultiRead request, MultiProcedure procedure) { - asyncRequest(request, new NoneToAsyncMultiProcedure(procedure)); + asyncRequest(request, new NoneToSyncMultiProcedure(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() { - - @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() { + @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 void waitAsyncProcedure(AsyncReadProcedure 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 syncGraph = new ThreadLocal() { + 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()); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphSupport.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphSupport.java index dea87d54e..f8d42fba5 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphSupport.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphSupport.java @@ -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 procedure); void forEachObject(ReadGraphImpl graph, Resource subject, Resource predicate, MultiProcedure procedure); void forEachObject(ReadGraphImpl graph, Resource subject, Resource predicate, AsyncMultiProcedure procedure); - void forEachDirectPredicate(ReadGraphImpl graph, Resource subject, AsyncMultiProcedure procedure); - void forEachDirectStatement(ReadGraphImpl graph, Resource subject, Procedure procedure); - void forEachDirectStatement(ReadGraphImpl graph, Resource subject, AsyncProcedure procedure, boolean ignoreVirtual); + void forEachDirectPredicate(ReadGraphImpl graph, Resource subject, AsyncProcedure> procedure); void forObjectSet(ReadGraphImpl graph, Resource subject, Resource predicate, AsyncSetListener procedure); void forPredicateSet(ReadGraphImpl graph, Resource subject, AsyncSetListener procedure); void forPrincipalTypeSet(ReadGraphImpl graph, Resource subject, AsyncSetListener procedure); @@ -64,7 +58,8 @@ public interface ReadGraphSupport { void forEachPrincipalType(ReadGraphImpl graph, Resource subject, AsyncMultiProcedure procedure); void forEachPrincipalType(ReadGraphImpl graph, Resource subject, MultiProcedure procedure); - void forRelationInfo(ReadGraphImpl graph, Resource subject, AsyncProcedure procedure); + RelationInfo getRelationInfo(ReadGraphImpl graph, Resource subject) throws DatabaseException; + void forTypes(ReadGraphImpl graph, Resource subject, AsyncProcedure> procedure); IntSet getTypes(ReadGraphImpl graph, Resource subject) throws Throwable; void forSupertypes(ReadGraphImpl graph, Resource subject, AsyncProcedure> procedure); @@ -72,7 +67,7 @@ public interface ReadGraphSupport { void forPossibleSuperrelation(ReadGraphImpl graph, Resource subject, AsyncProcedure procedure); void forSuperrelations(ReadGraphImpl graph, Resource subject, AsyncProcedure> procedure); byte[] getValue(ReadGraphImpl graph, Resource subject) throws DatabaseException; - byte[] forValue(ReadGraphImpl graph, Resource subject, AsyncProcedure procedure); + void forValue(ReadGraphImpl graph, Resource subject, AsyncProcedure procedure); void forPossibleValue(ReadGraphImpl graph, Resource subject, AsyncProcedure procedure); void forInverse(ReadGraphImpl graph, Resource relation, AsyncProcedure procedure); void forResource(ReadGraphImpl graph, String id, AsyncProcedure procedure); @@ -85,15 +80,9 @@ public interface ReadGraphSupport { void forHasValue(ReadGraphImpl graph, Resource subject, AsyncProcedure procedure); void forOrderedSet(ReadGraphImpl graph, Resource subject, AsyncMultiProcedure procedure); - T queryRead(ReadGraphImpl graph, Read request, CacheEntry parent, AsyncProcedure procedure, ListenerBase listener) throws Throwable; - void query(ReadGraphImpl graph, MultiRead request, CacheEntry parent, AsyncMultiProcedure procedure, ListenerBase listener); - void query(ReadGraphImpl graph, AsyncRead request, CacheEntry parent, AsyncProcedure procedure, ListenerBase listener); + void query(ReadGraphImpl graph, MultiRead request, CacheEntry parent, SyncMultiProcedure procedure, ListenerBase listener); void query(ReadGraphImpl graph, AsyncMultiRead request, CacheEntry parent, AsyncMultiProcedure procedure, ListenerBase listener); - void query(ReadGraphImpl graph, ExternalRead request, CacheEntry parent, Procedure procedure, ListenerBase listener); - - T tryQuery(final ReadGraphImpl graph, final Read request) throws DatabaseException; - void tryQuery(final ReadGraphImpl graph, final AsyncRead request, final AsyncProcedure procedure); - + VirtualGraph getProvider(Resource subject, Resource predicate, Resource object); VirtualGraph getProvider(Resource subject, Resource predicate); VirtualGraph getValueProvider(Resource subject); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java index ca485f989..56fb9ec72 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java @@ -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())) { diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/InternalProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/InternalProcedure.java index aa6425a8c..18345d632 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/InternalProcedure.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/InternalProcedure.java @@ -11,13 +11,14 @@ *******************************************************************************/ package org.simantics.db.impl.procedure; +import org.simantics.db.exception.DatabaseException; import org.simantics.db.impl.graph.ReadGraphImpl; public interface InternalProcedure { - 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 index 000000000..d2034fb08 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/ResultCallWrappedSyncQueryProcedure.java @@ -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 implements SyncMultiProcedure { + + private final ArrayList result; + private Throwable exception = null; + private final SyncMultiProcedure procedure; + private final AtomicBoolean latch; + + public ResultCallWrappedSyncQueryProcedure(SyncMultiProcedure procedure) { + this.procedure = procedure; + latch = new AtomicBoolean(false); + result = new ArrayList(); + } + + @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 get() { + return result; + } + + public Throwable getException() { + return exception; + } + + @Override + public String toString() { + return "ResultCallWrappedQueryProcedure4[" + procedure + "]"; + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/TripleIntProcedureAdapter.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/TripleIntProcedureAdapter.java index 44e7aa38c..9bb96a836 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/TripleIntProcedureAdapter.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/TripleIntProcedureAdapter.java @@ -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 { } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java index af8858e5a..b4104e965 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java @@ -11,120 +11,70 @@ *******************************************************************************/ 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 { - -// public ArrayList procs = null; +final public class AssertedPredicates extends UnaryQuery { - 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(); -// 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 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 } @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 }); - 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 assert(!isReady()); -// ArrayList 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 } - final static InternalProcedure ip = new InternalProcedure() { - - @Override - public void execute(ReadGraphImpl graph, RelationInfo result) { - } - - @Override - public void exception(ReadGraphImpl graph, Throwable throwable) { - } - - }; - - final static InternalProcedure ip2 = new InternalProcedure() { - - @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 } @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 } @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); - } + }); } - } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatements.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatements.java index 41b8e08d5..8649de32e 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatements.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatements.java @@ -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,22 +11,19 @@ *******************************************************************************/ 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 { -// public ArrayList procs; - public AssertedStatements(final int r1, final int r2) { super(r1, r2); } @@ -34,82 +31,20 @@ final public class AssertedStatements extends CollectionBinaryQuery(); -// 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 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 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 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() { + QueryCache.runnerSuperRelations(graph, pred, entry, null, new InternalProcedure() { @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() { + QueryCache.runnerSuperRelations(graph, pred, entry, null, new InternalProcedure() { @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() { - - @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 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 extends CacheEntryBase { +final public class AsyncMultiReadEntry extends CacheEntryBase> { -// public ArrayList> procs = null; + private static final Logger LOGGER = LoggerFactory.getLogger(AsyncMultiReadEntry.class); protected AsyncMultiRead request; - public AsyncMultiReadEntry(AsyncMultiRead request) { + AsyncMultiReadEntry(AsyncMultiRead request) { this.request = request; } @@ -49,55 +52,22 @@ final public class AsyncMultiReadEntry extends CacheEntryBase { final synchronized public void finish(AsyncReadGraph graph) { -// new Exception("finish " + this).printStackTrace(); - - if(!isPending()) { - System.err.println("aff"); - } - assert(isPending()); -// ArrayList> p = null; - synchronized(this) { - setReady(); -// p = procs; -// procs = null; - } -// if(p != null) { -// ArrayList v = (ArrayList)getResult(); -// if(v != null) { -// for(AsyncMultiProcedure proc : p) { -// for(T t : v) proc.execute(graph, t); -// } -// } -// -// for(AsyncMultiProcedure proc : p) proc.finished(graph); -// } - } final synchronized public void except(AsyncReadGraph graph, Throwable t) { assert(isPending()); -// ArrayList> p = null; - synchronized(this) { - except(t); -// p = procs; -// procs = null; - } -// if(p != null) { -// for(AsyncMultiProcedure proc : p) proc.exception(graph, t); -// } - } @SuppressWarnings("unchecked") @@ -121,42 +91,43 @@ final public class AsyncMultiReadEntry 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() { + BlockingAsyncMultiProcedure proc = new BlockingAsyncMultiProcedure<>(graph, new AsyncMultiProcedure() { - @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 extends CacheEntryBase { @SuppressWarnings("unchecked") @Override - public void performFromCache(ReadGraphImpl graph, Object provider, Object procedure) { - - final AsyncMultiProcedure proc = (AsyncMultiProcedure)procedure; + public Object performFromCache(ReadGraphImpl graph, AsyncMultiProcedure proc) { if(isExcepted()) { try { proc.exception(graph, (Throwable)getResult()); } catch (Throwable t) { - t.printStackTrace(); + LOGGER.error("performFromCache proc.exception failed", t); } - - + } else { - + final ArrayList values = (ArrayList)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 extends CacheEntryBase { else return request.toString() + statusOrException; } + public Object compute(ReadGraphImpl graph, AsyncMultiProcedure 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/AsyncReadEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncReadEntry.java index a9726a75d..00abbebf6 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncReadEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncReadEntry.java @@ -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,169 +12,200 @@ 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 extends CacheEntryBase { +final public class AsyncReadEntry extends CacheEntryBase> implements AsyncProcedure { + + private static final Logger LOGGER = LoggerFactory.getLogger(AsyncReadEntry.class); protected AsyncRead request; - public AsyncReadEntry(AsyncRead request) { - this.request = request; - if(DebugPolicy.QUERY_STATE) System.out.println("[QUERY STATE]: created " + this); + AsyncReadEntry(AsyncRead 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> p = null; - - synchronized(this) { - - setResult(item); - setReady(); -// p = procs; -// procs = null; - - } -// if(p != null) -// for(AsyncProcedure 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> p = null; - synchronized(this) { - + assert (isPending()); + + synchronized (this) { except(t); -//// p = procs; -// procs = null; - } -// if(p != null) -// for(AsyncProcedure 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() { + BlockingAsyncProcedure proc = new BlockingAsyncProcedure<>(graph, new AsyncProcedure() { @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 proc = (AsyncProcedure)procedure; + @Override + public Object performFromCache(ReadGraphImpl graph, AsyncProcedure 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 void computeForEach(ReadGraphImpl parentGraph, AsyncRead request, AsyncReadEntry entry, + AsyncProcedure procedure_) throws DatabaseException { + + AsyncProcedure procedure = entry != null ? entry : procedure_; + + ReadGraphImpl queryGraph = parentGraph.withParent(entry); + + BlockingAsyncProcedure proc = new BlockingAsyncProcedure<>(queryGraph, new AsyncProcedure() { + + @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); + } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQuery.java index cb2df4eea..d699ea825 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQuery.java @@ -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,11 +11,9 @@ *******************************************************************************/ package org.simantics.db.impl.query; -import org.simantics.db.impl.graph.ReadGraphImpl; import org.simantics.db.request.RequestFlags; - -abstract public class BinaryQuery extends CacheEntryBase implements Query { +public abstract class BinaryQuery extends CacheEntryBase implements Query { final public long id; @@ -65,23 +63,7 @@ abstract public class BinaryQuery 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 getEntry(QueryProcessor provider); } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQueryHash.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQueryHash.java index f09ccc082..b460a22bd 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQueryHash.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQueryHash.java @@ -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 extends THash { protected final BinaryQuery REMOVED = new BinaryQuery(-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 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!"); } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntry.java index d65622dad..848925622 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntry.java @@ -16,7 +16,7 @@ import org.simantics.db.impl.graph.ReadGraphImpl; -public abstract class CacheEntry { +public abstract class CacheEntry { 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 getResult(); abstract CacheEntry pruneFirstParents(); abstract void removeParent(CacheEntry entry); abstract void addParent(CacheEntry entry); abstract boolean hasParents(); - abstract Iterable getParents(QueryProcessor processor); + abstract Iterable> 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 getResult(); + abstract void setResult(Object result); + + abstract Object performFromCache(ReadGraphImpl graph, Procedure procedure) throws DatabaseException; abstract boolean isImmutable(ReadGraphImpl graph) throws DatabaseException; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntryBase.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntryBase.java index d30d59320..7c87b50e3 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntryBase.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CacheEntryBase.java @@ -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 extends CacheEntry { 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 getParents(QueryProcessor processor) { + final public Iterable> getParents(QueryProcessor processor) { - ArrayList result = new ArrayList(); + ArrayList> result = new ArrayList>(); 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 result) { - + protected void fillImpliedParents(QueryProcessor processor, ArrayList> 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 boolean handleException(ReadGraphImpl graph, InternalProcedure procedure) { + protected boolean handleException(ReadGraphImpl graph, InternalProcedure 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 index 000000000..8effbb1d5 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java @@ -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> { + + 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> procedure) + throws DatabaseException { + computeForEach(graph, id, this, procedure); + } + + public static void computeForEach(ReadGraphImpl graph, final int root, final ChildMap entry, + final InternalProcedure> procedure_) throws DatabaseException { + + InternalProcedure> 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> 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 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() { + + @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 index 000000000..89892ed56 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/CodeGen.java @@ -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", "entry.id" }; + String[] signatureR1Bytes = { "int r", "r", "keyR", "long", "InternalProcedure", "entry.id" }; + String[] signatureR1IntSet = { "int r", "r", "keyR", "long", "InternalProcedure", "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", "entry.id" }; + String[] signatureID2 = { "String id", "id", "keyID", "String", "InternalProcedure>", "entry.id" }; + String[] signatureChildMap = { "int r", "r", "keyR", "long", "InternalProcedure>", "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 extends UnaryQuery { +public abstract class CollectionUnaryQuery extends UnaryQuery 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 extends UnaryQuery { 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); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjects.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjects.java index 2c106476e..9bcb6ddb8 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjects.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjects.java @@ -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,190 +11,124 @@ *******************************************************************************/ 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 { +final public class DirectObjects extends CollectionBinaryQuery 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 entries(final QueryProcessor processor, final int r1) { - DoubleKeyQueryHashMap 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 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); } - -} +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java index 606afa430..1a006369a 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java @@ -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,104 +11,34 @@ *******************************************************************************/ 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 { +public final class DirectPredicates extends UnaryQueryP { - 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 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 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 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 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 { }); - 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 { 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); - } - } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectSuperRelations.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectSuperRelations.java index c11e9f262..47db3c8d8 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectSuperRelations.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectSuperRelations.java @@ -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,43 +11,26 @@ *******************************************************************************/ 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 { +import gnu.trove.procedure.TIntProcedure; +import gnu.trove.set.hash.TIntHashSet; - public ArrayList> procs = null; +public final class DirectSuperRelations extends UnaryQuery { - 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 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 { } - // 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 { } - @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 { 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 { @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 { @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(); + } + + }); } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DoubleKeyQueryHashMap.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DoubleKeyQueryHashMap.java index f1aa887bb..d59f5beb8 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DoubleKeyQueryHashMap.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DoubleKeyQueryHashMap.java @@ -193,9 +193,9 @@ public class DoubleKeyQueryHashMap extends DoubleKeyQueryHash values() { + final public ArrayList values() { - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList(); for (int i = _set.length; i-- > 0;) { if(_set[i] != null && _set[i] != REMOVED) { diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java index 18d91dc06..d61049744 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java @@ -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,19 +11,18 @@ *******************************************************************************/ 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 extends CacheEntryBase { +final public class ExternalReadEntry extends CacheEntryBase> { final LinkedList items = new LinkedList(); - -// public ArrayList> procs; protected ExternalRead request; @@ -47,6 +46,15 @@ final public class ExternalReadEntry 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 request) { assert request != null; @@ -67,7 +75,7 @@ final public class ExternalReadEntry extends CacheEntryBase { assert(isPending()); - ArrayList> p = null; + //ArrayList> p = null; synchronized(this) { @@ -89,43 +97,53 @@ final public class ExternalReadEntry 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 extends CacheEntryBase { } - public void performFromCache(Object procedure) { - - Procedure proc = (Procedure)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 procedure) { + + AsyncProcedure proc = (AsyncProcedure)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 extends CacheEntryBase { // Do nothing - the state is already set and cannot be recomputed on demand } + public Object compute(ReadGraphImpl graph, AsyncProcedure 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/IntProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntProcedure.java index 0a9ccad90..4a7bbdb28 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntProcedure.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntProcedure.java @@ -11,13 +11,14 @@ *******************************************************************************/ 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; } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntSet.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntSet.java index 7c32b8e59..3ef19b8f3 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntSet.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntSet.java @@ -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 extends CacheEntryBase { +public final class MultiReadEntry extends CacheEntryBase> { -// public ArrayList, AsyncBarrier>> procs; + private static final Logger LOGGER = LoggerFactory.getLogger(MultiReadEntry.class); protected MultiRead request; - public MultiReadEntry(MultiRead request) { + MultiReadEntry(MultiRead request) { this.request = request; } @@ -49,34 +52,14 @@ final public class MultiReadEntry extends CacheEntryBase { setResult(null); } - synchronized public void finish(AsyncReadGraph graph) { + synchronized public void finish(ReadGraph graph) { assert(isPending()); - ArrayList, AsyncBarrier>> p = null; - - synchronized(this) { - + synchronized(this) { setReady(); - -// p = procs; -// procs = null; - } -// if(p != null) { -// ArrayList v = (ArrayList)getResult(); -// if(v != null) { -// for(Pair, AsyncBarrier> pair : p) { -// for(T t : v) pair.first.execute(graph, t); -// } -// } -// for(Pair, AsyncBarrier> pair : p) { -// pair.first.finished(graph); -// pair.second.dec(); -// } -// } - } @Override @@ -99,41 +82,30 @@ final public class MultiReadEntry 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() { + request.perform(graph , new SyncMultiProcedure() { @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 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 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 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 proc = (AsyncMultiProcedure)procedure; + + @Override + public Object performFromCache(ReadGraphImpl graph, SyncMultiProcedure 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 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 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 index 526728003..000000000 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/NamespaceIndex.java +++ /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>> { - -// public ArrayList>> 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> 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>>(); -// 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> 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> 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 result = new TObjectIntHashMap(); - - 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() { - - @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> 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>() { - - @Override - public void execute(ReadGraphImpl graph, TObjectIntHashMap 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 result) { - - throw new Error("Not possible!"); - - } - - private void add2(ReadGraphImpl graph, TObjectIntHashMap result) { - - if(!isPending()) { - new Exception(""+hashCode()).printStackTrace(); - } - - assert(isPending()); - -// ArrayList>> p = null; - - synchronized(this) { - - setResult(result); - setReady(); -// p = procs; -// procs = null; - - } - -// if(p != null) { -// -// for(InternalProcedure> proc : p) proc.execute(graph, result); -// -// } - - } - - @Override - public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure> procedure) { - - assert(isReady()); - - if(handleException(graph, procedure)) return; - - procedure.execute(graph, (TObjectIntHashMap)getResult()); - - } - - @Override - public synchronized void recompute(ReadGraphImpl graph, QueryProcessor provider) { - - final Semaphore s = new Semaphore(0); - - computeForEach(graph, provider, new InternalProcedure>() { - - @Override - public void execute(ReadGraphImpl graph, TObjectIntHashMap 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); - } - - } - -} - diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java index 0b3e1be34..f74344b2f 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java @@ -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,11 +11,6 @@ *******************************************************************************/ 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 { +public final class Objects extends CollectionBinaryQuery 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 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 getEntry(QueryProcessor provider) { - return provider.objectsMap.get(id); - } - - @Override - public void putEntry(QueryProcessor provider) { - if(Development.DEVELOPMENT) { - if(Development.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 { } @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 { } 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 { 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 { } 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 { // 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 { } - 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 { }; // 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 { 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 { }); // 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 { } 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 { } @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 { } else { - SuperRelations.queryEach(graph, pred, graph.processor, entry, null, new InternalProcedure() { + QueryCache.runnerSuperRelations(graph, pred, parent, null, new InternalProcedure() { @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 { } @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 { } @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 { } @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 { } - 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 { }; @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 { } final public static void computeNotFunctionalFinalIndex(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, RelationInfo ri, AsyncMultiProcedure 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 { }); 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 { inc(); - SuperRelations.queryEach(graph, pred, graph.processor, entry, null, new InternalProcedure() { + QueryCache.runnerSuperRelations(graph, pred, parent, null, new InternalProcedure() { @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 { } @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 { } @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 { } - @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 ip = new InternalProcedure() { - - @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 { } 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 { 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); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSet.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSet.java index 65cfb007c..e850e96f1 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSet.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSet.java @@ -11,109 +11,43 @@ *******************************************************************************/ 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 { +final public class OrderedSet extends CollectionUnaryQuery { -// public ArrayList 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(); -// 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 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 { }); - 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 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 + "]"; } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PossibleSuperRelation.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PossibleSuperRelation.java index 51c6c68d3..d391cec9c 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PossibleSuperRelation.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PossibleSuperRelation.java @@ -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 { } - @Override - public UnaryQuery 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 { } 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 { } - @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 { 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 { @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 { @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) { } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java index 960cdb6c0..9445db03b 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java @@ -11,175 +11,62 @@ *******************************************************************************/ 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 { - -// public ArrayList 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 { - return runner2(graph, r, provider, parent); - - } - - @Override - public UnaryQuery 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 { } - @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 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 p = null; - - synchronized(this) { - - setReady(); -// p = procs; -// procs = null; - - } - -// if(p != null) { -// -// final ArrayList 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 procedure_) throws DatabaseException { + + InternalProcedure 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); - } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypes.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypes.java index 25e2b6fe3..298fcfd84 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypes.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypes.java @@ -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,90 +11,29 @@ *******************************************************************************/ 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 { +import gnu.trove.procedure.TIntProcedure; +import gnu.trove.set.hash.TIntHashSet; -// public ArrayList 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(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 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 { } @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 { 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 { } @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 { } @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 { 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 { 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 { } @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 { } @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 { } - 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 { } - 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() { + QueryCache.runnerSuperTypes(graph, type, parent, null, new InternalProcedure() { @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 { } - 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 { 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 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 result) { -// for(Objects o : Objects.entries(processor, id)) result.add(o); + protected void fillImpliedParents(QueryProcessor processor, ArrayList> result) { } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Query.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Query.java index 29ba90e11..22c970f31 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Query.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Query.java @@ -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,20 +11,18 @@ *******************************************************************************/ 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 index 000000000..7b591abb7 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCache.java @@ -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 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 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 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 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 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 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 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 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 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 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 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 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> 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> 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 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 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 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 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 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 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 index 000000000..b3d1c5f88 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java @@ -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 uRIToResourceMap; + //protected final THashMap namespaceIndexMap; + protected final UnaryQueryHashMap>> childMapMap; + protected final DoubleKeyQueryHashMap objectsMap; + protected final DoubleKeyQueryHashMap assertedStatementsMap; + protected final DoubleKeyQueryHashMap directObjectsMap; + protected final DoubleKeyQueryHashMap statementsMap; + protected final UnaryQueryHashMap> typesMap; + protected final UnaryQueryHashMap principalTypesMap; + protected final UnaryQueryHashMap> predicatesMap; + protected final UnaryQueryHashMap> superTypesMap; + protected final UnaryQueryHashMap> typeHierarchyMap; + protected final UnaryQueryHashMap> superRelationsMap; + + protected final UnaryQueryHashMap orderedSetMap; + protected final UnaryQueryHashMap assertedPredicatesMap; + protected final UnaryQueryHashMap> directPredicatesMap; + protected final UnaryQueryHashMap directSuperRelationsMap; + + protected final UnaryQueryHashMap> relationInfoQueryMap; + protected final UnaryQueryHashMap> valueQueryMap; + + protected final StableHashMap asyncReadEntryMap; + protected final StableHashMap readEntryMap; + protected final StableHashMap multiReadEntryMap; + protected final StableHashMap asyncMultiReadEntryMap; + protected final StableHashMap externalReadEntryMap; + + final THashMap> 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(); + //namespaceIndexMap = new THashMap(); + childMapMap = new UnaryQueryHashMap>>(); + 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(); + readEntryMap = new StableHashMap(); + asyncMultiReadEntryMap = new StableHashMap(); + multiReadEntryMap = new StableHashMap(); + externalReadEntryMap = new StableHashMap(); + listeners = new THashMap>(10, 0.75f); + } + +// public Object performQuery(ReadGraphImpl parentGraph, final AsyncRead query, final CacheEntryBase entry_, AsyncProcedure procedure_) throws DatabaseException { +// +// AsyncReadEntry entry = (AsyncReadEntry)entry_; +// AsyncProcedure procedure = (AsyncProcedure)procedure_; +// +// ReadGraphImpl queryGraph = parentGraph.withParent(entry_); +// +// try { +// +// query.perform(queryGraph, new AsyncProcedure() { +// +// @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 Object performQuery(ReadGraphImpl parentGraph, final Read 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 Object performQuery(ReadGraphImpl parentGraph, final ExternalRead query, final CacheEntryBase entry_, AsyncProcedure procedure_) throws DatabaseException { + + ExternalReadEntry entry = (ExternalReadEntry)entry_; + AsyncProcedure procedure = (AsyncProcedure)procedure_; + + try { + + query.register(parentGraph, new Listener() { + + 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 Object performQuery(ReadGraphImpl parentGraph, final AsyncMultiRead query, final CacheEntryBase entry_, Object procedure_) throws DatabaseException { + + ReadGraphImpl queryGraph = parentGraph.withParent(entry_); + + AsyncMultiReadEntry entry = (AsyncMultiReadEntry)entry_; + AsyncMultiProcedure procedure = (AsyncMultiProcedure)procedure_; + + try { + + query.perform(queryGraph, new AsyncMultiProcedure() { + + @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 Object performQuery(ReadGraphImpl parentGraph, final MultiRead query, final CacheEntryBase entry_, Object procedure_) throws DatabaseException { + + ReadGraphImpl queryGraph = parentGraph.withParent(entry_); + + MultiReadEntry entry = (MultiReadEntry)entry_; + SyncMultiProcedure procedure = (SyncMultiProcedure)procedure_; + + try { + + query.perform(queryGraph, new SyncMultiProcedure() { + + @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 list = listeners.get(entry); + if (list == null) { + list = new ArrayList(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 getRootList() { + + ArrayList result = new ArrayList(); + + 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 entries = new ArrayList(); + + 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 entriesObjects(QueryProcessor processor, int r1) { + synchronized(processor.cache.objectsMap) { + return processor.cache.objectsMap.values(r1); + } + } + + public static Collection entriesObjects(QueryProcessor processor) { + synchronized(processor.cache.objectsMap) { + return processor.cache.objectsMap.values(); + } + } + + public static Collection entriesDirectPredicates(QueryProcessor processor) { + synchronized(processor.cache.directPredicatesMap) { + return processor.cache.directPredicatesMap.values(); + } + } + + static final Collection entriesDirectObjects(final QueryProcessor processor, final int r1) { + DoubleKeyQueryHashMap hash = processor.cache.directObjectsMap; + return hash.values(r1); + } + + static final Collection 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 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 emptyIntSetProcedure = new InternalProcedure() { + + @Override + public void execute(ReadGraphImpl graph, IntSet result) { + } + + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } + + }; + + protected static InternalProcedure emptyBytesProcedure = new InternalProcedure() { + + @Override + public void execute(ReadGraphImpl graph, byte[] bytes) { + } + + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } + + }; + + protected static InternalProcedure emptyIntegerProcedure = new InternalProcedure() { + + @Override + public void execute(ReadGraphImpl graph, Integer i) { + } + + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } + + }; + + + protected static InternalProcedure> emptyNamespaceProcedure = new InternalProcedure>() { + + @Override + public void execute(ReadGraphImpl graph, TObjectIntHashMap i) { + } + + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } + + }; + + + protected static InternalProcedure emptyRelationInfoProcedure = new InternalProcedure() { + + @Override + public void execute(ReadGraphImpl graph, RelationInfo i) { + } + + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } + + }; + + protected static InternalProcedure> emptyChildMapProcedure = new InternalProcedure>() { + + @Override + public void execute(ReadGraphImpl graph, ObjectResourceIdMap 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 emptyAsyncProcedure = new AsyncProcedure() { + + @Override + public void execute(AsyncReadGraph graph, Object result) { + } + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + } + + }; + + protected static AsyncMultiProcedure emptyAsyncMultiProcedure = new AsyncMultiProcedure() { + + @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 emptySyncMultiProcedure = new SyncMultiProcedure() { + + @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 emptyProcedureTypes = emptyIntSetProcedure; + protected static InternalProcedure emptyProcedureSuperTypes = emptyIntSetProcedure; + protected static InternalProcedure emptyProcedureTypeHierarchy = emptyIntSetProcedure; + protected static InternalProcedure emptyProcedureSuperRelations = emptyIntSetProcedure; + protected static InternalProcedure emptyProcedurePredicates = emptyIntSetProcedure; + protected static InternalProcedure 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 emptyProcedureValueQuery = emptyBytesProcedure; + + protected static InternalProcedure emptyProcedureURIToResource = emptyIntegerProcedure; + protected static InternalProcedure> emptyProcedureNamespaceIndex = emptyNamespaceProcedure; + protected static InternalProcedure> emptyProcedureChildMap = emptyChildMapProcedure; + protected static InternalProcedure 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 implements AsyncProcedure { + + private AsyncProcedure procedure; + private T result = null; + private Throwable throwable = null; + private Semaphore s = new Semaphore(0); + + AsyncProcedureWrapper(AsyncProcedure 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 implements AsyncProcedure { + + private Procedure procedure; + private T result = null; + private Throwable throwable = null; + + ExternalProcedureWrapper(Procedure 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 implements InternalProcedure { + + private InternalProcedure procedure; + private T result = null; + private Throwable throwable = null; + + InternalProcedureWrapper(InternalProcedure 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 resultExternalReadEntry(ReadGraphImpl graph, ExternalRead r, CacheEntry parent, ListenerBase listener, Procedure procedure) throws DatabaseException { + ExternalProcedureWrapper wrap = new ExternalProcedureWrapper<>(procedure); + QueryCache.runnerExternalReadEntry(graph, r, parent, listener, wrap); + return wrap.get(); + } + + public static T resultReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, AsyncProcedure procedure) throws DatabaseException { + AsyncProcedureWrapper wrap = new AsyncProcedureWrapper<>(procedure); + QueryCache.runnerReadEntry(graph, r, parent, listener, wrap, true); + return wrap.get(); + } + + public static T resultAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, AsyncProcedure procedure) throws DatabaseException { + AsyncProcedureWrapper 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 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 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 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 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 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 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 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 wrap = new InternalProcedureWrapper(null); + QueryCache.runnerURIToResource(graph, id, parent, listener, wrap); + return wrap.get(); + } + + public static ObjectResourceIdMap resultChildMap(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException { + InternalProcedureWrapper> wrap = new InternalProcedureWrapper>(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 diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCollectorImpl2.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCollectorImpl2.java index 0c3332173..84273b81d 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCollectorImpl2.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCollectorImpl2.java @@ -25,7 +25,7 @@ class QueryCollectorImpl2 implements QueryProcessor.QueryCollector { this.support = support; } - private boolean findCollectables(CacheEntry entry, Map collectables, ArrayList result) { + private boolean findCollectables(CacheEntry entry, Map collectables, ArrayList result) { if (entry.isDiscarded()) { if(DebugPolicy.COLLECT && DebugPolicy.VERBOSE) @@ -129,7 +129,7 @@ class QueryCollectorImpl2 implements QueryProcessor.QueryCollector { // Prune discarded parents ArrayList removals = new ArrayList(); - 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; } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryIdentityHash.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryIdentityHash.java index 4842cf5a6..6db4726ac 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryIdentityHash.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryIdentityHash.java @@ -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 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; + } }; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java index ff15d301b..9c60691fa 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java @@ -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 directPredicatesMap; - final public UnaryQueryHashMap principalTypesMap; - final public THashMap uriToResourceMap; - final public THashMap namespaceIndexMap22; - final public UnaryQueryHashMap projectsMap; - final public UnaryQueryHashMap> relationInfoMap; - final public UnaryQueryHashMap> superTypesMap; - final public UnaryQueryHashMap> typeHierarchyMap; - final public UnaryQueryHashMap> superRelationsMap; - final public UnaryQueryHashMap> typesMap; - final public UnaryQueryHashMap> valueMap; - final public DoubleKeyQueryHashMap directObjectsMap; - final public DoubleKeyQueryHashMap objectsMap; - final public UnaryQueryHashMap orderedSetMap; - final public UnaryQueryHashMap predicatesMap; - final public DoubleKeyQueryHashMap statementsMap; - final public UnaryQueryHashMap assertedPredicatesMap; - final public BinaryQueryHashMap assertedStatementsMap; - final public StableHashMap externalReadMap; - final public StableHashMap asyncReadMap; - final public StableHashMap readMap; - final public StableHashMap asyncMultiReadMap; - final public StableHashMap multiReadMap; - - final private THashMap> 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[] queues; +// public ArrayList[] queues; + + public LinkedList freeScheduling = new LinkedList(); 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[] ownTasks; + //public ArrayList[] ownTasks; - public ArrayList[] ownSyncTasks; + //public ArrayList[] ownSyncTasks; - ArrayList[] delayQueues; + //ArrayList[] 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 throwable; - public SessionRead(Object object, DataContainer throwable, Semaphore notify, int thread) { - super(object, thread, thread); - this.throwable = throwable; - this.notify = notify; - } - - public SessionRead(Object object, DataContainer throwable, Semaphore notify, int thread, int syncThread) { - super(object, thread, syncThread); + public SessionRead(DataContainer 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; + + private class GarbageTracker { + + @Override + protected void finalize() throws Throwable { + +// System.err.println("GarbageTracker"); +// +// garbageTracker = new WeakReference(new GarbageTracker()); + + super.finalize(); + + } + + } public QueryProcessor(final int threads, QuerySupport core, Set threadSet) throws DatabaseException { + //garbageTracker = new WeakReference(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(); - } +// for (int i = 0; i < THREADS * THREADS; i++) { +// delayQueues[i] = new ArrayList(); +// } for (int i = 0; i < THREADS; i++) { // tasks[i] = new ArrayList(); - ownTasks[i] = new ArrayList(); - ownSyncTasks[i] = new ArrayList(); - queues[i] = new ArrayList(); - threadLocks[i] = new ReentrantLock(); - threadConditions[i] = threadLocks[i].newCondition(); +// ownTasks[i] = new ArrayList(); +// ownSyncTasks[i] = new ArrayList(); +// queues[i] = new ArrayList(); +// 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(); - namespaceIndexMap22 = new THashMap(); - 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(); - readMap = new StableHashMap(); - asyncMultiReadMap = new StableHashMap(); - multiReadMap = new StableHashMap(); - externalReadMap = new StableHashMap(); - listeners = new THashMap>(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 procedure) { - URIToResource.queryEach(graph, id, parent, null, new InternalProcedure() { + try { + + QueryCache.runnerURIToResource(graph, id, parent, null, new InternalProcedure() { - @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 procedure) { + public void forBuiltin(ReadGraphImpl graph, final String id, CacheEntry parent, final InternalProcedure 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 void runAsyncRead(final ReadGraphImpl graph, final AsyncRead query, final CacheEntry parent, final ListenerBase listener, final AsyncProcedure procedure) { - - int hash = requestHash(query); + final void runMultiRead(final ReadGraphImpl graph, MultiReadEntry cached, final MultiRead query, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final SyncMultiProcedure procedure) { - AsyncReadEntry 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(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>(); - // entry.procs.add(new AsyncProcedure() { - // - // @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 void runAsyncMultiRead(final ReadGraphImpl graph, final AsyncMultiRead query, final CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure procedure) { + + try { + QueryCache.runnerAsyncMultiReadEntry(graph, query, parent, listener, procedure); + } catch (DatabaseException e) { + throw new IllegalStateException(e); } } + final void runPrimitiveRead(ReadGraphImpl graph, ExternalReadEntry cached, final ExternalRead query, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final AsyncProcedure procedure) throws DatabaseException { + QueryCache.runnerExternalReadEntry(graph, query, parent, listener, procedure); + } - final static void runMultiRead(final ReadGraphImpl graph, MultiReadEntry cached, final MultiRead query, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final AsyncMultiProcedure 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, 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 query(final ReadGraphImpl graph, final Read query, final CacheEntry parent, final AsyncProcedure 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 void queryMultiRead(final ReadGraphImpl graph, final MultiRead query, final CacheEntry parent, final ListenerBase listener, final SyncMultiProcedure procedure) throws DatabaseException { - } else { + QueryCache.runnerMultiReadEntry(graph, query, parent, listener, procedure); - provider.performForEach(graph, query, entry, parent, listener, procedure, false); + } - } + public void queryPrimitiveRead(final ReadGraphImpl graph, final ExternalRead query, final CacheEntry parent, final ListenerBase listener, final AsyncProcedure procedure) throws DatabaseException { - } + QueryCache.runnerExternalReadEntry(graph, query, parent, listener, procedure); } - public final void runAsyncMultiRead(final ReadGraphImpl graph, final AsyncMultiRead query, final CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure 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(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>(); -// 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 void runPrimitiveRead(ReadGraphImpl graph, ExternalReadEntry cached, final ExternalRead query, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final Procedure procedure) { + + static class Dummy implements InternalProcedure, IntProcedure { - final ExternalReadEntry entry = cached != null ? cached : provider.externalReadMap.get(query); - if(entry == null) { - provider.performForEach(graph, query, new ExternalReadEntry(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>(); -// 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 queryRead(final ReadGraphImpl graph, final Read query, final CacheEntry parent, final AsyncProcedure 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 void queryMultiRead(final ReadGraphImpl graph, final MultiRead query, final CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure procedure) { + /* + public Object performForEach2(ReadGraphImpl graph, UnaryQuery 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 void queryPrimitiveRead(final ReadGraphImpl graph, final ExternalRead query, final CacheEntry parent, final ListenerBase listener, final Procedure 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 void performForEach(ReadGraphImpl parentGraph, final AsyncRead query, final AsyncReadEntry entry, final CacheEntry parent, final ListenerBase base, final AsyncProcedure procedure, - boolean inferredDependency) { + } + */ + - if (DebugPolicy.PERFORM) - System.out.println("PE[ " + (query.hashCode() & THREAD_MASK) + "] " + query); + interface QueryCollectorSupport { + public CacheCollectionResult allCaches(); + public Collection 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() { - - @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() { - - @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 performForEach(final ReadGraphImpl graph, final Read query, final ReadEntry entry, final CacheEntry parent, final ListenerBase listener, final AsyncProcedure 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 void performForEach(final ReadGraphImpl graph, final MultiRead query, final MultiReadEntry entry, CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure 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() { - - @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 void performForEach(final ReadGraphImpl callerGraph, AsyncMultiRead query, final AsyncMultiReadEntry entry, final CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure 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() { - - @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 void performForEach(ReadGraphImpl graph, final ExternalRead query, final ExternalReadEntry entry, final CacheEntry parent, final ListenerBase base, final Procedure 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() { - - 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 void performForEach(ReadGraphImpl graph, BinaryQuery 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 Object performForEach(ReadGraphImpl graph, UnaryQuery 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, 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 Object performForEach2(ReadGraphImpl graph, UnaryQuery 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 void performForEach(ReadGraphImpl graph, StringQuery 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 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 getRootList() { - - ArrayList result = new ArrayList(); - - 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 list = listeners.get(entry); + ArrayList list = cache.listeners.get(entry); if (list == null) { list = new ArrayList(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 list = listeners.get(entry.entry); + ArrayList 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 entries = listeners.get(entry); + if(cache.listeners.get(entry) != null) { + ArrayList entries = cache.listeners.get(entry); ArrayList 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 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> workarea) { + void processListenerReport(CacheEntry entry, Map> 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.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 entries = listeners.get(entry); + ArrayList 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 getReferencedClusters() { HashSet result = new HashSet(); - 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> 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 getRootList() { ArrayList result = new ArrayList(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 entries = new ArrayList(); - - 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 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 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 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 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 procedure) { + final public void forEachDirectPredicate(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure> 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 procedure) { - - assert(subject != null); - assert(procedure != null); + try { + QueryCache.runnerDirectPredicates(impl, sId, impl.parent, listener, new InternalProcedure() { - 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 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 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> 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 ip = new InternalProcedure() { - 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 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() { - - 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() { + try { + QueryCache.runnerSuperTypes(impl, querySupport.getId(subject), impl.parent, listener, new InternalProcedure() { - 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 result = new HashSet(); // 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 procedure) { + final public void forValue(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure 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 procedure) { - - assert(id != null); - assert(procedure != null); - -// impl.state.barrier.inc(); - - forBuiltin(impl, id, impl.parent, new InternalProcedure() { - - @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 procedure) { + final public void forBuiltin(final ReadGraphImpl impl, final String id, final AsyncProcedure 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() { - @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 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() { + try { + QueryCache.runnerValueQuery(impl, querySupport.getId(subject), impl.parent, listener, new InternalProcedure() { - @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 void query(final ReadGraphImpl impl, final AsyncRead request, final CacheEntry parent, final AsyncProcedure 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 tryQuery(final ReadGraphImpl graph, final Read 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 tryQuery(final ReadGraphImpl graph, final ExternalRead request) throws DatabaseException { - - assert(graph != null); - assert(request != null); - - final ExternalReadEntry 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 result = new DataContainer(); - final DataContainer exception = new DataContainer(); - - request.register(graph, new Listener() { - - @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 void query(final ReadGraphImpl impl, final AsyncRead request, final CacheEntry parent, final AsyncProcedure procedure, ListenerBase listener) throws DatabaseException { +// +// assert(request != null); +// assert(procedure != null); +// +// QueryCache.runnerAsyncReadEntry(impl, request, parent, listener, procedure); +// +// } - } +// @Override +// final public T tryQuery(final ReadGraphImpl graph, final Read 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 tryQuery(final ReadGraphImpl graph, final ExternalRead request) throws DatabaseException { +// +// assert(graph != null); +// assert(request != null); +// +// final ExternalReadEntry 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 result = new DataContainer(); +// final DataContainer exception = new DataContainer(); +// +// request.register(graph, new Listener() { +// +// @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 void tryQuery(final ReadGraphImpl graph, final AsyncRead request, AsyncProcedure 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 void tryQuery(final ReadGraphImpl graph, final AsyncRead request, AsyncProcedure 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 void query(final ReadGraphImpl impl, final MultiRead request, final CacheEntry parent, final AsyncMultiProcedure procedure, ListenerBase listener) { + final public void query(final ReadGraphImpl impl, final MultiRead request, final CacheEntry parent, final SyncMultiProcedure 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 void query(final ReadGraphImpl impl, final ExternalRead request, final CacheEntry parent, final Procedure procedure, ListenerBase listener) { - - assert(request != null); - assert(procedure != null); - - queryPrimitiveRead(impl, request, parent, listener, new Procedure() { - - @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 void query(final ReadGraphImpl impl, final ExternalRead request, final CacheEntry parent, final Procedure procedure, ListenerBase listener) throws DatabaseException { +// +// assert(request != null); +// assert(procedure != null); +// +// try { +// +// queryPrimitiveRead(impl, request, parent, listener, new AsyncProcedure() { +// +// @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 thread = new ThreadLocal() { + protected Integer initialValue() { + return -1; + } + }; } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySupport.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySupport.java index 6ba47cac7..3071c30c0 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySupport.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QuerySupport.java @@ -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); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java index a5e79244e..ab10efa0b 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java @@ -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 tasks = new ArrayList(); - final private ArrayList own; - final private ArrayList ownSync; - final private ArrayList queue; - final private ReentrantLock lock; - final private Condition condition; +// final private ArrayList own; +// final private ArrayList ownSync; +// final private ArrayList 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[] delayQueues; - final private QueryThread[] executors; - final private ReentrantLock[] threadLocks; - final private ArrayList[] queues; - final private ArrayList[] ownSyncTasks; +// final private ArrayList[] delayQueues; +// final private QueryThread[] executors; +// final private ReentrantLock[] threadLocks; +// final private ArrayList[] queues; +// final private ArrayList[] 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 newTasks(boolean doWait, ArrayList 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 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 extends CacheEntryBase { +public final class ReadEntry extends CacheEntryBase> implements AsyncProcedure { - protected Read request; + private static final Logger LOGGER = LoggerFactory.getLogger(ReadEntry.class); - public ReadEntry(Read request) { - this.request = request; + protected Read request; + + public ReadEntry(Read 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, AsyncBarrier>> p = null; - - synchronized(this) { - - setResult(item); - setReady(); -// p = procs; -// procs = null; - - } - -// if(p != null) -// for(Pair, 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 proc = (AsyncProcedure)procedure; - if(isExcepted()) { + public static void computeForEach(ReadGraphImpl graph, Read request, ReadEntry entry, + AsyncProcedure 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 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 procedure) { + + AsyncProcedure proc = (AsyncProcedure) 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 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); + } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java index d32da5be5..0b60fdd0c 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java @@ -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,311 +11,99 @@ *******************************************************************************/ 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> { - -// public ArrayList> 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 procedure) { +public final class RelationInfoQuery extends UnaryQueryP { - 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>(); -// 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 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 procedure) throws DatabaseException { - @Override - public UnaryQuery> 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 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() { -// -// @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 proc) { - -// System.out.println("RelationInfoQuery: computeTypes " + id); - - Types.queryEach(graph, id, queryProvider, this, null, new InternalProcedure() { - - @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 procedure, boolean store) { - -// System.out.println("RelationInfoQuery computeForEach begin " + id + " " + getResult() + " " + statusOrException); + public static void computeForEach(ReadGraphImpl graph, int r, RelationInfoQuery entry, InternalProcedure procedure_) throws DatabaseException { - final int superRelationOf = provider.getSuperrelationOf(); - assert(superRelationOf != 0); - - DirectPredicates.queryEach(graph, id, provider, this, null, new IntProcedure() { - - boolean found = false; + InternalProcedure 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> 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 proc : p) -// proc.execute(graph, (RelationInfo)result); -// } - - } + if(entry != null) entry.performFromCache(graph, procedure_); - @Override - public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure 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 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() { + @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; - } - } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java index 935b81159..6652f1b6b 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java @@ -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,13 +11,11 @@ *******************************************************************************/ 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 { - -// public ArrayList procs = null; +public final class Statements extends CollectionBinaryQuery 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 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(); -// 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 return; } - runner(graph, r1, r2, parent, listener, procedure); + QueryCache.runnerStatements(graph, r1, r2, parent, listener, procedure); } - @Override - public BinaryQuery 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 }; - 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 } @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 } 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 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 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 } 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 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 } - 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 }; // 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 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 }); // 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 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 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 inc(); - SuperRelations.queryEach(graph, pred, graph.processor, entry, null, new InternalProcedure() { + QueryCache.runnerSuperRelations(graph, pred, parent, null, new InternalProcedure() { @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 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 } @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 } @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 } - 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 }; @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 } - 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 }); 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 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 } @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 } } - - @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() { - - @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 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 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 } -// final private void finish(ReadGraphImpl graph, QueryProcessor provider) { -// -// assert(isPending()); -// -// ArrayList 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 } @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 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); + } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/StringQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/StringQuery.java index 36d6acc5a..3498b1ac2 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/StringQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/StringQuery.java @@ -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,34 +11,33 @@ *******************************************************************************/ package org.simantics.db.impl.query; -import org.simantics.db.impl.graph.ReadGraphImpl; import org.simantics.db.request.RequestFlags; -abstract public class StringQuery extends CacheEntryBase implements Query { +public abstract class StringQuery extends CacheEntryBase 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 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 getEntry(QueryProcessor provider); - + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java index e76f702e1..1f540062e 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java @@ -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,123 +11,32 @@ *******************************************************************************/ 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> { - -// public ArrayList> 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 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 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 { - 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 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 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> 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> } - @Override - public Object computeForEach(final ReadGraphImpl graph, final QueryProcessor provider, final InternalProcedure procedure, final boolean store) { + public void compute(final ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { + computeForEach(graph, id, this, procedure); + } - provider.querySupport.ensureLoaded(graph, id); + static class DirectProcedure extends Ints implements IntProcedure, TIntProcedure, InternalProcedure { + + IntSet result; + InternalProcedure proc; + + public DirectProcedure(IntSet result, InternalProcedure 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 procedure_) throws DatabaseException { + + InternalProcedure procedure = entry != null ? entry : procedure_; + + QueryProcessor processor = graph.processor; + + processor.querySupport.ensureLoaded(graph, id); final InternalProcedure proc = (InternalProcedure)procedure; - final int subrelationOf = provider.getSubrelationOf(); - - final IntSet result = new IntSet(provider.querySupport); - - final class DirectProcedure extends Koss implements IntProcedure, TIntProcedure, InternalProcedure { - @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> @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() { + QueryCache.runnerSuperRelations(graph, arg0, entry, null, new InternalProcedure() { @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> } + if(entry != null) entry.performFromCache(graph, procedure_); + return result; } @@ -275,77 +202,5 @@ final public class SuperRelations extends UnaryQuery> public String toString() { return "SuperRelations[" + id + "]"; } - - private void addOrSet(ReadGraphImpl graph, final IntSet value, QueryProcessor provider) { - - assert(!isReady()); - -// ArrayList> 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 proc : p) proc.execute(graph, v); -// } -// } - - } - - @Override - public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure 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() { - - @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); - } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java index 0489546c5..a02fda462 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java @@ -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,231 +11,99 @@ *******************************************************************************/ 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> { - -// public ArrayList> procs = null; - - private SuperTypes(final int resource) { +import gnu.trove.procedure.TIntProcedure; + +public final class SuperTypes extends UnaryQueryP { + + 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 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>(); -// 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 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 procedure) throws DatabaseException { + computeForEach(graph, id, this, procedure); } - - @Override - public UnaryQuery> 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 procedure, boolean store) { + + public static Object computeForEach(ReadGraphImpl graph, int r, SuperTypes entry, final InternalProcedure procedure_) throws DatabaseException { + + InternalProcedure 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() { + QueryCache.runnerSuperTypes(graph, i, entry, null, new InternalProcedure() { @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> 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 proc : p) proc.execute(graph, v); -// } -// } - - } + if(entry != null) entry.performFromCache(graph, procedure_); - @Override - public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure 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() { - - @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 + "]"; } - + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SyncIntProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SyncIntProcedure.java index f79910358..c03f63b5e 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SyncIntProcedure.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SyncIntProcedure.java @@ -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,34 +11,34 @@ *******************************************************************************/ 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); } - + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ThreadRunnable.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ThreadRunnable.java index 779495484..60dc593bf 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ThreadRunnable.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ThreadRunnable.java @@ -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,10 +11,11 @@ *******************************************************************************/ 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; + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TripleIntProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TripleIntProcedure.java index 341dd48f9..7fbbdf76c 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TripleIntProcedure.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TripleIntProcedure.java @@ -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,13 +11,14 @@ *******************************************************************************/ 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; + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java index 5c5d6cb09..5c2be0c64 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java @@ -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,86 +11,41 @@ *******************************************************************************/ 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> { - -// public ArrayList> procs = null; - - private TypeHierarchy(final int resource) { +import gnu.trove.procedure.TIntProcedure; + +public final class TypeHierarchy extends UnaryQueryP { + + 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 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>(); -// 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 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 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 procedure) throws DatabaseException { + computeForEach(graph, id, this, procedure); } - - @Override - public UnaryQuery> 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 procedure, boolean store) { - - final IntSet result = new IntSet(provider.querySupport, id); - + + public static IntSet computeForEach(ReadGraphImpl graph, int id, TypeHierarchy entry, final InternalProcedure procedure_) throws DatabaseException { + + InternalProcedure 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> { return true; } }; - - SuperTypes.queryEach(graph, id, provider, TypeHierarchy.this, null, new InternalProcedure() { - - @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() { - } + @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> 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 proc : p) proc.execute(graph, v); -// } -// } - } @Override - public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure 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() { - - @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); - } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java index 49cb5c4c6..a9fe36bc6 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java @@ -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,373 +11,233 @@ *******************************************************************************/ 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> { - -// public ArrayList> procs; - - private Types(final int resource) { +import gnu.trove.procedure.TIntProcedure; + +public final class Types extends UnaryQueryP { + + 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 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 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 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 procedure_) throws DatabaseException { + + InternalProcedure procedure = entry != null ? entry : procedure_; + + computeForEach2(graph, id, entry, procedure); + + if (entry != null) + entry.performFromCache(graph, procedure_); + } - - @Override - public UnaryQuery> 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 procedure) throws DatabaseException { - @Override - public Object computeForEach(final ReadGraphImpl graph, final QueryProcessor queryProvider, final InternalProcedure 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() { + 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() { - 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() { + QueryCache.runnerSuperTypes(graph, i, parent, null, new InternalProcedure() { @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() { + QueryCache.runnerTypes(graph, i, parent, null, new InternalProcedure() { @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() { + + QueryCache.runnerTypes(graph, i, parent, null, new InternalProcedure() { @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 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() { - - @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 + "]"; } - + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java index c466cb261..ec7ebeed7 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java @@ -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,248 +11,116 @@ *******************************************************************************/ 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> { +public class URIToResource extends StringQuery> implements InternalProcedure { -// public ArrayList> 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 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>(); -// 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 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 procedure) throws DatabaseException { + computeForEach(graph, id, this, procedure); + return getResult(); } - private void lookup(ReadGraphImpl graph, final QueryProcessor processor, final InternalProcedure procedure, final String namespace, final String name) { - - NamespaceIndex.queryEach(graph, namespace, processor, this, null, new InternalProcedure>() { + static void computeForEach(ReadGraphImpl graph, String id, final URIToResource entry, final InternalProcedure procedure_) throws DatabaseException { - @Override - public void execute(ReadGraphImpl graph, TObjectIntHashMap 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 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 procedure, final String namespace, final String name) { - - NamespaceIndex.queryEach(graph, namespace, graph.processor, entry, null, new InternalProcedure>() { + final String[] parts = URIStringUtils.splitURI(id); + if (parts != null) { - @Override - public void execute(ReadGraphImpl graph, TObjectIntHashMap 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() { - } + @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 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 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 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> p = null; + assert(isPending()); synchronized(this) { - setResult(result); setReady(); -// p = procs; -// procs = null; - } -// if(p != null) -// for(InternalProcedure proc : p) proc.execute(graph, result); - } - + @Override public String toString() { return "URIToResource[" + id + "]"; } @Override - public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure procedure) { - + public Object performFromCache(ReadGraphImpl graph, InternalProcedure 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() { + public void recompute(ReadGraphImpl graph) throws DatabaseException { + + compute(graph, new InternalProcedure() { @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> { } }); - - 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); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQuery.java index ee89bedf7..26eff457d 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQuery.java @@ -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 extends CacheEntryBase implements Query { - +public abstract class UnaryQuery extends CacheEntryBase implements Query { + final public int id; public UnaryQuery(int r) { @@ -52,26 +52,11 @@ abstract public class UnaryQuery 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 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(); } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryHash.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryHash.java index f259090aa..a1095fe18 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryHash.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryHash.java @@ -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 extends THash { protected final UnaryQuery REMOVED = new UnaryQuery(-1) { @Override - public Object computeForEach(ReadGraphImpl graph, QueryProcessor provider, Object procedure, boolean store) { - throw new Error("Not possible."); - } - - @Override - public UnaryQuery 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 index 000000000..cd5cd03d9 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryP.java @@ -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 extends UnaryQuery> implements InternalProcedure { + + public UnaryQueryP(int r) { + super(r); + } + + public abstract void compute(ReadGraphImpl graph, InternalProcedure procedure) throws DatabaseException; + + @Override + public final void recompute(ReadGraphImpl graph) throws DatabaseException { + + compute(graph, new InternalProcedure() { + + @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 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); + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java index d85595831..ad4017f9c 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java @@ -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,152 +11,44 @@ *******************************************************************************/ 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> { - - private ValueQuery(final int resource) { +public final class ValueQuery extends UnaryQueryP { + + 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 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 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 procedure) throws DatabaseException { + computeForEach(graph, id, this, procedure); } - - @Override - public UnaryQuery> 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 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 procedure_) throws DatabaseException { - public static byte[] computeForEach(ReadGraphImpl graph, final int r) { + InternalProcedure procedure = entry != null ? entry : procedure_; graph.ensureLoaded(r); - - return graph.getValue(r); - - } - - @Override - public Object computeForEach(ReadGraphImpl graph, final QueryProcessor queryProvider, final InternalProcedure 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 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() { + 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 + "]"; + } + } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/TGRemover.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/TGRemover.java index be34bb9ba..8b29a9349 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/TGRemover.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/TGRemover.java @@ -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()); } } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java index fc3222208..4f98af7b4 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java @@ -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 result = new ArrayList(); - final AsyncContextMultiProcedure structure; - final AsyncContextProcedure names; - final AsyncContextProcedure type; + final SyncContextMultiProcedure structure; + final SyncContextProcedure names; + final SyncContextProcedure 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() { + names = dqs.compilePossibleRelatedValue(graph, L0.HasName, new SyncContextProcedure() { @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() { + type = new SyncContextProcedure() { @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() { + structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new SyncContextMultiProcedure() { @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 result = new ArrayList(); 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; diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/ExternalRequest.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/ExternalRequest.java index b090c4a76..8cf5652ce 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/ExternalRequest.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/ExternalRequest.java @@ -29,17 +29,20 @@ class ExternalRequest extends ParametrizedPrimitiveRead { } @Override - public void perform(ReadGraph graph, AsyncMultiProcedure callback) throws DatabaseException { + public void perform(ReadGraph graph, SyncMultiProcedure callback) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); ProjectResource PROJ = ProjectResource.getInstance(graph); diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/OntologiesForModel.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/OntologiesForModel.java index f1edc367e..2394db7ed 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/OntologiesForModel.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/OntologiesForModel.java @@ -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 { super(model); } - public void check(ReadGraph graph, Resource resource, AsyncMultiProcedure callback) throws DatabaseException { + public void check(ReadGraph graph, Resource resource, SyncMultiProcedure callback) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); ProjectResource PROJ = ProjectResource.getInstance(graph); @@ -51,7 +51,7 @@ public class OntologiesForModel extends ResourceMultiRead { } @Override - public void perform(ReadGraph graph, AsyncMultiProcedure callback) throws DatabaseException { + public void perform(ReadGraph graph, SyncMultiProcedure callback) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/combinations/Combinators.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/combinations/Combinators.java index bd2409f5d..1eea49e26 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/combinations/Combinators.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/combinations/Combinators.java @@ -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 callback) + SyncMultiProcedure 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 procedure = new SynchronizationProcedure(); - 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 procedure = new SynchronizationProcedure(); - 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 callback) throws DatabaseException { + public void perform(ReadGraph graph, final SyncMultiProcedure 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 callback) + public void perform(ReadGraph graph, SyncMultiProcedure 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 callback) throws DatabaseException { + public void perform(ReadGraph graph, final SyncMultiProcedure 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 callback) + public void perform(ReadGraph graph, SyncMultiProcedure callback) throws DatabaseException { callback.execute(graph, value); callback.finished(graph); @@ -640,29 +639,18 @@ public class Combinators { // ------------------------------------------------------------------------ - private static class Name implements Read { - Resource resource; + private static class Name extends ResourceRead { + public Name(Resource resource) { - this.resource = resource; + super(resource); } + @Override public String perform(ReadGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); - SynchronizationProcedure procedure = new SynchronizationProcedure(); - 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 name(Resource resource) { return new Name(resource); diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java index 75c75764a..55fe1ac01 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java @@ -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 result; final Set childrenWithNoName; - final AsyncContextMultiProcedure structure; - final AsyncContextMultiProcedure names; + final SyncContextMultiProcedure structure; + final SyncContextMultiProcedure names; public static Pair,Set> walk(ReadGraph graph, Collection 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() { + names = dqs.compileForEachObject(graph, L0.HasName, new SyncContextMultiProcedure() { @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() { - - @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() { + structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new SyncContextMultiProcedure() { @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); } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSourceRequest.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSourceRequest.java index 9832f9d08..c5cb20af2 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSourceRequest.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSourceRequest.java @@ -578,15 +578,15 @@ public class ModelTransferableGraphSourceRequest extends UniqueRead T getClusterByResourceKey(final int resourceKey) { + public synchronized final 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."); diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterWriteOnly.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterWriteOnly.java index f7e3a20cf..5dea700c8 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterWriteOnly.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterWriteOnly.java @@ -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 procedure) throws DatabaseException { + SyncMultiProcedure procedure) throws DatabaseException { throw new DatabaseException("Not implemented."); } @Override diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java index c8560bad8..8b4df608f 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java @@ -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 implements Map { - - final private SessionImplSocket session; - final private TObjectIntHashMap 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 map) { - @SuppressWarnings("unchecked") - ObjectResourceMap other = (ObjectResourceMap) map; - other.backend.forEachEntry(new TObjectIntProcedure() { - - @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 keySet() { - final Set result = new HashSet(); - backend.forEach(new TObjectProcedure() { - - @Override - public boolean execute(T object) { - result.add(object); - return true; - } - }); - return result; - } - - @Override - public Collection values() { - ArrayList result = new ArrayList(); - for (int key : backend.values()) { - try { - result.add(session.getResourceByKey(key)); - } catch (ResourceNotFoundException e) { - e.printStackTrace(); - } - } - return result; - } - - @Override - public Set> entrySet() { - final HashSet> result = new HashSet>(); - backend.forEachEntry(new TObjectIntProcedure() { - - @Override - public boolean execute(final T a, final int b) { - return result.add(new Map.Entry() { - - @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> i = entrySet().iterator(); - while (i.hasNext()) { - Entry 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 createObjectResourceMap(Class clazz) { diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DirectQuerySupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DirectQuerySupportImpl.java index 0b640861e..06c5ebfed 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DirectQuerySupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/DirectQuerySupportImpl.java @@ -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 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 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 procedure) { - forEachDirectStatement(graph, subject, new SyncToAsyncProcedure(procedure)); - } - - @Override - public void forEachDirectStatement(AsyncReadGraph graph, Resource subject, Procedure 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 procedure) { - ReadGraphImpl impl = (ReadGraphImpl)graph; - impl.processor.forRelationInfo(impl, subject, procedure); - } + public SyncMultiProcedure compileForEachObject(ReadGraph graph, final Resource relation, SyncMultiProcedure user) throws DatabaseException { - @Override - public void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure procedure) { - forRelationInfo(graph, subject, new SyncToAsyncProcedure(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 procedure) { - forRelationInfo(graph, subject, new NoneToAsyncProcedure(procedure)); } @Override - public AsyncMultiProcedure compileForEachObject(ReadGraph graph, final Resource relation, AsyncMultiProcedure user) { - - try { - RelationInfo info = graph.syncRequest(new AsyncRead() { + public SyncContextMultiProcedure compileForEachObject(ReadGraph graph, final Resource relation, SyncContextMultiProcedure user) throws DatabaseException { - @Override - public void perform(AsyncReadGraph graph, AsyncProcedure 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(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 AsyncContextMultiProcedure compileForEachObject(ReadGraph graph, final Resource relation, AsyncContextMultiProcedure user) { - - try { - RelationInfo info = graph.syncRequest(new AsyncRead() { - - @Override - public void perform(AsyncReadGraph graph, AsyncProcedure procedure) { - forRelationInfo(graph, relation, procedure); - } + public SyncProcedure compilePossibleRelatedValue(ReadGraph graph, final Resource relation, SyncProcedure user) throws DatabaseException { - @Override - public int threadHash() { - return hashCode(); - } + RelationInfo info = getRelationInfo(graph, relation); + final int predicateKey = ((ResourceImpl)relation).id; + return new ForPossibleRelatedValueProcedure(predicateKey, info, user); - @Override - public int getFlags() { - return 0; - } - - }); - final int predicateKey = ((ResourceImpl)relation).id; - return new ForEachObjectContextProcedure(predicateKey, info, session.queryProvider2, user); - } catch (DatabaseException e) { - return null; - } - - } - - @Override - public AsyncProcedure compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncProcedure user) { - - try { - RelationInfo info = graph.syncRequest(new AsyncRead() { - - @Override - public void perform(AsyncReadGraph graph, AsyncProcedure 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(predicateKey, info, user); - } catch (DatabaseException e) { - return null; - } - } @Override - public AsyncContextProcedure compilePossibleRelatedValue(ReadGraph graph, final Resource relation, AsyncContextProcedure user) { - - try { - RelationInfo info = graph.syncRequest(new AsyncRead() { + public SyncContextProcedure compilePossibleRelatedValue(ReadGraph graph, final Resource relation, SyncContextProcedure user) throws DatabaseException { - @Override - public void perform(AsyncReadGraph graph, AsyncProcedure 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(predicateKey, info, user); - @Override - public int getFlags() { - return 0; - } - - }); - final int predicateKey = ((ResourceImpl)relation).id; - return new ForPossibleRelatedValueContextProcedure(predicateKey, info, user); - } catch (DatabaseException e) { - return null; - } - } - + @Override - public void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, final AsyncMultiProcedure procedure) { + public void forEachObjectCompiled(ReadGraph graph, Resource subject, final SyncMultiProcedure procedure) { assert(subject != null); @@ -261,7 +150,7 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } @Override - public void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextMultiProcedure procedure) { + public void forEachObjectCompiled(ReadGraph graph, Resource subject, C context, final SyncContextMultiProcedure procedure) { assert(subject != null); @@ -283,9 +172,9 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } } - + @Override - public void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, final AsyncProcedure procedure) { + public void forPossibleRelatedValueCompiled(ReadGraph graph, Resource subject, final SyncProcedure 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 void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, C context, final AsyncContextProcedure procedure) { + public void forPossibleRelatedValueCompiled(ReadGraph graph, Resource subject, C context, final SyncContextProcedure 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 void forPossibleType(final AsyncReadGraph graph, Resource subject, final AsyncProcedure procedure) { assert(subject != null); @@ -413,9 +321,11 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { } + + */ @Override - public void forPossibleDirectType(final AsyncReadGraph graph, Resource subject, final C context, final AsyncContextProcedure procedure) { + public void forPossibleDirectType(final ReadGraph graph, Resource subject, final C context, final SyncContextProcedure 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 void getRelatedValue4(final ReadGraphImpl graph, final int subject, final C context, final ForPossibleRelatedValueContextProcedure procedure) { + private T getRelatedValue4(final ReadGraphImpl graph, final int subject, final C context, final ForPossibleRelatedValueContextProcedure 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 void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure procedure) { + private T getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final ForPossibleRelatedValueProcedure 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 void getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure procedure) { + private T getValue4(final ReadGraphImpl graph, final ClusterImpl containerCluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure 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 void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final ForPossibleRelatedValueProcedure procedure) { - - try { + private T getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final ForPossibleRelatedValueProcedure 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 void getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final C context, final ForPossibleRelatedValueContextProcedure procedure) { - try { + } + + private T getRelatedDirectValue4(final ReadGraphImpl graph, final ClusterImpl cluster, final int subject, final int result, final C context, final ForPossibleRelatedValueContextProcedure 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 void getRelatedValue4(final ReadGraphImpl graph, final int subject, final ForPossibleRelatedValueProcedure procedure) { + public T getRelatedValue4(final ReadGraphImpl graph, final int subject, final ForPossibleRelatedValueProcedure 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 void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure procedure) { try { @@ -900,40 +715,16 @@ public class DirectQuerySupportImpl implements DirectQuerySupport { // graph.dec(); } + */ - private void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final ForPossibleRelatedValueProcedure 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 getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject) throws DatabaseException { - private void getDirectValue4(final ReadGraphImpl graph, final ClusterBig cluster, final int subject, final C context, final ForPossibleRelatedValueContextProcedure 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 void getDirectValue4(final ReadGraphImpl graph, final ClusterSmall cluster, final int subject, final ForPossibleRelatedValueProcedure procedure) { + + private 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 implements Map, ObjectResourceIdMap { + + private final SessionImplSocket session; + private final TObjectIntHashMap 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 map) { + @SuppressWarnings("unchecked") + ObjectResourceMap other = (ObjectResourceMap) map; + other.backend.forEachEntry(new TObjectIntProcedure() { + + @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 keySet() { + final Set result = new HashSet<>(); + backend.forEach(new TObjectProcedure() { + + @Override + public boolean execute(T object) { + result.add(object); + return true; + } + }); + return result; + } + + @Override + public Collection values() { + ArrayList result = new ArrayList<>(); + for (int key : backend.values()) { + try { + result.add(session.getResourceByKey(key)); + } catch (ResourceNotFoundException e) { + e.printStackTrace(); + } + } + return result; + } + + @Override + public Set> entrySet() { + final HashSet> result = new HashSet<>(); + backend.forEachEntry(new TObjectIntProcedure() { + + @Override + public boolean execute(final T a, final int b) { + return result.add(new Map.Entry() { + + @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> i = entrySet().iterator(); + while (i.hasNext()) { + Entry 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 diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QueryControlImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QueryControlImpl.java index d871720a8..7165abef3 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QueryControlImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QueryControlImpl.java @@ -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); } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QueryDebugImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QueryDebugImpl.java index e3f738339..2974c9025 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QueryDebugImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QueryDebugImpl.java @@ -22,7 +22,7 @@ public class QueryDebugImpl implements QueryDebug { @Override public Set getParents(AsyncRead request) { HashSet result = new HashSet(); - 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 getParents(AsyncMultiRead request) { HashSet result = new HashSet(); - 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 getParents(Read request) { HashSet result = new HashSet(); - 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 getParents(MultiRead request) { HashSet result = new HashSet(); - 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); } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java index 190db364c..eea97e2e0 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java @@ -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 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() { -//// -//// @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 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 proc = new ClusterI.ObjectProcedure() { -// -// @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 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 got = new DataContainer(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); } } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java index d71a8bfc8..f5b6611b7 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java @@ -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() { + + AsyncProcedure ap = new AsyncProcedure() { @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 wrapper = new ResultCallWrappedSingleQueryProcedure4( +// procedure, "request"); + + BlockingAsyncProcedure wrap = new BlockingAsyncProcedure(newGraph, procedure, request); + + try { + + request.perform(newGraph, wrap); + wrap.get(); + + } catch (DatabaseException e) { + + Logger.defaultLogError(e); + + } + + } + + } finally { + + fireSessionVariableChange(SessionVariables.QUEUED_READS); + + } + + } + + }); + + } + + public void scheduleRequest(final MultiRead request, final SyncMultiProcedure 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 wrapper = new ResultCallWrappedSingleQueryProcedure4( - procedure, "request"); + final ResultCallWrappedSyncQueryProcedure wrapper = new ResultCallWrappedSyncQueryProcedure(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 void scheduleRequest(final AsyncMultiRead request, final AsyncMultiProcedure 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() { - - @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 result = new ArrayList(); final DataContainer exception = new DataContainer(); - syncRequest(request, new AsyncMultiProcedure() { + syncRequest(request, new SyncMultiProcedure() { @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 Collection syncRequest(MultiRead request, AsyncMultiListener procedure) throws DatabaseException { + public Collection syncRequest(MultiRead arg0, SyncMultiProcedure arg1) throws DatabaseException { assertNotSession(); - return syncRequest(request, (AsyncMultiProcedure)procedure); + throw new Error("Not implemented!"); } @Override public Collection syncRequest(MultiRead request, SyncMultiListener procedure) throws DatabaseException { assertNotSession(); - return syncRequest(request, new SyncToAsyncMultiListener(procedure)); + return syncRequest(request, (SyncMultiProcedure)procedure); } @Override public Collection syncRequest(MultiRead request, MultiListener procedure) throws DatabaseException { assertNotSession(); - return syncRequest(request, new NoneToAsyncMultiListener(procedure)); - } - - @Override - public Collection syncRequest(MultiRead request, SyncMultiProcedure procedure) throws DatabaseException { - assertNotSession(); - return syncRequest(request, new SyncToAsyncMultiProcedure(procedure)); + return syncRequest(request, new NoneToSyncMultiListener(procedure)); } @Override public Collection syncRequest(MultiRead request, MultiProcedure procedure) throws DatabaseException { assertNotSession(); - return syncRequest(request, new NoneToAsyncMultiProcedure(procedure)); + return syncRequest(request, new NoneToSyncMultiProcedure(procedure)); } @Override @@ -3262,38 +3310,33 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule assert(request != null); - asyncRequest(request, new AsyncMultiProcedureAdapter() { + asyncRequest(request, new SyncMultiProcedureAdapter() { @Override - public void exception(AsyncReadGraph graph, Throwable t) { + public void exception(ReadGraph graph, Throwable t) { t.printStackTrace(); } }); } - @Override - public void asyncRequest(MultiRead request, AsyncMultiListener procedure) { - asyncRequest(request, (AsyncMultiProcedure)procedure); - } - @Override public void asyncRequest(MultiRead request, SyncMultiListener procedure) { - asyncRequest(request, new SyncToAsyncMultiListener(procedure)); + asyncRequest(request, (SyncMultiProcedure)procedure); } @Override public void asyncRequest(MultiRead request, MultiListener procedure) { - asyncRequest(request, new NoneToAsyncMultiListener(procedure)); + asyncRequest(request, new NoneToSyncMultiListener(procedure)); } @Override public void asyncRequest(MultiRead request, SyncMultiProcedure procedure) { - asyncRequest(request, new SyncToAsyncMultiProcedure(procedure)); + scheduleRequest(request, procedure, null); } @Override public void asyncRequest(MultiRead request, MultiProcedure procedure) { - asyncRequest(request, new NoneToAsyncMultiProcedure(procedure)); + asyncRequest(request, new NoneToSyncMultiProcedure(procedure)); } @Override @@ -3335,17 +3378,6 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule asyncRequest(request, new NoneToAsyncMultiProcedure(procedure)); } - @Override - public Collection syncRequest(MultiRead arg0, AsyncMultiProcedure arg1) throws DatabaseException { - assertNotSession(); - throw new Error("Not implemented!"); - } - - @Override - public void asyncRequest(MultiRead arg0, AsyncMultiProcedure arg1) { - throw new Error("Not implemented!"); - } - @Override final public void asyncRequest(final ExternalRead request) { diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java index a29d6ce04..2902274b9 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java @@ -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) { diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java index 0f8d9706c..9a0097b11 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/UndoRedoSupportImpl.java @@ -44,7 +44,7 @@ public class UndoRedoSupportImpl implements UndoRedoSupport { final Operation fop = (Operation)ops.toArray()[0]; final DataContainer id = new DataContainer(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; diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterBig.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterBig.java index 29f34b45f..4cedb7947 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterBig.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterBig.java @@ -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 procedure, + public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, SyncMultiProcedure 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 void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, AsyncContextMultiProcedure procedure, + public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, SyncContextMultiProcedure 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 procedure) + int predicateKey, SyncMultiProcedure procedure) throws DatabaseException { SessionImplSocket session = (SessionImplSocket)graph.getSession(); diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterSmall.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterSmall.java index c8309c6bf..6063dc8d5 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterSmall.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterSmall.java @@ -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 procedure, + public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, SyncMultiProcedure 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 void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, C context, AsyncContextMultiProcedure procedure, + public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, C context, SyncContextMultiProcedure 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 procedure) throws DatabaseException { + int predicateKey, SyncMultiProcedure 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); diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/IntHash.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/IntHash.java index c0ead5d07..48f46bb07 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/IntHash.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/IntHash.java @@ -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 procedure, Modifier modifier) throws DatabaseException { + static void foreachInt(final ReadGraphImpl graph, int[] table, int base, final SyncMultiProcedure 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 void foreachInt(final ReadGraphImpl graph, int[] table, int base, C context, final AsyncContextMultiProcedure procedure, Modifier modifier) throws DatabaseException { + static void foreachInt(final ReadGraphImpl graph, int[] table, int base, C context, final SyncContextMultiProcedure procedure, Modifier modifier) throws DatabaseException { int capacity = getRealSize(table, base); final int size = getUsedSize(table, base); diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ObjectTable.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ObjectTable.java index da3b7903e..458f7b04a 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ObjectTable.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ObjectTable.java @@ -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 { } final public void foreachObject( ReadGraphImpl graph, final int objectIndex, - final AsyncMultiProcedure procedure, Modifier modifier) throws DatabaseException { + final SyncMultiProcedure 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 { } final public void foreachObject( ReadGraphImpl graph, final int objectIndex, C context, - final AsyncContextMultiProcedure procedure, Modifier modifier) throws DatabaseException { + final SyncContextMultiProcedure procedure, Modifier modifier) throws DatabaseException { if (ClusterTraits.statementIndexIsDirect(objectIndex)) { int key = modifier.execute(objectIndex); procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), key)); diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java index 90519a36c..d7f6abc49 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java @@ -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 procedure, + final ReadGraphImpl graph, final SyncMultiProcedure 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 void foreachObject(long[] table, int index, - final ReadGraphImpl graph, final C context, final AsyncContextMultiProcedure procedure, + final ReadGraphImpl graph, final C context, final SyncContextMultiProcedure procedure, ClusterSupport support, final int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier) throws DatabaseException { if (DEBUG) diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTable.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTable.java index e997b7318..d0619976d 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTable.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTable.java @@ -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 procedure, + final ReadGraphImpl graph, final SyncMultiProcedure 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 void foreachObject(long[] table, int index, - final ReadGraphImpl graph, final C context, final AsyncContextMultiProcedure procedure, + final ReadGraphImpl graph, final C context, final SyncContextMultiProcedure 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 { } public void foreachObject(int resourceIndex, ReadGraphImpl graph, - AsyncMultiProcedure procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) throws DatabaseException { + SyncMultiProcedure 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 void foreachObject(int resourceIndex, ReadGraphImpl graph, C context, - AsyncContextMultiProcedure procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) throws DatabaseException { + SyncContextMultiProcedure 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); diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTableSmall.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTableSmall.java index d72b79aa5..0278b1531 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTableSmall.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTableSmall.java @@ -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 { } public void foreachObject(int resourceIndex, ReadGraphImpl graph, - AsyncMultiProcedure procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException { + SyncMultiProcedure 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 void foreachObject(int resourceIndex, ReadGraphImpl graph, C context, - AsyncContextMultiProcedure procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException { + SyncContextMultiProcedure 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); diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java index 2c57f3627..c0ba6ec61 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java @@ -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 procedure, Modifier modifier) throws DatabaseException { + static void foreachInt(final int[] table, final int base, ReadGraphImpl graph, SyncMultiProcedure procedure, Modifier modifier) throws DatabaseException { final int size = -table[base + SIZE_OFFSET]; assert(size>0); @@ -170,7 +170,7 @@ final class TableIntArraySet { } - static void foreachInt(final int[] table, final int base, ReadGraphImpl graph, C context, AsyncContextMultiProcedure procedure, Modifier modifier) throws DatabaseException { + static void foreachInt(final int[] table, final int base, ReadGraphImpl graph, C context, SyncContextMultiProcedure procedure, Modifier modifier) throws DatabaseException { final int size = -table[base + SIZE_OFFSET]; assert(size>0); diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntSet.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntSet.java index f13042faa..a0e0eb14b 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntSet.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntSet.java @@ -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 procedure, Modifier modifier) throws DatabaseException { + static void foreachInt(int[] table, int base, QueryProcessor processor, ReadGraphImpl graph, SyncMultiProcedure procedure, Modifier modifier) throws DatabaseException { IntHash.foreachInt(graph, table, base, procedure, modifier); } diff --git a/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java b/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java index 47a14ddbc..879eec034 100644 --- a/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java +++ b/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java @@ -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,17 +11,12 @@ *******************************************************************************/ 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,Class>, AdapterDeclaration> adapters = @@ -366,24 +365,9 @@ public class AdaptionService2 implements AdaptionService { final Adapter adapter = (Adapter)findAdapter(resource, g); if(adapter == null) return null; - else return g.syncRequest(new AsyncRead() { - - @Override - public void perform(AsyncReadGraph graph, AsyncProcedure 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)(graph, procedure) -> { + //System.out.println("adapter=" + adapter); + adapter.adapt(graph, resource, context, procedure); }); } @@ -583,11 +567,9 @@ public class AdaptionService2 implements AdaptionService { public T adapt(ReadGraph g, Resource r, C context, Class contextClass, Class targetClass, boolean possible) throws DatabaseException { Adapter adapter = getAdapter(g, r, context, contextClass, targetClass, possible); + if(adapter == null) return null; - SyncReadProcedure procedure = new SyncReadProcedure(); - adapter.adapt(g, r, context, procedure); - procedure.checkAndThrow(); - return procedure.result; + return g.syncRequest((AsyncRead)(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)); } } diff --git a/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/reflection/AbstractReflectionAdapter.java b/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/reflection/AbstractReflectionAdapter.java index bfef0a95a..e281a0294 100644 --- a/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/reflection/AbstractReflectionAdapter.java +++ b/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/reflection/AbstractReflectionAdapter.java @@ -41,7 +41,7 @@ public abstract class AbstractReflectionAdapter implements Adapter implements Adapter { try { for(int i=0;i implements AsyncRead { + protected Result result = null; + + public abstract void run(AsyncReadGraph graph) throws Throwable; + + @Override + public void perform(AsyncReadGraph graph, AsyncProcedure 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 { } + protected abstract class TestAsyncReadRequest extends AsyncReadQuery { + + @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 { diff --git a/bundles/org.simantics.db/src/org/simantics/db/AsyncReadGraph.java b/bundles/org.simantics.db/src/org/simantics/db/AsyncReadGraph.java index 088c10daa..97f489f8b 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/AsyncReadGraph.java +++ b/bundles/org.simantics.db/src/org/simantics/db/AsyncReadGraph.java @@ -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 procedure); + void forEachDirectPredicate(Resource subject, AsyncProcedure> procedure); /** * @see ReadGraph#getObjects(Resource, Resource) */ - void forEachDirectPredicate(Resource subject, SyncMultiProcedure procedure); + void forEachDirectPredicate(Resource subject, SyncProcedure> procedure); /** * @see ReadGraph#getObjects(Resource, Resource) */ - void forEachDirectPredicate(Resource subject, MultiProcedure procedure); + void forEachDirectPredicate(Resource subject, Procedure> procedure); /** * @see ReadGraph#getObjects(Resource, Resource) @@ -1129,10 +1129,9 @@ public interface AsyncReadGraph extends AsyncRequestProcessor { */ void forOrderedSet(Resource subject, MultiProcedure procedure); - int thread(); // void inc(); // void dec(); - boolean isImmutable(Resource resource) throws DatabaseException; + boolean performPending(); } diff --git a/bundles/org.simantics.db/src/org/simantics/db/AsyncRequestProcessor.java b/bundles/org.simantics.db/src/org/simantics/db/AsyncRequestProcessor.java index 3f17927e2..ded8292fa 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/AsyncRequestProcessor.java +++ b/bundles/org.simantics.db/src/org/simantics/db/AsyncRequestProcessor.java @@ -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 { void async(ReadInterface r, Procedure procedure); void async(ReadInterface r, AsyncProcedure procedure); @@ -80,9 +73,4 @@ public interface AsyncRequestProcessor extends ServiceLocator, AsyncRequestProce void async(ReadInterface r, AsyncListener procedure); void async(ReadInterface r, SyncListener procedure); - void async(WriteInterface r); - void async(WriteInterface r, Procedure procedure); - - Object getModificationCounter(); - } diff --git a/bundles/org.simantics.db/src/org/simantics/db/AsyncRequestProcessorSpecific.java b/bundles/org.simantics.db/src/org/simantics/db/AsyncRequestProcessorSpecific.java index 429696cda..254174917 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/AsyncRequestProcessorSpecific.java +++ b/bundles/org.simantics.db/src/org/simantics/db/AsyncRequestProcessorSpecific.java @@ -289,7 +289,7 @@ public interface AsyncRequestProcessorSpecific extends ServiceLocator { * @param request an instance of {@link MultiRead}. * @param procedure an instance of {@link AsyncMultiListener}. */ - void asyncRequest(MultiRead request, AsyncMultiListener procedure); + // void asyncRequest(MultiRead request, AsyncMultiListener 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}. */ - void asyncRequest(MultiRead request, AsyncMultiProcedure procedure); + // void asyncRequest(MultiRead request, AsyncMultiProcedure procedure); /** * Asynchronously supplies the result determined from the given @@ -463,65 +463,5 @@ public interface AsyncRequestProcessorSpecific extends ServiceLocator { void asyncRequest(ExternalRead request, Listener procedure); void asyncRequest(ExternalRead request, Procedure 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 callback); - - void asyncRequest(WriteResult r, Procedure 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 callback); - - void asyncRequest(DelayedWriteResult r, Procedure 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 callback); - - void asyncRequest(WriteOnlyResult r, Procedure 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 index 000000000..7585bdf8e --- /dev/null +++ b/bundles/org.simantics.db/src/org/simantics/db/ObjectResourceIdMap.java @@ -0,0 +1,10 @@ +package org.simantics.db; + +import java.util.Map; + +public interface ObjectResourceIdMap extends Map { + + void putId(T t, int r); + int getId(T t); + +} diff --git a/bundles/org.simantics.db/src/org/simantics/db/ReadGraph.java b/bundles/org.simantics.db/src/org/simantics/db/ReadGraph.java index bead66644..36081c3a8 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/ReadGraph.java +++ b/bundles/org.simantics.db/src/org/simantics/db/ReadGraph.java @@ -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 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(); + } diff --git a/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java b/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java index 68af4664b..5e818cb99 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java +++ b/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java @@ -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 sync(ReadInterface r) throws DatabaseException; T sync(WriteInterface r) throws DatabaseException; - + + void async(WriteInterface r); + void async(WriteInterface r, Procedure procedure); + + Object getModificationCounter(); + } diff --git a/bundles/org.simantics.db/src/org/simantics/db/RequestProcessorSpecific.java b/bundles/org.simantics.db/src/org/simantics/db/RequestProcessorSpecific.java index 523d41013..b121c0829 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/RequestProcessorSpecific.java +++ b/bundles/org.simantics.db/src/org/simantics/db/RequestProcessorSpecific.java @@ -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}. */ - Collection syncRequest(MultiRead request, AsyncMultiListener procedure) throws DatabaseException; + // Collection syncRequest(MultiRead request, AsyncMultiListener 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}. */ - Collection syncRequest(MultiRead request, AsyncMultiProcedure procedure) throws DatabaseException; + // Collection syncRequest(MultiRead request, AsyncMultiProcedure 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 syncRequest(WriteOnlyResult 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 callback); + + void asyncRequest(WriteResult r, Procedure 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 callback); + + void asyncRequest(DelayedWriteResult r, Procedure 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 callback); + + void asyncRequest(WriteOnlyResult r, Procedure procedure); + } diff --git a/bundles/org.simantics.db/src/org/simantics/db/Session.java b/bundles/org.simantics.db/src/org/simantics/db/Session.java index 8e8b2d9bc..22a747b7f 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/Session.java +++ b/bundles/org.simantics.db/src/org/simantics/db/Session.java @@ -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 index 000000000..cdbfc2a1f --- /dev/null +++ b/bundles/org.simantics.db/src/org/simantics/db/procedure/SyncContextMultiProcedure.java @@ -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 the result object type accepted by the procedure + */ +public interface SyncContextMultiProcedure { + + /** + * Invoked once for each separate result of the request with potentially + * multiple results. It shall be guaranteed that all execute + * invocations have been completed when either + * {@link #finished(AsyncReadGraph)} or + * {@link #exception(AsyncReadGraph, Throwable)} are called and that no + * execute 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 index 000000000..93c745fb8 --- /dev/null +++ b/bundles/org.simantics.db/src/org/simantics/db/procedure/SyncContextProcedure.java @@ -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 { + + void execute(ReadGraph graph, Context context, Result result); + void exception(ReadGraph graph, Throwable throwable); + +} diff --git a/bundles/org.simantics.db/src/org/simantics/db/request/AsyncMultiRead.java b/bundles/org.simantics.db/src/org/simantics/db/request/AsyncMultiRead.java index cb191f647..a8e2f2b61 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/request/AsyncMultiRead.java +++ b/bundles/org.simantics.db/src/org/simantics/db/request/AsyncMultiRead.java @@ -50,7 +50,7 @@ import org.simantics.db.procedure.AsyncMultiProcedure; * @see AsyncMultiProcedure * @see Session */ -public interface AsyncMultiRead extends Request { +public interface AsyncMultiRead { /** * When a GraphRequest is serviced by the database session diff --git a/bundles/org.simantics.db/src/org/simantics/db/request/AsyncRead.java b/bundles/org.simantics.db/src/org/simantics/db/request/AsyncRead.java index a197a5f21..f0856a796 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/request/AsyncRead.java +++ b/bundles/org.simantics.db/src/org/simantics/db/request/AsyncRead.java @@ -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 extends Request { +@FunctionalInterface +public interface AsyncRead { /** * When a GraphRequest is serviced by the database session @@ -76,6 +77,13 @@ public interface AsyncRead extends Request { * be cancelled and any changes rolled back */ void perform(AsyncReadGraph graph, AsyncProcedure procedure); - int getFlags(); - - } + + default int getFlags() { + return 0; + } + + default int threadHash() { + return hashCode(); + } + +} diff --git a/bundles/org.simantics.db/src/org/simantics/db/request/MultiRead.java b/bundles/org.simantics.db/src/org/simantics/db/request/MultiRead.java index b8a4c2012..0754ac73f 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/request/MultiRead.java +++ b/bundles/org.simantics.db/src/org/simantics/db/request/MultiRead.java @@ -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 GraphRequest interface is used to create transaction @@ -91,6 +92,6 @@ public interface MultiRead { * @throws CancelTransactionException to indicate that the request needs to * be cancelled and any changes rolled back */ - void perform(ReadGraph graph, AsyncMultiProcedure callback) throws DatabaseException; + void perform(ReadGraph graph, SyncMultiProcedure 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 index ef605a53b..000000000 --- a/bundles/org.simantics.db/src/org/simantics/db/request/Request.java +++ /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(); - -} diff --git a/bundles/org.simantics.db/src/org/simantics/db/service/DirectQuerySupport.java b/bundles/org.simantics.db/src/org/simantics/db/service/DirectQuerySupport.java index 472eb9eee..7b932f3de 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/service/DirectQuerySupport.java +++ b/bundles/org.simantics.db/src/org/simantics/db/service/DirectQuerySupport.java @@ -11,41 +11,43 @@ *******************************************************************************/ 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 procedure); + DirectStatements getDirectPersistentStatements(ReadGraph graph, Resource subject); + DirectStatements getDirectStatements(ReadGraph graph, Resource subject); - void forEachDirectStatement(AsyncReadGraph graph, Resource subject, AsyncProcedure procedure); - void forEachDirectStatement(AsyncReadGraph graph, Resource subject, SyncProcedure procedure); - void forEachDirectStatement(AsyncReadGraph graph, Resource subject, Procedure procedure); +// void forEachDirectPersistentStatement(ReadGraph graph, Resource subject, AsyncProcedure procedure); +// void forEachDirectStatement(ReadGraph graph, Resource subject, AsyncProcedure procedure); +// void forEachDirectStatement(ReadGraph graph, Resource subject, SyncProcedure procedure); +// void forEachDirectStatement(ReadGraph graph, Resource subject, Procedure procedure); - void forRelationInfo(AsyncReadGraph graph, Resource subject, AsyncProcedure procedure); - void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure procedure); - void forRelationInfo(AsyncReadGraph graph, Resource subject, Procedure procedure); + RelationInfo getRelationInfo(ReadGraph graph, Resource subject) throws DatabaseException; - void forPossibleType(AsyncReadGraph graph, Resource subject, AsyncProcedure procedure); +// void forRelationInfo(AsyncReadGraph graph, Resource subject, AsyncProcedure procedure); +// void forRelationInfo(AsyncReadGraph graph, Resource subject, SyncProcedure procedure); +// void forRelationInfo(AsyncReadGraph graph, Resource subject, Procedure procedure); - AsyncMultiProcedure compileForEachObject(ReadGraph graph, Resource relation, AsyncMultiProcedure user); - AsyncContextMultiProcedure compileForEachObject(ReadGraph graph, Resource relation, AsyncContextMultiProcedure user); - AsyncProcedure compilePossibleRelatedValue(ReadGraph graph, Resource relation, AsyncProcedure user); - AsyncContextProcedure compilePossibleRelatedValue(ReadGraph graph, Resource relation, AsyncContextProcedure user); + // void forPossibleType(AsyncReadGraph graph, Resource subject, AsyncProcedure procedure); - void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, AsyncMultiProcedure procedure); - void forEachObjectCompiled(AsyncReadGraph graph, Resource subject, C context, AsyncContextMultiProcedure procedure); - void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, AsyncProcedure procedure); - void forPossibleRelatedValueCompiled(AsyncReadGraph graph, Resource subject, C context, AsyncContextProcedure procedure); - void forPossibleDirectType(AsyncReadGraph graph, Resource subject, C context, AsyncContextProcedure procedure); + SyncMultiProcedure compileForEachObject(ReadGraph graph, Resource relation, SyncMultiProcedure user) throws DatabaseException; + SyncContextMultiProcedure compileForEachObject(ReadGraph graph, Resource relation, SyncContextMultiProcedure user) throws DatabaseException; + SyncProcedure compilePossibleRelatedValue(ReadGraph graph, Resource relation, SyncProcedure user) throws DatabaseException; + SyncContextProcedure compilePossibleRelatedValue(ReadGraph graph, Resource relation, SyncContextProcedure user) throws DatabaseException; + + void forEachObjectCompiled(ReadGraph graph, Resource subject, SyncMultiProcedure procedure); + void forEachObjectCompiled(ReadGraph graph, Resource subject, C context, SyncContextMultiProcedure procedure); + void forPossibleRelatedValueCompiled(ReadGraph graph, Resource subject, SyncProcedure procedure); + void forPossibleRelatedValueCompiled(ReadGraph graph, Resource subject, C context, SyncContextProcedure procedure); + void forPossibleDirectType(ReadGraph graph, Resource subject, C context, SyncContextProcedure procedure); } diff --git a/bundles/org.simantics.db/src/org/simantics/db/service/QueryControl.java b/bundles/org.simantics.db/src/org/simantics/db/service/QueryControl.java index 5cc3fa655..3da3c5aa3 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/service/QueryControl.java +++ b/bundles/org.simantics.db/src/org/simantics/db/service/QueryControl.java @@ -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); diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/ConstantStyle.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/ConstantStyle.java index 428acc686..4a59f4b3c 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/ConstantStyle.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/ConstantStyle.java @@ -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; diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java index 56063b990..9be72d29f 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java @@ -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,22 +11,17 @@ *******************************************************************************/ 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(previousElementCount); - result.nodeSet = new THashSet(); - result.connectionSet = new THashSet(); - result.connectionSegments = new THashSet(); - result.branchPoints = new THashSet(); - result.routeGraphConnectionSet = new THashSet(); - result.routeLinks = new THashSet(); - result.routeLines = new THashSet(); - result.routePoints = new THashSet(); - - result.partToConnection = new THashMap(); // These help loading result.elements in the correct order. final AtomicInteger index = new AtomicInteger(); final TIntArrayList unrecognizedElementIndices = new TIntArrayList(); - g.forOrderedSet(data, new AsyncMultiProcedure() { + Collection components = OrderedSetUtils.toList(g, data); + DiagramContents res = g.syncRequest((AsyncRead)(graph, procedure) -> { - @Override - public void execute(AsyncReadGraph graph, final Resource component) { + DiagramContents result = new DiagramContents(); + procedure.execute(graph, result); + + result.elements = new ArrayList(previousElementCount); + result.nodeSet = new THashSet(); + result.connectionSet = new THashSet(); + result.connectionSegments = new THashSet(); + result.branchPoints = new THashSet(); + result.routeGraphConnectionSet = new THashSet(); + result.routeLinks = new THashSet(); + result.routeLines = new THashSet(); + result.routePoints = new THashSet(); + + result.partToConnection = new THashMap(); + + 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>() { + graph.forTypes(component, new ProcedureAdapter>() { @Override - public void exception(AsyncReadGraph graph, Throwable t) { - if (errorHandler != null) - errorHandler.error(t.getMessage(), t); - } + public void execute(Set types) { - @Override - public void execute(AsyncReadGraph graph, Set 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() { - @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() { - @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 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() { + graph.syncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure() { @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() { + graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure() { @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 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() { + graph.syncRequest(new ConnectionRequest(canvas, diagram, connection, errorHandler, loadListener), new Procedure() { @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 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() { + graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure() { @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 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() { + graph.syncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure() { @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() { + 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() { + @Override + public void exception(AsyncReadGraph graph, Throwable t) { + error("failed to load layers for connection segment", t); + } + }); } }); diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/MappedTypeGroup.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/MappedTypeGroup.java index 856631fa2..6e7d368b5 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/MappedTypeGroup.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/MappedTypeGroup.java @@ -68,13 +68,13 @@ public class MappedTypeGroup implements Group { } @Override - public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener listener) { + public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener listener) throws DatabaseException { if (types.isEmpty()) { System.out.println("MappedTypeGroup has no types!"); return; } - processor.asyncRequest(new BinaryRead, Collection>(runtimeDiagram, types) { + processor.syncRequest(new BinaryRead, Collection>(runtimeDiagram, types) { @Override public Set perform(ReadGraph graph) throws DatabaseException { diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java index 8e2db2488..e025fb2dd 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java @@ -63,13 +63,13 @@ public class TypeGroup implements Group { } @Override - public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener listener) { + public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener listener) throws DatabaseException { if (types.isEmpty()) { System.out.println("TypeGroup has no types!"); return; } - processor.asyncRequest(new BinaryRead, Collection>(runtimeDiagram, types) { + processor.syncRequest(new BinaryRead, Collection>(runtimeDiagram, types) { @Override public Set perform(ReadGraph graph) throws DatabaseException { diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/DiagramElementGroup.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/DiagramElementGroup.java index 059bb55fb..cc04927f6 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/DiagramElementGroup.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/DiagramElementGroup.java @@ -38,8 +38,8 @@ public abstract class DiagramElementGroup implements Group { } @Override - public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener listener) { - processor.asyncRequest(new BinaryRead, Resource, Collection>(getClass(), runtimeDiagram) { + public void trackItems(RequestProcessor processor, final Resource runtimeDiagram, final SetListener listener) throws DatabaseException { + processor.syncRequest(new BinaryRead, Resource, Collection>(getClass(), runtimeDiagram) { @Override public Set perform(ReadGraph graph) throws DatabaseException { diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java index ee203616d..21071ba74 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java @@ -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 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); diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/runtime/RuntimeDiagramManager.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/runtime/RuntimeDiagramManager.java index bfc439101..04e30f70d 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/runtime/RuntimeDiagramManager.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/runtime/RuntimeDiagramManager.java @@ -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() { + private void listenRequest(RequestProcessor processor, final Resource diagram) throws DatabaseException { + processor.syncRequest(new RuntimeVariableForInput(getResourceInput()), new AsyncListener() { @Override public void exception(AsyncReadGraph graph, Throwable throwable) { diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java index 66cc0047c..aabe7b29f 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java @@ -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)); diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/IssueUtils.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/IssueUtils.java index bb0c8a5b1..ecc6b20cc 100644 --- a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/IssueUtils.java +++ b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/IssueUtils.java @@ -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(issue, model, source) { + graph.syncRequest(new ResourceRead3(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)); } diff --git a/bundles/org.simantics.layer0.utils/src/org/simantics/layer0/utils/queries/QueryExecutor2.java b/bundles/org.simantics.layer0.utils/src/org/simantics/layer0/utils/queries/QueryExecutor2.java index 9814925e3..8608fc4d5 100644 --- a/bundles/org.simantics.layer0.utils/src/org/simantics/layer0/utils/queries/QueryExecutor2.java +++ b/bundles/org.simantics.layer0.utils/src/org/simantics/layer0/utils/queries/QueryExecutor2.java @@ -47,11 +47,6 @@ public abstract class QueryExecutor2 extends ReadRequest implements AsyncListene public void execute(RequestProcessor processor) throws DatabaseException { AsyncMultiRead request = new AsyncMultiRead() { - - @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); } diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorClassFactory2.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorClassFactory2.java index 17c26f483..597a125a8 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorClassFactory2.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorClassFactory2.java @@ -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); } } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/issue/SCLExpressionIssueProvider.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/issue/SCLExpressionIssueProvider.java index 7e480d4ff..46142247f 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/issue/SCLExpressionIssueProvider.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/issue/SCLExpressionIssueProvider.java @@ -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> implements Disposable { + private static class ComponentSyncListenerAdapter extends AsyncListenerAdapter> implements Disposable { private ConcurrentHashMap currentlyListening = new ConcurrentHashMap<>(); private boolean disposed; @@ -195,7 +196,7 @@ public class SCLExpressionIssueProvider implements SCLIssueProvider { } @Override - public void execute(ReadGraph graph, Set newComponents) { + public void execute(AsyncReadGraph graph, Set newComponents) { if (currentlyListening.isEmpty() && newComponents.isEmpty()) { // we can stop here as nothing will change return; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/subscription/ModelHistoryCollector.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/subscription/ModelHistoryCollector.java index 27c840467..a18fa7b46 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/subscription/ModelHistoryCollector.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/subscription/ModelHistoryCollector.java @@ -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(); } diff --git a/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/Group.java b/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/Group.java index 8d1a11124..27d6a0dbc 100644 --- a/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/Group.java +++ b/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/Group.java @@ -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 listener); + void trackItems(RequestProcessor processor, Resource runtimeDiagram, SetListener listener) throws DatabaseException; } diff --git a/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/Style.java b/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/Style.java index d18e623d0..c719df2d7 100644 --- a/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/Style.java +++ b/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/Style.java @@ -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 diff --git a/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java b/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java index 23c1ad508..f3d4c3430 100644 --- a/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java +++ b/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java @@ -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() { @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 exceptionCallback, Function1 isDisposedCallback) throws DatabaseException { - graph.asyncRequest(new Subquery(query), new SyncListenerAdapter() { + graph.syncRequest(new Subquery(query), new SyncListenerAdapter() { @Override public void execute(ReadGraph graph, Object result) throws DatabaseException { Simantics.applySCLRead(graph, executeCallback, result); diff --git a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/GraphUI.java b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/GraphUI.java index 607661163..03df2dd0a 100644 --- a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/GraphUI.java +++ b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/GraphUI.java @@ -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() { + graph.syncRequest(new CellValue(property.second), new SyncListener() { @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 diff --git a/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SheetFactory.java b/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SheetFactory.java index 4669fdf4d..7edd2e816 100644 --- a/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SheetFactory.java +++ b/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SheetFactory.java @@ -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); } diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorInput2.java b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorInput2.java index b33137b52..6b5a03552 100644 --- a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorInput2.java +++ b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorInput2.java @@ -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 { diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/editor/input/InputValidationCombinators.java b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/editor/input/InputValidationCombinators.java index 9b2c1e06c..1fd5a1620 100644 --- a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/editor/input/InputValidationCombinators.java +++ b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/editor/input/InputValidationCombinators.java @@ -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 procedure = new SynchronizationProcedure(); 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 procedure = new SynchronizationProcedure(); Resource relation = graph.getResource(relationURI); - graph.forSingleObject(subject, relation, procedure); - return procedure.getResult(); + return graph.getSingleObject(subject, relation); } @Override public int hashCode() { diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/readGraph/forObjectSet/ForObjectSetTest1.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/readGraph/forObjectSet/ForObjectSetTest1.java index 1a6a3a0b4..dc492e20c 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/readGraph/forObjectSet/ForObjectSetTest1.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/readGraph/forObjectSet/ForObjectSetTest1.java @@ -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() { - - @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() { + + @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; + } + + }); + + } + + }); + } }); diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/AsyncTransactionTest.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/AsyncTransactionTest.java index 749fbeb76..b4137a43a 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/AsyncTransactionTest.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/AsyncTransactionTest.java @@ -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() { + session.asyncRequest(new AsyncReadRequest() { @Override - public Object perform(ReadGraph graph) throws DatabaseException { + public void run(AsyncReadGraph graph) { AsyncTransactionTest.this.perform(graph); - return null; } }); diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest3.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest3.java index 2bec7c21e..8181e08fb 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest3.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest3.java @@ -33,11 +33,6 @@ public class RequestParentTest3 extends ExistingDatabaseTest { QueryDebug debug = session.getService(QueryDebug.class); class Request implements AsyncMultiRead { - - @Override - public int threadHash() { - return hashCode(); - } @Override public void perform(AsyncReadGraph graph, AsyncMultiProcedure callback) { diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest4.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest4.java index 7ae1a8491..8bdad204b 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest4.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest4.java @@ -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 { @Override - public void perform(ReadGraph graph, AsyncMultiProcedure callback) throws DatabaseException { + public void perform(ReadGraph graph, SyncMultiProcedure 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() { + session.syncRequest(request1, new SyncMultiListener() { @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) { } }); diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest5.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest5.java index 5b261c75c..1e63dc487 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest5.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest5.java @@ -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() { diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest6.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest6.java index 34c73424c..1b3d112e0 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest6.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestParentTest6.java @@ -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() { diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestProcessorTest1.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestProcessorTest1.java index 2c89c1ecc..4466f733d 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestProcessorTest1.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestProcessorTest1.java @@ -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); diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestQueuingTest.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestQueuingTest.java index c17e35797..188ab6db9 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestQueuingTest.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestQueuingTest.java @@ -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() { + 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 resources = new ArrayList(); 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 rs = graph.getObjects(root, b.ConsistsOf); diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest2.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest2.java index 971a35dd5..7f79a58fb 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest2.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest2.java @@ -40,10 +40,10 @@ public class SyncAsyncSyncTest2 extends ExistingDatabaseTest { final ArrayList resources = new ArrayList(); 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 rs = graph.getObjects(root, b.ConsistsOf); diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest5.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest5.java index 29b682119..7e50d9a08 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest5.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest5.java @@ -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 resources = new ArrayList(); 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() { @@ -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() { diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest6.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest6.java index 3e1d3ff1f..208062f20 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest6.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest6.java @@ -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 resources = new ArrayList(); 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() { diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest9.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest9.java index 4d6b1fb46..9deff6d34 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest9.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/SyncAsyncSyncTest9.java @@ -12,12 +12,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.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() { + g.forPossibleObject(g.getRootLibrary(), b.InstanceOf, new AsyncListener() { @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() { @@ -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); } diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/performance/read/HierarchicalNames.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/performance/read/HierarchicalNames.java index 18d6ce537..088f15667 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/performance/read/HierarchicalNames.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/performance/read/HierarchicalNames.java @@ -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 readAsync(final Resource resource) { + public static AsyncRead 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 structure; - final AsyncProcedure names; + final SyncMultiProcedure structure; + final SyncProcedure 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() { + names = dqs.compilePossibleRelatedValue(graph, L0.HasName, new SyncProcedure() { @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() { + structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new SyncMultiProcedure() { @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 procedure, final RelationInfo name, final Serializer serializer, final AsyncProcedure procedure2) { - dqs.forPossibleType(graph, resource, new AsyncProcedure() { + dqs.forPossibleDirectType(graph, resource, dqs, new SyncContextProcedure() { @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, String>>() { + try { + graph.syncRequest(new TypeSetAndString(type), new SyncProcedure, String>>() { - @Override - public void execute(AsyncReadGraph graph, Pair, String> typeInfo) { - - Set types = typeInfo.first; - if(types.contains(L0.Ontology)) { + @Override + public void execute(ReadGraph graph, Pair, String> typeInfo) { + Set types = typeInfo.first; + if(types.contains(L0.Ontology)) { + // dqs.forPossibleRelatedValue(graph, resource, name, serializer, new AsyncProcedure() { // // @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 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 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 diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/performance/read/ReadHierarchicalNames.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/performance/read/ReadHierarchicalNames.java index 66e3842e0..6e2231fb5 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/performance/read/ReadHierarchicalNames.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/performance/read/ReadHierarchicalNames.java @@ -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 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 request) throws DatabaseException { long start = System.nanoTime(); diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test1.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test1.java index 768ebf73a..1673c89f1 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test1.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test1.java @@ -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() { - - @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() { + + @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 { diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test2.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test2.java index 5c44a694c..b7595baed 100644 --- a/tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test2.java +++ b/tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test2.java @@ -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 { -- 2.47.1