From 77ba75dcaf7d7c16187907f0661916d48e99edf6 Mon Sep 17 00:00:00 2001 From: Antti Villberg Date: Fri, 19 Jul 2019 13:27:54 +0300 Subject: [PATCH] First step to enable reading of cache when not writing gitlab #320 Change-Id: If12e55796207f0d08f46fc0670760c2937593e89 --- .../db/impl/query/AsyncMultiReadEntry.java | 24 +- .../db/impl/query/AsyncReadEntry.java | 26 +- .../simantics/db/impl/query/CacheEntry.java | 2 +- .../db/impl/query/CacheEntryBase.java | 8 +- .../org/simantics/db/impl/query/CodeGen.java | 433 ++++++++++-------- .../db/impl/query/ExternalReadEntry.java | 30 +- .../db/impl/query/MultiReadEntry.java | 22 +- .../simantics/db/impl/query/QueryCache.java | 285 ++++++------ .../db/impl/query/QueryIdentityHash.java | 2 +- .../db/impl/query/QueryProcessor.java | 158 ++++--- .../simantics/db/impl/query/ReadEntry.java | 28 +- 11 files changed, 555 insertions(+), 463 deletions(-) diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncMultiReadEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncMultiReadEntry.java index bc3cf0a4f..ea88d1791 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncMultiReadEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AsyncMultiReadEntry.java @@ -27,26 +27,26 @@ final public class AsyncMultiReadEntry extends CacheEntryBase request; + protected AsyncMultiRead id; AsyncMultiReadEntry(AsyncMultiRead request) { - this.request = request; + this.id = request; } @Override int makeHash() { - return request.hashCode(); + return id.hashCode(); } @Override public Object getOriginalRequest() { - return request; + return id; } @Override public void discard() { super.discard(); - request = null; + id = null; setResult(null); } @@ -111,9 +111,9 @@ final public class AsyncMultiReadEntry extends CacheEntryBase extends CacheEntryBase extends CacheEntryBase procedure) throws DatabaseException { - return graph.processor.cache.performQuery(graph, request, this, procedure); + return graph.processor.cache.performQuery(graph, id, 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 cd5420656..72582ee60 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 @@ -30,10 +30,10 @@ final public class AsyncReadEntry extends CacheEntryBase> i private static final Logger LOGGER = LoggerFactory.getLogger(AsyncReadEntry.class); - protected AsyncRead request; + protected AsyncRead id; AsyncReadEntry(AsyncRead request) { - this.request = request; + this.id = request; if (Development.DEVELOPMENT) { if(Development.getProperty(DevelopmentKeys.CACHE_ENTRY_STATE, Bindings.BOOLEAN)) { System.err.println("[QUERY STATE]: created " + this); @@ -43,12 +43,12 @@ final public class AsyncReadEntry extends CacheEntryBase> i @Override int makeHash() { - return request.hashCode(); + return id.hashCode(); } @Override public Object getOriginalRequest() { - return request; + return id; } @Override @@ -90,9 +90,9 @@ final public class AsyncReadEntry extends CacheEntryBase> i except(t); } - }, request); + }, id); - request.perform(graph, proc); + id.perform(graph, proc); proc.get(); @@ -109,17 +109,17 @@ final public class AsyncReadEntry extends CacheEntryBase> i @Override public int type() { - return request.getFlags(); + return id.getFlags(); } @Override public String toString() { - if (request == null) + if (id == null) return "DISCARDED"; else if (isExcepted()) - return request.toString() + " " + getResult(); + return id.toString() + " " + getResult(); else - return request.toString() + " " + statusOrException; + return id.toString() + " " + statusOrException; } }; @@ -242,11 +242,11 @@ final public class AsyncReadEntry extends CacheEntryBase> i @Override public String toString() { if (isDiscarded()) - return "DISCARDED " + request.toString(); + return "DISCARDED " + id.toString(); else if (isExcepted()) - return request.toString() + " " + getResult(); + return id.toString() + " " + getResult(); else - return request.toString() + " " + statusOrException; + return id.toString() + " " + statusOrException; } @Override 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 848925622..1cdcbde9d 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 @@ -29,7 +29,7 @@ public abstract class CacheEntry { abstract void setReady(); abstract void refute(); - abstract void setPending(); + abstract void setPending(QuerySupport querySupport); abstract void discard(); abstract void except(Throwable t); abstract void clearResult(QuerySupport support); 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 3a94e52b6..e79f99dea 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 @@ -145,8 +145,9 @@ public abstract class CacheEntryBase extends CacheEntry { } @Override - public void setPending() { - statusOrException = PENDING; + public void setPending(QuerySupport querySupport) { + statusOrException = PENDING; + clearResult(querySupport); } @Override @@ -439,8 +440,7 @@ public abstract class CacheEntryBase extends CacheEntry { @Override void prepareRecompute(QuerySupport querySupport) { - setPending(); - clearResult(querySupport); + setPending(querySupport); } @Override 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 index 8661428cb..66ee865a6 100644 --- 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 @@ -11,203 +11,246 @@ 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", "", false ); + GenerationInfo signatureR1Bytes = new GenerationInfo ( "int r", "r", "keyR", "long", "InternalProcedure", "", false ); + GenerationInfo signatureR1IntSet = new GenerationInfo ( "int r", "r", "keyR", "long", "InternalProcedure", "", false ); + GenerationInfo signatureR1IP = new GenerationInfo ( "int r", "r", "keyR", "long", "IntProcedure", "", false ); + GenerationInfo signatureR2IP = new GenerationInfo ( "int r1, int r2", "r1,r2", "keyR2", "long", "IntProcedure", "", false ); + GenerationInfo signatureR2TIP = new GenerationInfo ( "int r1, int r2", "r1,r2", "keyR2", "long", "TripleIntProcedure", "", false ); + GenerationInfo signatureID1 = new GenerationInfo ( "String id", "id", "keyID", "String", "InternalProcedure", "", false ); + GenerationInfo signatureID2 = new GenerationInfo ( "String id", "id", "keyID", "String", "InternalProcedure>", "", false ); + GenerationInfo signatureChildMap = new GenerationInfo ( "int r", "r", "keyR", "long", "InternalProcedure>", "", false ); + GenerationInfo signatureRead = new GenerationInfo ( "Read r", "r", "id", "long", "AsyncProcedure", "", true ); + GenerationInfo signatureAsyncRead = new GenerationInfo ( "AsyncRead r", "r", "id", "long", "AsyncProcedure", "", true ); + GenerationInfo signatureMultiRead = new GenerationInfo ( "MultiRead r", "r", "id", "long", "SyncMultiProcedure", "", false ); + GenerationInfo signatureAsyncMultiRead = new GenerationInfo ( "AsyncMultiRead r", "r", "id", "long", "AsyncMultiProcedure", "", false ); + GenerationInfo signatureExternalRead = new GenerationInfo ( "ExternalRead r", "r", "id", "long", "AsyncProcedure", ", graph", false ); + + private void line(StringBuilder content, String line) { + for(int i=0;i extends CacheEntryBase final LinkedList items = new LinkedList(); - protected ExternalRead request; + protected ExternalRead id; protected ReadGraphImpl graph; protected boolean registered = false; @Override int makeHash() { - return request.hashCode(); + return id.hashCode(); } @Override public Object getOriginalRequest() { - return request; + return id; } @Override @@ -47,14 +47,14 @@ final public class ExternalReadEntry extends CacheEntryBase @Override public void discard() { - request.unregistered(); - request = null; + id.unregistered(); + id = null; graph = null; super.discard(); } @Override - public void setPending() { + public void setPending(QuerySupport querySupport) { //if(result != NO_RESULT) { //new Exception("result = " + result).printStackTrace(); //} @@ -64,7 +64,7 @@ final public class ExternalReadEntry extends CacheEntryBase public ExternalReadEntry(ExternalRead request, ReadGraphImpl graph) { assert request != null; - this.request = request; + this.id = request; this.graph = graph; } @@ -119,7 +119,7 @@ final public class ExternalReadEntry extends CacheEntryBase } // Reschedule if(!items.isEmpty()) { - graph.processor.updatePrimitive(request); + graph.processor.updatePrimitive(id); } } @@ -138,8 +138,8 @@ final public class ExternalReadEntry extends CacheEntryBase @Override public String toString() { - if(request == null) return "DISCARDED ExternalRead"; - else return request.toString(); + if(id == null) return "DISCARDED ExternalRead"; + else return id.toString(); } }; @@ -148,8 +148,8 @@ final public class ExternalReadEntry extends CacheEntryBase @Override public String toString() { - if(request == null) return "DISCARDED ExternalRead " + System.identityHashCode(this); - else return request.toString() + " " + + System.identityHashCode(this); + if(id == null) return "DISCARDED ExternalRead " + System.identityHashCode(this); + else return id.toString() + " " + + System.identityHashCode(this); } @Override @@ -183,11 +183,11 @@ final public class ExternalReadEntry extends CacheEntryBase ReadGraphImpl queryGraph = graph.withParent(this); if(!registered) { - request.register(graph, this); + id.register(graph, this); registered = true; } - queryGraph.asyncBarrier.waitBarrier(request, graph); + queryGraph.asyncBarrier.waitBarrier(id, graph); } catch (Throwable t) { @@ -213,7 +213,7 @@ final public class ExternalReadEntry extends CacheEntryBase synchronized(items) { items.addLast(result); - graph.processor.updatePrimitive(request); + graph.processor.updatePrimitive(id); // TODO: implement flags/logic in ExternalRead to state that all but the latest request result can be evaporated // In some cases where data is produced really fast this might be necessary but currently this queueing will do. } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/MultiReadEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/MultiReadEntry.java index 6b7415c97..77e3b8d0f 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/MultiReadEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/MultiReadEntry.java @@ -29,26 +29,26 @@ public final class MultiReadEntry extends CacheEntryBase request; + protected MultiRead id; MultiReadEntry(MultiRead request) { - this.request = request; + this.id = request; } @Override int makeHash() { - return request.hashCode(); + return id.hashCode(); } @Override public Object getOriginalRequest() { - return request; + return id; } @Override public void discard() { super.discard(); - request = null; + id = null; setResult(null); } @@ -86,7 +86,7 @@ public final class MultiReadEntry extends CacheEntryBase() { + id.perform(graph , new SyncMultiProcedure() { @Override public void execute(ReadGraph graph, T result) { @@ -123,8 +123,8 @@ public final class MultiReadEntry extends CacheEntryBase extends CacheEntryBase procedure) throws DatabaseException { - return graph.processor.cache.performQuery(graph, request, this, procedure); + return graph.processor.cache.performQuery(graph, id, this, procedure); } } 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 index 48d5646c2..06882a489 100644 --- 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 @@ -19,9 +19,8 @@ import org.simantics.db.request.Read; public class QueryCache extends QueryCacheBase { - // Using QueryChaching breaks Diagram Editor (and probably something else). - private static final boolean SINGLE = false; - + private static final boolean SINGLE = false; + public QueryCache(QuerySupport querySupport, int threads) { super(querySupport, threads); } @@ -32,18 +31,19 @@ public class QueryCache extends QueryCacheBase { existing = (Objects)objectsMap.get(r1,r2); if(existing == null) { existing = new Objects(r1,r2); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); objectsMap.put(keyR2(r1,r2), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -89,18 +89,19 @@ public class QueryCache extends QueryCacheBase { existing = (Statements)statementsMap.get(r1,r2); if(existing == null) { existing = new Statements(r1,r2); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); statementsMap.put(keyR2(r1,r2), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -146,18 +147,19 @@ public class QueryCache extends QueryCacheBase { existing = (DirectObjects)directObjectsMap.get(r1,r2); if(existing == null) { existing = new DirectObjects(r1,r2); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); directObjectsMap.put(keyR2(r1,r2), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -203,18 +205,19 @@ public class QueryCache extends QueryCacheBase { existing = (RelationInfoQuery)relationInfoQueryMap.get(r); if(existing == null) { existing = new RelationInfoQuery(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); relationInfoQueryMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -260,18 +263,19 @@ public class QueryCache extends QueryCacheBase { existing = (URIToResource)uRIToResourceMap.get(id); if(existing == null) { existing = new URIToResource(id); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); uRIToResourceMap.put(keyID(id), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -317,18 +321,19 @@ public class QueryCache extends QueryCacheBase { existing = (ValueQuery)valueQueryMap.get(r); if(existing == null) { existing = new ValueQuery(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); valueQueryMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -374,18 +379,19 @@ public class QueryCache extends QueryCacheBase { existing = (OrderedSet)orderedSetMap.get(r); if(existing == null) { existing = new OrderedSet(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); orderedSetMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -431,18 +437,19 @@ public class QueryCache extends QueryCacheBase { existing = (PrincipalTypes)principalTypesMap.get(r); if(existing == null) { existing = new PrincipalTypes(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); principalTypesMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -488,18 +495,19 @@ public class QueryCache extends QueryCacheBase { existing = (DirectPredicates)directPredicatesMap.get(r); if(existing == null) { existing = new DirectPredicates(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); directPredicatesMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -545,18 +553,19 @@ public class QueryCache extends QueryCacheBase { existing = (Predicates)predicatesMap.get(r); if(existing == null) { existing = new Predicates(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); predicatesMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -602,32 +611,33 @@ public class QueryCache extends QueryCacheBase { existing = (ReadEntry)readEntryMap.get(r); if(existing == null) { existing = new ReadEntry(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); readEntryMap.put(id(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } if(existing.isPending()) { - if(needsToBlock) waitPending(graph, existing); - else return null; + if(needsToBlock) + waitPending(graph, existing); + else { + return null; + } } return existing; } - void remove(ReadEntry entry) { synchronized(readEntryMap) { - readEntryMap.remove(entry.request); + readEntryMap.remove(entry.id); } } - public static Object runnerReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure, final boolean needsToBlock) throws DatabaseException { + public static Object runnerReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure, boolean needsToBlock) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { if (SINGLE) { @@ -636,33 +646,32 @@ public class QueryCache extends QueryCacheBase { return e.performFromCache(graph, procedure); } } - return ReadEntry.computeForEach(graph, r, null, procedure); + return ReadEntry.computeForEach(graph, r, null, procedure, needsToBlock); } ReadEntry entry = (ReadEntry)cache.getOrCreateReadEntry(graph, r, needsToBlock); if(entry == null) { - graph.processor.schedule(new SessionTask(graph) { - @Override - public void run0(int thread) { - try { - runnerReadEntry(graph, r, parent, listener, procedure, needsToBlock); - } catch (DatabaseException e) { - Logger.defaultLogError(e); - } - } - }); - return null; + graph.processor.schedule(new SessionTask(graph) { + @Override + public void run0(int thread) { + try { + runnerReadEntry(graph, r, parent, listener, procedure, needsToBlock); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + } + }); + return null; } AsyncProcedure procedure_ = procedure != null ? procedure : emptyProcedureReadEntry; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); if(entry.isReady()) return entry.performFromCache(graph, procedure_); else { assert(entry.isPending()); - Object result = ReadEntry.computeForEach(graph, r, entry, procedure_); + Object result = ReadEntry.computeForEach(graph, r, entry, procedure_, needsToBlock); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); return result; } } - private ReadEntry peekReadEntry(Read r) { synchronized(readEntryMap) { @@ -676,32 +685,33 @@ public class QueryCache extends QueryCacheBase { existing = (AsyncReadEntry)asyncReadEntryMap.get(r); if(existing == null) { existing = new AsyncReadEntry(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); asyncReadEntryMap.put(id(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } if(existing.isPending()) { - if(needsToBlock) waitPending(graph, existing); - else return null; + if(needsToBlock) + waitPending(graph, existing); + else { + return null; + } } return existing; } - void remove(AsyncReadEntry entry) { synchronized(asyncReadEntryMap) { - asyncReadEntryMap.remove(entry.request); + asyncReadEntryMap.remove(entry.id); } } - public static Object runnerAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure, final boolean needsToBlock) throws DatabaseException { + public static Object runnerAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure, boolean needsToBlock) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { if (SINGLE) { @@ -714,17 +724,17 @@ public class QueryCache extends QueryCacheBase { } AsyncReadEntry entry = (AsyncReadEntry)cache.getOrCreateAsyncReadEntry(graph, r, needsToBlock); if(entry == null) { - graph.processor.schedule(new SessionTask(graph) { - @Override - public void run0(int thread) { - try { - runnerAsyncReadEntry(graph, r, parent, listener, procedure, needsToBlock); - } catch (DatabaseException e) { - Logger.defaultLogError(e); - } - } - }); - return null; + graph.processor.schedule(new SessionTask(graph) { + @Override + public void run0(int thread) { + try { + runnerAsyncReadEntry(graph, r, parent, listener, procedure, needsToBlock); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + } + }); + return null; } AsyncProcedure procedure_ = procedure != null ? procedure : emptyProcedureAsyncReadEntry; ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); @@ -736,7 +746,6 @@ public class QueryCache extends QueryCacheBase { return result; } } - private AsyncReadEntry peekAsyncReadEntry(AsyncRead r) { synchronized(asyncReadEntryMap) { @@ -750,18 +759,19 @@ public class QueryCache extends QueryCacheBase { existing = (Types)typesMap.get(r); if(existing == null) { existing = new Types(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); typesMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -807,18 +817,19 @@ public class QueryCache extends QueryCacheBase { existing = (ChildMap)childMapMap.get(r); if(existing == null) { existing = new ChildMap(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); childMapMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -864,18 +875,19 @@ public class QueryCache extends QueryCacheBase { existing = (TypeHierarchy)typeHierarchyMap.get(r); if(existing == null) { existing = new TypeHierarchy(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); typeHierarchyMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -921,18 +933,19 @@ public class QueryCache extends QueryCacheBase { existing = (SuperTypes)superTypesMap.get(r); if(existing == null) { existing = new SuperTypes(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); superTypesMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -978,18 +991,19 @@ public class QueryCache extends QueryCacheBase { existing = (SuperRelations)superRelationsMap.get(r); if(existing == null) { existing = new SuperRelations(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); superRelationsMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -1035,18 +1049,19 @@ public class QueryCache extends QueryCacheBase { existing = (AssertedPredicates)assertedPredicatesMap.get(r); if(existing == null) { existing = new AssertedPredicates(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); assertedPredicatesMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -1081,18 +1096,19 @@ public class QueryCache extends QueryCacheBase { existing = (AssertedStatements)assertedStatementsMap.get(r1,r2); if(existing == null) { existing = new AssertedStatements(r1,r2); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); assertedStatementsMap.put(keyR2(r1,r2), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -1127,18 +1143,19 @@ public class QueryCache extends QueryCacheBase { existing = (DirectSuperRelations)directSuperRelationsMap.get(r); if(existing == null) { existing = new DirectSuperRelations(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); directSuperRelationsMap.put(keyR(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } @@ -1173,24 +1190,25 @@ public class QueryCache extends QueryCacheBase { existing = (MultiReadEntry)multiReadEntryMap.get(r); if(existing == null) { existing = new MultiReadEntry(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); multiReadEntryMap.put(id(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } void remove(MultiReadEntry entry) { synchronized(multiReadEntryMap) { - multiReadEntryMap.remove(entry.request); + multiReadEntryMap.remove(entry.id); } } @@ -1219,24 +1237,25 @@ public class QueryCache extends QueryCacheBase { existing = (AsyncMultiReadEntry)asyncMultiReadEntryMap.get(r); if(existing == null) { existing = new AsyncMultiReadEntry(r); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); asyncMultiReadEntryMap.put(id(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } void remove(AsyncMultiReadEntry entry) { synchronized(asyncMultiReadEntryMap) { - asyncMultiReadEntryMap.remove(entry.request); + asyncMultiReadEntryMap.remove(entry.id); } } @@ -1265,25 +1284,25 @@ public class QueryCache extends QueryCacheBase { existing = (ExternalReadEntry)externalReadEntryMap.get(r); if(existing == null) { existing = new ExternalReadEntry(r, graph); - existing.clearResult(querySupport); - existing.setPending(); + existing.setPending(querySupport); externalReadEntryMap.put(id(r), existing); size++; return existing; } if(existing.requiresComputation()) { - existing.setPending(); + existing.setPending(querySupport); return existing; } } - if(existing.isPending()) waitPending(graph, existing); + if(existing.isPending()) { + waitPending(graph, existing); + } return existing; } - void remove(ExternalReadEntry entry) { synchronized(externalReadEntryMap) { - externalReadEntryMap.remove(entry.request); + externalReadEntryMap.remove(entry.id); } } 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 6db4726ac..c2b21444f 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 @@ -131,7 +131,7 @@ abstract public class QueryIdentityHash extends THash { } @Override - public void setPending() { + public void setPending(QuerySupport querySupport) { // TODO Auto-generated method stub } 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 774390720..9b54d15f6 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 @@ -1266,11 +1266,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap for(CacheEntry entry : workarea.keySet()) { Class clazz = entry.getClass(); - if(entry instanceof ReadEntry) clazz = ((ReadEntry)entry).request.getClass(); - else if(entry instanceof MultiReadEntry) clazz = ((MultiReadEntry)entry).request.getClass(); - else if(entry instanceof AsyncReadEntry) clazz = ((AsyncReadEntry)entry).request.getClass(); - else if(entry instanceof AsyncMultiReadEntry) clazz = ((AsyncMultiReadEntry)entry).request.getClass(); - else if(entry instanceof ExternalReadEntry) clazz = ((ExternalReadEntry)entry).request.getClass(); + if(entry instanceof ReadEntry) clazz = ((ReadEntry)entry).id.getClass(); + else if(entry instanceof MultiReadEntry) clazz = ((MultiReadEntry)entry).id.getClass(); + else if(entry instanceof AsyncReadEntry) clazz = ((AsyncReadEntry)entry).id.getClass(); + else if(entry instanceof AsyncMultiReadEntry) clazz = ((AsyncMultiReadEntry)entry).id.getClass(); + else if(entry instanceof ExternalReadEntry) clazz = ((ExternalReadEntry)entry).id.getClass(); Integer c = counts.get(clazz); if(c == null) counts.put(clazz, -1); else counts.put(clazz, c-1); @@ -1452,17 +1452,17 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap return false; } - if (entry.isRefuted()) { - if (Development.DEVELOPMENT) { - if(Development.getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) { - System.err.print("R"); - for (int i = 0; i < e.indent; i++) - System.err.print(" "); - System.err.println(entry.getQuery()); - } - } - return false; - } +// if (entry.isRefuted()) { +// if (Development.DEVELOPMENT) { +// if(Development.getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) { +// System.err.print("R"); +// for (int i = 0; i < e.indent; i++) +// System.err.print(" "); +// System.err.println(entry.getQuery()); +// } +// } +// return false; +// } if (entry.isExcepted()) { if (Development.DEVELOPMENT) { @@ -1851,6 +1851,22 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap private Object primitiveUpdateLock = new Object(); private THashSet scheduledPrimitiveUpdates = new THashSet(); + private ArrayList refutations = new ArrayList<>(); + + private void markForUpdate(ReadGraphImpl graph, CacheEntry e) { + e.refute(); + refutations.add(e); + } + + private void updateRefutations(ReadGraphImpl graph) { + + for(CacheEntry e : refutations) + update(graph, e); + + refutations.clear(); + + } + public void performDirtyUpdates(final ReadGraphImpl graph) { cache.dirty = false; @@ -1870,28 +1886,37 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap final int subject = (int)(arg0 >>> 32); final int predicate = (int)(arg0 & 0xffffffff); - 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); + for(Objects o : QueryCache.entriesObjects(QueryProcessor.this, subject)) markForUpdate(graph, o); + for(DirectObjects o : QueryCache.entriesDirectObjects(QueryProcessor.this, subject)) markForUpdate(graph, o); + for(Statements o : QueryCache.entriesStatements(QueryProcessor.this, subject)) markForUpdate(graph, o); if(predicate == instanceOf || predicate == inherits || predicate == subrelationOf) { PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, subject); - if(principalTypes != null) update(graph, principalTypes); + if(principalTypes != null) markForUpdate(graph, principalTypes); Types types = QueryCache.entryTypes(QueryProcessor.this, subject); - if(types != null) update(graph, types); + if(types != null) markForUpdate(graph, types); } if(predicate == subrelationOf) { SuperRelations superRelations = SuperRelations.entry(QueryProcessor.this, subject); - if(superRelations != null) update(graph, superRelations); + if(superRelations != null) markForUpdate(graph, superRelations); } DirectPredicates dp = QueryCache.entryDirectPredicates(QueryProcessor.this, subject); - if(dp != null) update(graph, dp); + if(dp != null) markForUpdate(graph, dp); OrderedSet os = QueryCache.entryOrderedSet(QueryProcessor.this, predicate); - if(os != null) update(graph, os); + if(os != null) markForUpdate(graph, os); + updateRefutations(graph); + scheduledObjectUpdates.clear(); + + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) { + System.err.println("== Query update ends =="); + } + } + return; } @@ -1902,9 +1927,18 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap int arg0 = scheduledValueUpdates.getFirst(); ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, arg0); - if(valueQuery != null) update(graph, valueQuery); + if(valueQuery != null) markForUpdate(graph, valueQuery); + + updateRefutations(graph); scheduledValueUpdates.clear(); + + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) { + System.err.println("== Query update ends =="); + } + } + return; } @@ -1918,30 +1952,12 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap scheduledPrimitiveUpdates = new THashSet(); } - primitiveUpdates.forEach(new TObjectProcedure() { - - @Override - public boolean execute(Object arg0) { - - ExternalReadEntry query = (ExternalReadEntry)cache.externalReadEntryMap.get(arg0); - if (query != null) { - boolean listening = update(graph, query); - if (!listening && !query.hasParents()) { - cache.externalReadEntryMap.remove(arg0); - query.discard(); - } - } - return true; - } - - }); - scheduledValueUpdates.forEach(new TIntProcedure() { @Override public boolean execute(int arg0) { ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, arg0); - if(valueQuery != null) update(graph, valueQuery); + if(valueQuery != null) markForUpdate(graph, valueQuery); return true; } @@ -1953,15 +1969,15 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap public boolean execute(int resource) { ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, resource); - if(valueQuery != null) update(graph, valueQuery); + if(valueQuery != null) markForUpdate(graph, valueQuery); PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, resource); - if(principalTypes != null) update(graph, principalTypes); + if(principalTypes != null) markForUpdate(graph, principalTypes); Types types = QueryCache.entryTypes(QueryProcessor.this, resource); - if(types != null) update(graph, types); + if(types != null) markForUpdate(graph, types); SuperRelations superRelations = SuperRelations.entry(QueryProcessor.this, resource); - if(superRelations != null) update(graph, superRelations); + if(superRelations != null) markForUpdate(graph, superRelations); predicates.add(resource); @@ -1980,14 +1996,14 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap if(predicate == instanceOf || predicate == inherits || predicate == subrelationOf) { PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, subject); - if(principalTypes != null) update(graph, principalTypes); + if(principalTypes != null) markForUpdate(graph, principalTypes); Types types = QueryCache.entryTypes(QueryProcessor.this, subject); - if(types != null) update(graph, types); + if(types != null) markForUpdate(graph, types); } if(predicate == subrelationOf) { SuperRelations superRelations = SuperRelations.entry(QueryProcessor.this, subject); - if(superRelations != null) update(graph, superRelations); + if(superRelations != null) markForUpdate(graph, superRelations); } predicates.add(subject); @@ -2004,12 +2020,12 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap @Override public boolean execute(final int subject) { - 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); + for(Objects o : QueryCache.entriesObjects(QueryProcessor.this, subject)) markForUpdate(graph, o); + for(DirectObjects o : QueryCache.entriesDirectObjects(QueryProcessor.this, subject)) markForUpdate(graph, o); + for(Statements o : QueryCache.entriesStatements(QueryProcessor.this, subject)) markForUpdate(graph, o); DirectPredicates entry = QueryCache.entryDirectPredicates(QueryProcessor.this, subject); - if(entry != null) update(graph, entry); + if(entry != null) markForUpdate(graph, entry); return true; @@ -2023,7 +2039,7 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap public boolean execute(int orderedSet) { OrderedSet entry = QueryCache.entryOrderedSet(QueryProcessor.this, orderedSet); - if(entry != null) update(graph, entry); + if(entry != null) markForUpdate(graph, entry); return true; @@ -2031,21 +2047,35 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap }); - // for (Integer subject : predicates) { - // DirectPredicates entry = DirectPredicates.entry(QueryProcessor.this, subject); - // if(entry != null) update(graph, entry); - // } + updateRefutations(graph); + primitiveUpdates.forEach(new TObjectProcedure() { - if (Development.DEVELOPMENT) { - if(Development.getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) { - System.err.println("== Query update ends =="); + @Override + public boolean execute(Object arg0) { + + ExternalReadEntry query = (ExternalReadEntry)cache.externalReadEntryMap.get(arg0); + if (query != null) { + boolean listening = update(graph, query); + if (!listening && !query.hasParents()) { + cache.externalReadEntryMap.remove(arg0); + query.discard(); + } + } + return true; } - } + }); + scheduledValueUpdates.clear(); scheduledObjectUpdates.clear(); scheduledInvalidates.clear(); + + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) { + System.err.println("== Query update ends =="); + } + } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ReadEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ReadEntry.java index 1ceca45a5..72f132288 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ReadEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ReadEntry.java @@ -25,20 +25,20 @@ public final class ReadEntry extends CacheEntryBase> implem private static final Logger LOGGER = LoggerFactory.getLogger(ReadEntry.class); - protected Read request; + protected Read id; public ReadEntry(Read request) { - this.request = request; + this.id = request; } @Override int makeHash() { - return request.hashCode(); + return id.hashCode(); } @Override public Object getOriginalRequest() { - return request; + return id; } @Override @@ -57,7 +57,7 @@ public final class ReadEntry extends CacheEntryBase> implem try { - T result = request.perform(graph); + T result = id.perform(graph); setResult(result); setReady(); @@ -76,8 +76,8 @@ public final class ReadEntry extends CacheEntryBase> implem @Override public int type() { - if (request instanceof ReadExt) { - return ((ReadExt) request).getType(); + if (id instanceof ReadExt) { + return ((ReadExt) id).getType(); } else { return RequestFlags.INVALIDATE; } @@ -85,10 +85,10 @@ public final class ReadEntry extends CacheEntryBase> implem @Override public String toString() { - if (request == null) + if (id == null) return "DISCARDED"; else - return request.toString() + statusOrException; + return id.toString() + statusOrException; } }; @@ -96,7 +96,7 @@ public final class ReadEntry extends CacheEntryBase> implem } public static T computeForEach(ReadGraphImpl graph, Read request, ReadEntry entry, - AsyncProcedure procedure_) throws DatabaseException { + AsyncProcedure procedure_, boolean needsToBlock) throws DatabaseException { AsyncProcedure procedure = entry != null ? entry : procedure_; @@ -181,10 +181,10 @@ public final class ReadEntry extends CacheEntryBase> implem @Override public String toString() { - if (request == null) + if (id == null) return "DISCARDED"; else - return request.toString() + " - " + statusOrException; + return id.toString() + " - " + statusOrException; } public Object get(ReadGraphImpl graph, AsyncProcedure procedure) throws DatabaseException { @@ -196,8 +196,8 @@ public final class ReadEntry extends CacheEntryBase> implem @Override boolean isImmutable(ReadGraphImpl graph) throws DatabaseException { - if (request instanceof ReadExt) { - return ((ReadExt) request).isImmutable(graph); + if (id instanceof ReadExt) { + return ((ReadExt) id).isImmutable(graph); } return false; } -- 2.43.2