X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.impl%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fimpl%2Fquery%2FCacheEntryBase.java;h=98e7f0d00554f1c3f351339d8aa4b891028966ae;hp=31b585aaeeccd43cb2089ebe254d680c314a709b;hb=HEAD;hpb=0ae2b770234dfc3cbb18bd38f324125cf0faca07 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 31b585aae..98e7f0d00 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 @@ -12,16 +12,22 @@ package org.simantics.db.impl.query; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; -import org.simantics.db.common.utils.Logger; +import org.simantics.databoard.Bindings; +import org.simantics.db.DevelopmentKeys; 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.utils.Development; +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); + // Default level is something that is not quite a prospect but still allows for ordering within CacheCollectionResult public static final short UNDEFINED_LEVEL = 5; @@ -31,11 +37,11 @@ abstract public class CacheEntryBase extends CacheEntry { final public static CacheEntryBase[] NONE = new CacheEntryBase[0]; - static private Object NO_RESULT = new Object(); - static protected Object INVALID_RESULT = new Object(); + static Object NO_RESULT = new Object() { public String toString() { return "NO_RESULT"; }}; + static protected Object INVALID_RESULT = new Object() { public String toString() { return "INVALID_RESULT"; }}; - // 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 @@ -43,12 +49,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; @@ -64,13 +70,14 @@ 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() { + assert(result != NO_RESULT); statusOrException = READY; } @@ -81,7 +88,11 @@ abstract public class CacheEntryBase extends CacheEntry { @Override public void discard() { - if(DebugPolicy.QUERY_STATE) System.out.println("[QUERY STATE]: discarded " + this); + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.CACHE_ENTRY_STATE, Bindings.BOOLEAN)) { + System.err.println("[QUERY STATE]: discarded " + this); + } + } statusOrException = DISCARDED; } @@ -92,24 +103,32 @@ abstract public class CacheEntryBase extends CacheEntry { @Override final public void refute() { - if(DebugPolicy.QUERY_STATE) System.out.println("[QUERY STATE]: refuted " + this); - statusOrException = REFUTED; + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.CACHE_ENTRY_STATE, Bindings.BOOLEAN)) { + System.err.println("[QUERY STATE]: refuted " + this); + } + } + statusOrException = REQUIRES_COMPUTATION; } @Override final public boolean isRefuted() { - return REFUTED == statusOrException; + return REQUIRES_COMPUTATION == statusOrException; } @Override - final public void except(Throwable t) { - if(DebugPolicy.QUERY_STATE) System.out.println("[QUERY STATE]: excepted " + this); + public void except(Throwable throwable) { + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.CACHE_ENTRY_STATE, Bindings.BOOLEAN)) { + System.err.println("[QUERY STATE]: excepted " + this); + } + } if(statusOrException != DISCARDED) { statusOrException = EXCEPTED; - result = t; + result = throwable; } else { - Logger.defaultLogError("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; } } @@ -127,8 +146,9 @@ abstract public class CacheEntryBase extends CacheEntry { } @Override - final public void setPending() { - statusOrException = PENDING; + public void setPending(QuerySupport querySupport) { + statusOrException = PENDING; + clearResult(querySupport); } @Override @@ -136,10 +156,14 @@ 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) { - System.err.println("Assertion failed, expected pending, got " + statusOrException); + LOGGER.warn("Assertion failed, expected pending, got " + statusOrException); } return result; } @@ -165,6 +189,7 @@ abstract public class CacheEntryBase extends CacheEntry { this.result = result; } + @SuppressWarnings("unchecked") @Override final public T getResult() { assert(statusOrException != DISCARDED); @@ -253,7 +278,31 @@ abstract public class CacheEntryBase extends CacheEntry { } } - + + @Override + void pruneParentSet() { + // First parent is discarded => look for more parents + if(p2OrParents instanceof QueryIdentityHashSet) { + + QueryIdentityHashSet set = (QueryIdentityHashSet)p2OrParents; + set.removeDiscardedReally(); + if(set.isEmpty()) p2OrParents = null; + + } else if(p2OrParents instanceof CacheEntry) { + + CacheEntry entry = (CacheEntry)p2OrParents; + if(entry.isDiscarded()) { + // Second entry is also discarded => all empty + p2OrParents = null; + } + + } else { + + // Nothing left + + } + } + @Override final public void removeParent(CacheEntry entry) { @@ -315,9 +364,9 @@ abstract public class CacheEntryBase extends CacheEntry { } @Override - final public Iterable getParents(QueryProcessor processor) { + final public Collection> getParents(QueryProcessor processor) { - ArrayList result = new ArrayList(); + ArrayList> result = new ArrayList>(); if(p1 != null) result.add(p1); if(p2OrParents != null) { if(p2OrParents instanceof QueryIdentityHashSet) { @@ -357,8 +406,7 @@ abstract public class CacheEntryBase extends CacheEntry { } - protected void fillImpliedParents(QueryProcessor processor, ArrayList result) { - + protected void fillImpliedParents(QueryProcessor processor, ArrayList> result) { } protected String internalError() { @@ -366,7 +414,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; @@ -375,7 +423,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; @@ -384,7 +432,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; @@ -417,14 +465,9 @@ abstract public class CacheEntryBase extends CacheEntry { @Override void prepareRecompute(QuerySupport querySupport) { - setPending(); - clearResult(querySupport); + setPending(querySupport); } - /* - * - * - */ @Override int getGCStatus() { return GCStatus; @@ -450,5 +493,47 @@ abstract public class CacheEntryBase extends CacheEntry { // This is the original request for all built-in queries return getQuery(); } + + public CacheEntryBase() { + } + public String classId() { + return getClass().getName(); + } + + public void serializeKey(QuerySerializer serializer) { + throw new IllegalStateException("Cannot serialize query key for " + this); + } + + public void serializeValue(QuerySerializer serializer) { + throw new IllegalStateException("Cannot serialize query value for " + this); + } + + public void serializeParents(QuerySerializer serializer) { + Collection> ps = getParents(serializer.getQueryProcessor()); + int sizePos = serializer.writeUnknownSize(); + int actual = 0; + for(CacheEntry entry : ps) { + CacheEntryBase b = (CacheEntryBase)entry; + String cid = b.classId(); + if(cid == null) + continue; + serializer.serializeId(b.classId()); + b.serializeKey(serializer); + actual++; + } + serializer.setUnknownSize(sizePos, actual); + } + + public long cluster(QueryProcessor processor) { + throw new IllegalStateException("Cannot compute query cluster for " + this); + } + + public void serialize(QuerySerializer serializer) { + serializer.serializeId(classId()); + serializeKey(serializer); + serializeValue(serializer); + serializeParents(serializer); + } + }