X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.impl%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fimpl%2Fquery%2FQueryCollectorImpl.java;fp=bundles%2Forg.simantics.db.impl%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fimpl%2Fquery%2FQueryCollectorImpl.java;h=3d5a5a50604d7f3f16e520c80067c2cc3d3be67c;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCollectorImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCollectorImpl.java new file mode 100644 index 000000000..3d5a5a506 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCollectorImpl.java @@ -0,0 +1,196 @@ +package org.simantics.db.impl.query; + +import org.simantics.db.impl.query.QueryProcessor.QueryCollectorSupport; + +class QueryCollectorImpl implements QueryProcessor.QueryCollector { + + private static final boolean DEBUG = false; + private static final boolean DEBUG_STATUS = false; + + private final QueryProcessor queryProcessor; + + final private QueryCollectorSupport support; + + /* + * Set to true: at end of iteration if moreAll is false + * Set to false: upon gc start and whenever a prospect is added. + * + */ + boolean doneAll = false; + /* + * Set to true: upon gc start and whenever a prospect is added. + * Set to false: at end of entry iteration + * => if this is already false at end of entry iteration => no more work to be done + */ + int moreAll = 0; + + /* + * Change propagation is in progress + */ + boolean propagate = true; + + + private static final int COLLECT_N = 1000; + + private long spent = 0; + + QueryCollectorImpl(QueryProcessor queryProcessor, QueryCollectorSupport support) { + this.queryProcessor = queryProcessor; + this.support = support; + } + + @Override + public void collect(int youngTarget, int allowedTimeInMs) { + + long start = System.nanoTime(); + + // Refresh current size + int size = support.calculateCurrentSize(); + int bound = queryProcessor.boundQueries; + int young = size - bound; + int youngPct = size > 0 ? 100*young / size : 0; + + // Initialize support for new run + // If support returns 0 we are starting from 0 + if(support.start(youngTarget == 0)) { + + moreAll = 0; + + // We monitor all prospects here + CacheEntryBase prospect = support.iterate(0); + while(prospect != null) { + if(prospect.isDiscarded()) { + support.remove(); + propagate = true; + } else { + CacheEntry parent = prospect.getFirstParent(queryProcessor); + if(parent == null) { + tryCollect(prospect); + } else { + support.setLevel(prospect, parent.getLevel() + 1); + } + } + prospect = support.iterate(0); + } + + // If no prospects were collected and most of the queries are old we can stop here + if(!propagate && youngPct < youngTarget) { +// System.err.println("collect2 skipped"); +// System.err.println("-size=" + size); +// System.err.println("-young=" + young); + return; + } + + } + + long test = (long)allowedTimeInMs*1000000; + + start(); + + while(true) { + + size = support.getCurrentSize(); + bound = queryProcessor.boundQueries; + + long elapsed = System.nanoTime()-start; + boolean timeCondition = elapsed > test; + + if(doneAll || timeCondition) { + + spent += elapsed; + + if(DEBUG_STATUS) + System.err.println("Query collector used " + 1e-9*elapsed + "s total queries: " + size + " bound queries: " + bound + " spent: " + (double)spent*1e-9); + + return; + + } + + // Iterate all entries and update sets + if(!doneAll) { +// long start2 = System.nanoTime(); + for(int i=0;i