Optimize ReadGraph.hasStatements(s,p) to not use getObjects(s,p)
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Wed, 10 Jun 2020 18:41:27 +0000 (21:41 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Wed, 17 Jun 2020 20:56:54 +0000 (23:56 +0300)
Depending on the predicate asked for, hasStatements(s,p) can be
optimized to not realize the entire [object] result list created by
getObjects(s,p).

gitlab #558

Change-Id: I7be1d2000396ce6c1e4595cabaafef5db4224de9
(cherry picked from commit ac990d10ff2d1d1042a68f0594489aed23a27453)

bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java

index cc15c1eac9111e063369cadd9c7167b3c843b4a9..5d4852c0d7822efe1f88ef70a1a7eb6a941cb272 100644 (file)
@@ -50,6 +50,7 @@ import org.simantics.db.DevelopmentKeys;
 import org.simantics.db.ExternalValueSupport;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.RelationContext;
+import org.simantics.db.RelationInfo;
 import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.Statement;
@@ -1849,8 +1850,35 @@ public class ReadGraphImpl implements AsyncReadGraph {
 
                try {
 
-                       Collection<Resource> objects = getObjects(subject, relation);
-                       return !objects.isEmpty();
+                       SyncReadProcedure<RelationInfo> procedure = new SyncReadProcedure<RelationInfo>();
+                       processor.forRelationInfo(this, relation, procedure);
+                       Collection<Resource> predicates = getPredicates(subject);
+                       
+                       if(procedure.result.isFinal) {
+                               
+                               return predicates.contains(relation);
+                               
+                       } else if (procedure.result.isFunctional) {
+
+                               try {
+                                       int result = processor.getSingleObject(this, subject, relation);
+                                       return result != 0;
+                               } catch (ManyObjectsForFunctionalRelationException e) {
+                                       return true;
+                               } catch (DatabaseException e) {
+                                       throw new ServiceException(e);
+                               }
+                               
+                       } else {
+
+                               for(Resource predicate : getPredicates(subject)) {
+                                       if(isSubrelationOf(predicate, relation))
+                                               return true;
+                               }
+                               
+                       }
+                       
+                       return false;
 
                } catch (ServiceException e) {