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%2FQueryCollectorImpl2.java;h=b0e6330700e2fd587d9aa873a0446671ddd1f77d;hp=b964854b77465bf8752d25b4cfa9473e1db385fd;hb=HEAD;hpb=969bd23cab98a79ca9101af33334000879fb60c5 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 b964854b7..b0e633070 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 @@ -1,184 +1,216 @@ -package org.simantics.db.impl.query; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; - -import org.simantics.databoard.util.IdentityHashSet; -import org.simantics.db.common.exception.DebugException; -import org.simantics.db.impl.DebugPolicy; -import org.simantics.db.impl.query.QueryProcessor.QueryCollectorSupport; -import org.simantics.utils.Development; - -class QueryCollectorImpl2 implements QueryProcessor.QueryCollector { - - private final QueryProcessor queryProcessor; - - final private QueryCollectorSupport support; - - private int lastKnownFixedSize = 0; - - QueryCollectorImpl2(QueryProcessor queryProcessor, QueryCollectorSupport support) { - this.queryProcessor = queryProcessor; - this.support = support; - } - - private boolean findCollectables(CacheEntry entry, Map collectables, ArrayList result) { - - if (entry.isDiscarded()) { - if(DebugPolicy.COLLECT && DebugPolicy.VERBOSE) - System.out.println("GC: discarded entry " + entry); - return true; - } - - if (entry.isPending()) { - if(DebugPolicy.COLLECT && DebugPolicy.VERBOSE) - System.out.println("GC: pending entry " + entry + " was not collected."); - collectables.remove(entry); - return false; - } - - if (this.queryProcessor.hasListenerAfterDisposing(entry)) { - if (DebugPolicy.COLLECT && DebugPolicy.VERBOSE) { - System.out.println("GC: listened entry " + entry + " was not collected. Entry=" + entry); - } - collectables.remove(entry); - return false; - } - - for (CacheEntry parent : entry.getParents(queryProcessor)) { - - boolean parentIsCollectable = false; - - if (!collectables.containsKey(parent)) { - collectables.put(parent, true); - parentIsCollectable = findCollectables(parent, collectables, result); - } else { - parentIsCollectable = collectables.get(parent); - } - - if(!parentIsCollectable) { - if(DebugPolicy.COLLECT && DebugPolicy.VERBOSE) - System.out.println("GC: due to bound parent " + parent + " the entry + " + entry + " was not collected."); - collectables.remove(entry); - return false; - } - - } - - if(entry.shouldBeCollected()) { - // This can be collected - result.add(entry); - return true; - } else { - return false; - } - - } - - private List findCollectables() { - - ArrayList result = new ArrayList(); - - IdentityHashMap collectables = new IdentityHashMap(); - Collection rootList = support.getRootList(); - for (CacheEntry entry : rootList) { - if(!collectables.containsKey(entry)) { - collectables.put(entry, true); - findCollectables(entry, collectables, result); - } - } - - if(Development.DEVELOPMENT) { - IdentityHashSet set = new IdentityHashSet(); - for(CacheEntry entry : result) { - if(!set.add(entry)) throw new IllegalStateException(); - } - } - - return result; - - } - - private void doCollect(int currentSize, int maxNumberOfCollectableQueries) { - - List collectables = findCollectables(); - - // Compute amount of free queries - int freeCount = collectables.size(); - - if(DebugPolicy.COLLECT) - System.out.println("collector found " + freeCount + " free queries."); - - lastKnownFixedSize = currentSize - freeCount; - - // No need to collect - if(freeCount < maxNumberOfCollectableQueries) return; - - int target = freeCount - maxNumberOfCollectableQueries/2; - - if(DebugPolicy.COLLECT) - System.out.println("collector removes " + target + " free queries."); - - for(CacheEntry entry : collectables) { - if(queryProcessor.removeQuery(entry)) - if(--target < 0) break; - } - - // Prune discarded parents - ArrayList removals = new ArrayList(); - for (CacheEntry entry : support.allCaches().toCollection()) { - for(CacheEntry p : entry.getParents(queryProcessor)) { - if(p.isDiscarded()) removals.add(p); - } - for(CacheEntry r : removals) { - entry.removeParent(r); - } - removals.clear(); - } - - if(DebugPolicy.COLLECT) { - System.out.println("collect found " + freeCount + " collectable entries."); - } - - return; - - } - - @Override - public void collect(int youngTarget, int maxAllowedTimeInMs) { - - try { - - int current = support.calculateCurrentSize(); - - if(DebugPolicy.COLLECT) - new DebugException("checking the need for collecting queries (current=" + current + " , lastKnownFixedSize=" + lastKnownFixedSize + " max free=" + 0 + ")").printStackTrace(); - - QueryProcessor.collecting = true; - - long start = System.nanoTime(); - - doCollect(current, 0); - - if(DebugPolicy.COLLECT) - System.out.println("collect finished with " + support.calculateCurrentSize() + " entries (lastKnownFixedSize=" + lastKnownFixedSize + ")."); - - long duration = System.nanoTime() - start; - - if(DebugPolicy.COLLECT) - System.err.println("Collect took " + 1e-9*duration + "s."); - - } catch (Throwable t) { - t.printStackTrace(); - } - - QueryProcessor.collecting = false; - - - } - - +package org.simantics.db.impl.query; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.util.IdentityHashSet; +import org.simantics.db.DevelopmentKeys; +import org.simantics.db.common.exception.DebugException; +import org.simantics.db.impl.query.QueryProcessor.QueryCollectorSupport; +import org.simantics.utils.Development; + +class QueryCollectorImpl2 implements QueryProcessor.QueryCollector { + + private final QueryProcessor queryProcessor; + + final private QueryCollectorSupport support; + + private int lastKnownFixedSize = 0; + + QueryCollectorImpl2(QueryProcessor queryProcessor, QueryCollectorSupport support) { + this.queryProcessor = queryProcessor; + this.support = support; + } + + private boolean findCollectables(CacheEntry entry, Map collectables, ArrayList result) { + + if (entry.isDiscarded()) { + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYCOLLECTOR, Bindings.BOOLEAN)) { + System.err.println("GC: discarded entry " + entry); + } + } + return true; + } + + if (entry.isPending()) { + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYCOLLECTOR, Bindings.BOOLEAN)) { + System.err.println("GC: pending entry " + entry + " was not collected."); + } + } + collectables.remove(entry); + return false; + } + + if (this.queryProcessor.listening.hasListenerAfterDisposing(entry)) { + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYCOLLECTOR, Bindings.BOOLEAN)) { + System.err.println("GC: listened entry " + entry + " was not collected. Entry=" + entry); + } + } + collectables.remove(entry); + return false; + } + + for (CacheEntry parent : entry.getParents(queryProcessor)) { + + boolean parentIsCollectable = false; + + if (!collectables.containsKey(parent)) { + collectables.put(parent, true); + parentIsCollectable = findCollectables(parent, collectables, result); + } else { + parentIsCollectable = collectables.get(parent); + } + + if(!parentIsCollectable) { + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYCOLLECTOR, Bindings.BOOLEAN)) { + System.err.println("GC: due to bound parent " + parent + " the entry + " + entry + " was not collected."); + } + } + collectables.remove(entry); + return false; + } + + } + + if(entry.shouldBeCollected()) { + // This can be collected + result.add(entry); + return true; + } else { + return false; + } + + } + + private List findCollectables() { + + ArrayList result = new ArrayList(); + + IdentityHashMap collectables = new IdentityHashMap(); + Collection rootList = support.getRootList(); + for (CacheEntry entry : rootList) { + if(!collectables.containsKey(entry)) { + collectables.put(entry, true); + findCollectables(entry, collectables, result); + } + } + + if(Development.DEVELOPMENT) { + IdentityHashSet set = new IdentityHashSet(); + for(CacheEntry entry : result) { + if(!set.add(entry)) throw new IllegalStateException(); + } + } + + return result; + + } + + private void doCollect(int currentSize, int maxNumberOfCollectableQueries) { + + List collectables = findCollectables(); + + // Compute amount of free queries + int freeCount = collectables.size(); + + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYCOLLECTOR, Bindings.BOOLEAN)) { + System.err.println("collector found " + freeCount + " free queries."); + } + } + + lastKnownFixedSize = currentSize - freeCount; + + // No need to collect + if(freeCount < maxNumberOfCollectableQueries) return; + + int target = freeCount - maxNumberOfCollectableQueries/2; + + + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYCOLLECTOR, Bindings.BOOLEAN)) { + System.err.println("collector found " + freeCount + " free queries."); + System.err.println("collector removes " + target + " free queries."); + } + } + + for(CacheEntry entry : collectables) { + if(queryProcessor.removeQuery(entry)) + if(--target < 0) break; + } + + // Prune discarded parents + ArrayList removals = new ArrayList(); + for (CacheEntry entry : support.allCaches().toCollection()) { + for(CacheEntry p : entry.getParents(queryProcessor)) { + if(p.isDiscarded()) removals.add(p); + } + for(CacheEntry r : removals) { + entry.removeParent(r); + } + removals.clear(); + } + + + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYCOLLECTOR, Bindings.BOOLEAN)) { + System.err.println("collect found " + freeCount + " collectable entries."); + } + } + + return; + + } + + @Override + public void collect(int youngTarget, int maxAllowedTimeInMs) { + + try { + + + int current = support.calculateCurrentSize(); + + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYCOLLECTOR, Bindings.BOOLEAN)) { + new DebugException("checking the need for collecting queries (current=" + current + " , lastKnownFixedSize=" + lastKnownFixedSize + " max free=" + 0 + ")").printStackTrace(); + } + } + + queryProcessor.cache.collecting = true; + + long start = System.nanoTime(); + + doCollect(current, 0); + + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYCOLLECTOR, Bindings.BOOLEAN)) { + System.err.println("collect finished with " + support.calculateCurrentSize() + " entries (lastKnownFixedSize=" + lastKnownFixedSize + ")."); + } + } + + long duration = System.nanoTime() - start; + + if (Development.DEVELOPMENT) { + if(Development.getProperty(DevelopmentKeys.QUERYCOLLECTOR, Bindings.BOOLEAN)) { + System.err.println("Collect took " + 1e-9*duration + "s."); + } + } + + } catch (Throwable t) { + t.printStackTrace(); + } + + queryProcessor.cache.collecting = false; + + } + + } \ No newline at end of file