From: Antti Villberg Date: Thu, 14 Jun 2018 14:16:54 +0000 (+0300) Subject: Still working for multiple readers X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=68ce0966a57f5153b133c6283fdbae10f683b745;p=simantics%2Fplatform.git Still working for multiple readers gitlab #5 gitlab #6 Change-Id: Ica299d5dd091a641a7a1a18e1093602a9027dd57 --- diff --git a/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/GENodeQueryManager.java b/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/GENodeQueryManager.java index 6921a3b2f..d6bba94bf 100644 --- a/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/GENodeQueryManager.java +++ b/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/GENodeQueryManager.java @@ -511,4 +511,8 @@ public class GENodeQueryManager implements NodeQueryManager, PrimitiveQueryUpdat ge.getCache().decRef(context); } + public void execFromQuery(Runnable runnable) { + ge.execFromQuery(runnable); + } + } diff --git a/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/IGraphExplorerContext.java b/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/IGraphExplorerContext.java index b832f6c66..342153604 100644 --- a/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/IGraphExplorerContext.java +++ b/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/IGraphExplorerContext.java @@ -60,5 +60,6 @@ public interface IGraphExplorerContext extends IDisposable { int getActivityInt(); void scheduleQueryUpdate(Runnable r); + void execFromQuery(Runnable r); } diff --git a/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/viewpoints/ViewpointStub.java b/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/viewpoints/ViewpointStub.java index 4895d3f75..b33b57a0b 100644 --- a/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/viewpoints/ViewpointStub.java +++ b/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/viewpoints/ViewpointStub.java @@ -29,10 +29,21 @@ public abstract class ViewpointStub implements Viewpoint { protected Boolean hasChildren = Viewpoint.PENDING_HAS_CHILDREN; final public void setChildren(PrimitiveQueryUpdater updater, NodeContext[] children) { + if (children == null) throw new NullPointerException(this + ": null children produced by " + getClass().getName()); - for(NodeContext c : children) updater.incRef(c); - for(NodeContext c : this.children) updater.decRef(c); + + final NodeContext[] currentChildren = this.children; + + updater.execFromQuery(new Runnable() { + + @Override + public void run() { + for(NodeContext c : children) updater.incRef(c); + for(NodeContext c : currentChildren) updater.decRef(c); + } + + }); this.children = children; } diff --git a/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/NatTableGraphExplorer.java b/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/NatTableGraphExplorer.java index 2e9d5a1fc..2d2e9ffee 100644 --- a/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/NatTableGraphExplorer.java +++ b/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/NatTableGraphExplorer.java @@ -2384,6 +2384,11 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap } } + @Override + public void execFromQuery(java.lang.Runnable r) { + ge.queryUpdateScheduler.execute(r); + } + Runnable QUERY_UPDATE_SCHEDULER = new Runnable() { @Override public void run() { diff --git a/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl.java b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl.java index 0e45f86ca..37532c64f 100644 --- a/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl.java +++ b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl.java @@ -465,6 +465,11 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph queryUpdateScheduler.execute(QUERY_UPDATE_SCHEDULER); } } + + @Override + public void execFromQuery(java.lang.Runnable r) { + queryUpdateScheduler.execute(r); + } Runnable QUERY_UPDATE_SCHEDULER = new Runnable() { @Override diff --git a/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl2.java b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl2.java index 928bed03f..c3407a4fd 100644 --- a/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl2.java +++ b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl2.java @@ -1609,6 +1609,11 @@ public class GraphExplorerImpl2 extends GraphExplorerImplBase implements GraphEx } } + @Override + public void execFromQuery(java.lang.Runnable r) { + ge.queryUpdateScheduler.execute(r); + } + Runnable QUERY_UPDATE_SCHEDULER = new Runnable() { @Override public void run() { diff --git a/bundles/org.simantics.browsing.ui/src/org/simantics/browsing/ui/PrimitiveQueryUpdater.java b/bundles/org.simantics.browsing.ui/src/org/simantics/browsing/ui/PrimitiveQueryUpdater.java index c10df01b0..c48e947a8 100644 --- a/bundles/org.simantics.browsing.ui/src/org/simantics/browsing/ui/PrimitiveQueryUpdater.java +++ b/bundles/org.simantics.browsing.ui/src/org/simantics/browsing/ui/PrimitiveQueryUpdater.java @@ -63,5 +63,7 @@ public interface PrimitiveQueryUpdater { void incRef(NodeContext context); void decRef(NodeContext context); + + void execFromQuery(Runnable runnable); } \ No newline at end of file diff --git a/bundles/org.simantics.db.common/META-INF/MANIFEST.MF b/bundles/org.simantics.db.common/META-INF/MANIFEST.MF index f0ac2886d..b05ec52cd 100644 --- a/bundles/org.simantics.db.common/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.db.common/META-INF/MANIFEST.MF @@ -25,6 +25,7 @@ Export-Package: org.simantics.db.common, org.simantics.db.common.internal.config;x-friends:="org.simantics.db.procore", org.simantics.db.common.issue, org.simantics.db.common.primitiverequest, + org.simantics.db.common.procedure, org.simantics.db.common.procedure.adapter, org.simantics.db.common.procedure.guarded, org.simantics.db.common.procedure.single, diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/PossibleAdapter.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/PossibleAdapter.java index 61a47ecb1..983e1c546 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/PossibleAdapter.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/primitiverequest/PossibleAdapter.java @@ -11,53 +11,24 @@ *******************************************************************************/ package org.simantics.db.common.primitiverequest; -import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; import org.simantics.db.Resource; -import org.simantics.db.procedure.AsyncProcedure; -import org.simantics.db.request.AsyncRead; +import org.simantics.db.adaption.AdaptionService; +import org.simantics.db.common.request.BinaryRead; +import org.simantics.db.exception.DatabaseException; -final public class PossibleAdapter implements AsyncRead { +final public class PossibleAdapter extends BinaryRead, T> { - final private Resource resource; - final private Class clazz; - - @Override - public int hashCode() { - return resource.hashCode() + 31 * clazz.hashCode(); - } - - @Override - public boolean equals(Object object) { - if (this == object) - return true; - else if (object == null) - return false; - else if (getClass() != object.getClass()) - return false; - PossibleAdapter r = (PossibleAdapter)object; - return resource.equals(r.resource) && clazz.equals(r.clazz); - } - - @Override - public int threadHash() { - return hashCode(); - } - - @Override - public int getFlags() { - return 0; - } - public PossibleAdapter(Resource resource, Class clazz) { - this.resource = resource; - this.clazz = clazz; + super(resource, clazz); } @Override - public void perform(AsyncReadGraph graph, AsyncProcedure procedure) { - - graph.forPossibleAdapted(resource, clazz, procedure); - + public T perform(ReadGraph graph) throws DatabaseException { + + final AdaptionService service = graph.peekService(AdaptionService.class); + return service.adapt(graph, parameter, parameter, Resource.class, parameter2, true); + } } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java new file mode 100644 index 000000000..d239c87f7 --- /dev/null +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/BlockingAsyncProcedure.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.db.common.procedure; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.AsyncProcedure; + +public class BlockingAsyncProcedure implements AsyncProcedure { + + final private Object key; + private Result result = null; + private Throwable exception = null; + final private AsyncProcedure procedure; + final private Semaphore semaphore = new Semaphore(0); +// final private AtomicBoolean latch; + + public BlockingAsyncProcedure(AsyncProcedure procedure, Object key) { +// assert(procedure != null); + this.key = key; + this.procedure = procedure; + if(key == null) + System.err.println("asd"); + //System.err.println("BlockingAsyncProcedure " + key); +// latch = new AtomicBoolean(false); + } + + @Override + public void execute(AsyncReadGraph graph, Result result) { + this.result = result; + semaphore.release(); +// if(latch.compareAndSet(false, true)) { + try { + if(procedure != null) procedure.execute(graph, result); + } catch (Throwable throwable) { + Logger.defaultLogError("AsyncProcedure.execute threw for " + procedure, throwable); + } +// } finally { +//// System.err.println("ResultCallWrappedSingleQueryProcedure4 dec " + key); +// } +// } else { +// Logger.defaultLogError("Procedure was called many times (this time is execute)"); +// } + } + + @Override + public void exception(AsyncReadGraph graph, Throwable t) { + this.exception = t; + semaphore.release(); +// if(latch.compareAndSet(false, true)) { + try { + if(procedure != null) procedure.exception(graph, t); + } catch (Throwable throwable) { + Logger.defaultLogError("AsyncProcedure.exception threw for " + procedure, throwable); + } finally { + } +// } else { +// Logger.defaultLogError("Procedure was called many times (this time is exception)"); +// } + + } + + public Result get() throws DatabaseException { + + try { + boolean success = semaphore.tryAcquire(10, TimeUnit.SECONDS); + if(!success) throw new DatabaseException("Timeout while waiting for async request to complete: " + key); + } catch (InterruptedException e) { + throw new DatabaseException(e); + } + + if(exception != null) { + if(exception instanceof DatabaseException) throw (DatabaseException)exception; + throw new DatabaseException(exception); + } else { + return result; + } + + } + + public Result getResult() { + return result; + } + + public Throwable getException() { + return exception; + } + + @Override + public String toString() { + return "." + procedure; + } + +} diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java index 7184acbc5..fb771a35a 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/AsyncBarrierImpl.java @@ -324,13 +324,13 @@ final public class AsyncBarrierImpl extends AtomicInteger implements AsyncBarrie if(Development.DEVELOPMENT) { impl.processor.threadLocks[0].lock(); - System.err.println("-queues=" + impl.processor.queues[0].size()); +// System.err.println("-queues=" + impl.processor.queues[0].size()); impl.processor.threadLocks[0].unlock(); - System.err.println("-own=" + impl.processor.ownTasks[0].size()); - System.err.println("-ownSync=" + impl.processor.ownSyncTasks[0].size()); - for(SessionTask task : impl.processor.ownSyncTasks[0]) { - System.err.println("--" + task); - } +// System.err.println("-own=" + impl.processor.ownTasks[0].size()); +// System.err.println("-ownSync=" + impl.processor.ownSyncTasks[0].size()); +// for(SessionTask task : impl.processor.ownSyncTasks[0]) { +// System.err.println("--" + task); +// } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java index c6e41f618..f0147e047 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java @@ -88,6 +88,7 @@ import org.simantics.db.common.primitiverequest.UniqueAdapter; import org.simantics.db.common.primitiverequest.Value; import org.simantics.db.common.primitiverequest.ValueImplied; import org.simantics.db.common.primitiverequest.VariantValueImplied; +import org.simantics.db.common.procedure.BlockingAsyncProcedure; import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter; import org.simantics.db.common.procedure.adapter.ProcedureAdapter; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; @@ -136,6 +137,7 @@ import org.simantics.db.impl.ResourceImpl; import org.simantics.db.impl.internal.RandomAccessValueSupport; import org.simantics.db.impl.internal.ResourceData; import org.simantics.db.impl.procedure.CallWrappedSingleQueryProcedure4; +import org.simantics.db.impl.procedure.InternalProcedure; import org.simantics.db.impl.procedure.ResultCallWrappedQueryProcedure4; import org.simantics.db.impl.procedure.ResultCallWrappedSingleQueryProcedure4; import org.simantics.db.impl.query.CacheEntry; @@ -144,6 +146,7 @@ import org.simantics.db.impl.query.QueryCacheBase; import org.simantics.db.impl.query.QueryProcessor; import org.simantics.db.impl.query.QuerySupport; import org.simantics.db.impl.query.TripleIntProcedure; +import org.simantics.db.impl.query.QueryProcessor.SessionTask; import org.simantics.db.impl.support.ResourceSupport; import org.simantics.db.procedure.AsyncListener; import org.simantics.db.procedure.AsyncMultiListener; @@ -283,8 +286,17 @@ public class ReadGraphImpl implements ReadGraph { try { - return syncRequest(new org.simantics.db.common.primitiverequest.Resource( - id)); +// assert (id != null); +// assert (procedure != null); +// +// processor.forResource(this, id, procedure); +// +//// return syncRequest(new org.simantics.db.common.primitiverequest.Resource( +//// id)); + + Integer rid = QueryCache.resultURIToResource(this, id, parent, null); + if(rid == 0) throw new ResourceNotFoundException(id); + return processor.querySupport.getResource(rid); } catch (ResourceNotFoundException e) { @@ -314,8 +326,10 @@ public class ReadGraphImpl implements ReadGraph { try { - return syncRequest(new org.simantics.db.common.primitiverequest.Resource( - id)); + return getResource(id); + +// return syncRequest(new org.simantics.db.common.primitiverequest.Resource( +// id)); } catch (ResourceNotFoundException e) { @@ -2050,10 +2064,12 @@ public class ReadGraphImpl implements ReadGraph { throws DatabaseException { assert (request != null); - AsyncReadProcedure procedure = new AsyncReadProcedure(); - syncRequest(request, procedure); - procedure.checkAndThrow(); - return procedure.result; +// AsyncReadProcedure procedure = new AsyncReadProcedure(); + BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(null, request); + syncRequest(request, ap); + return ap.get(); +// procedure.checkAndThrow(); +// return procedure.result; // return syncRequest(request, new AsyncProcedureAdapter()); @@ -2085,14 +2101,18 @@ public class ReadGraphImpl implements ReadGraph { ListenerBase listener = getListenerBase(procedure); - final ResultCallWrappedSingleQueryProcedure4 wrapper = new ResultCallWrappedSingleQueryProcedure4( - procedure, request); + BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(procedure, request); + +// final ResultCallWrappedSingleQueryProcedure4 wrapper = new ResultCallWrappedSingleQueryProcedure4( +// procedure, request); - QueryCache.runnerAsyncReadEntry(this, request, parent, listener, wrapper); + QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true); //processor.query(this, request, parent, wrapper, listener); - return wrapper.getResult(); + return ap.get(); + +// return wrapper.getResult(); // if (parent != null || listener != null || ((request.getFlags() & RequestFlags.SCHEDULE) > 0)) { // @@ -2160,10 +2180,14 @@ public class ReadGraphImpl implements ReadGraph { ListenerBase listener = getListenerBase(procedure); assert(listener == null); + BlockingAsyncProcedure ap = new BlockingAsyncProcedure<>(procedure, request); + // final ResultCallWrappedSingleQueryProcedure4 wrapper = new ResultCallWrappedSingleQueryProcedure4( // procedure, request); - QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure); + QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true); + + ap.get(); } @@ -5400,47 +5424,64 @@ public class ReadGraphImpl implements ReadGraph { assert (request != null); assert (procedure != null); + + processor.schedule(Integer.MIN_VALUE, new SessionTask(request, processor.THREAD_MASK+1, -1) { - final ListenerBase listener = getListenerBase(procedure); - - if (parent != null || listener != null) { - - try { - QueryCache.runnerReadEntry(this, request, parent, listener, procedure); - //processor.query(this, request, parent, procedure,listener); - } catch (DatabaseException e) { - Logger.defaultLogError(e); - // This throwable has already been transferred to procedure at this point - do nothing about it - // - } - - } else { - -// final ReadGraphImpl newGraph = newSync(); - - try { - - T result = request.perform(this); - - try { - procedure.execute(this, result); - } catch (Throwable t) { - Logger.defaultLogError(t); - } - - } catch (Throwable t) { - + @Override + public void run(int thread) { try { - procedure.exception(this, t); - } catch (Throwable t2) { - Logger.defaultLogError(t2); + final ListenerBase listener = getListenerBase(procedure); + QueryCache.runnerReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false); + } catch (DatabaseException e) { + Logger.defaultLogError(e); } - - } finally { - } + + }); - } + +// quer +// +// final ListenerBase listener = getListenerBase(procedure); +// +// if (parent != null || listener != null) { +// +// try { +// QueryCache.runnerReadEntry(this, request, parent, listener, procedure); +// //processor.query(this, request, parent, procedure,listener); +// } catch (DatabaseException e) { +// Logger.defaultLogError(e); +// // This throwable has already been transferred to procedure at this point - do nothing about it +// // +// } +// +// } else { +// +//// final ReadGraphImpl newGraph = newSync(); +// +// try { +// +// T result = request.perform(this); +// +// try { +// procedure.execute(this, result); +// } catch (Throwable t) { +// Logger.defaultLogError(t); +// } +// +// } catch (Throwable t) { +// +// try { +// procedure.exception(this, t); +// } catch (Throwable t2) { +// Logger.defaultLogError(t2); +// } +// +// } finally { +// +// } +// +// } } @@ -5512,38 +5553,55 @@ public class ReadGraphImpl implements ReadGraph { assert (request != null); assert (procedure != null); - final ListenerBase listener = getListenerBase(procedure); + //final ListenerBase listener = getListenerBase(procedure); - if (parent != null || listener != null) { + processor.schedule(Integer.MIN_VALUE, new SessionTask(request, processor.THREAD_MASK+1, -1) { - try { - QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure); - //processor.query(this, request, parent, procedure, listener); - } catch (DatabaseException e) { - Logger.defaultLogError(e); + @Override + public void run(int thread) { + try { + final ListenerBase listener = getListenerBase(procedure); + QueryCache.runnerAsyncReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } } + + }); - } else { - - try { - - request.perform(this, new CallWrappedSingleQueryProcedure4(procedure, request)); - - } catch (Throwable t) { - - if (t instanceof DatabaseException) - procedure.exception(this, t); - else - procedure - .exception( - this, - new DatabaseException( - "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)", - t)); + - } - } +// if (parent != null || listener != null) { +// +// try { +// QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure); +// //processor.query(this, request, parent, procedure, listener); +// } catch (DatabaseException e) { +// Logger.defaultLogError(e); +// } +// +// } else { +// +// try { +// +// request.perform(this, new CallWrappedSingleQueryProcedure4(procedure, request)); +// +// } catch (Throwable t) { +// +// if (t instanceof DatabaseException) +// procedure.exception(this, t); +// else +// procedure +// .exception( +// this, +// new DatabaseException( +// "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)", +// t)); +// +// } +// +// } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java index ca485f989..8462433f1 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java @@ -802,6 +802,10 @@ final public class WriteGraphImpl extends ReadGraphImpl implements WriteGraph { Layer0 b = getBuiltins(); initBuiltinValues(b); + if(resource.toString().equals("[id=$319492]") && predicate.toString().equals("[id=$235477]")) + System.err.println("foobar2"); + + Statement literalStatement = getPossibleStatement(resource, predicate); if(literalStatement != null && resource.equals(literalStatement.getSubject())) { diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java index 410db7118..184276412 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedPredicates.java @@ -82,7 +82,7 @@ final public class AssertedPredicates extends CollectionUnaryQuery } - @Override + //@Override public Object compute(ReadGraphImpl graph, final IntProcedure proc) throws DatabaseException { QueryProcessor processor = graph.processor; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatements.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatements.java index 90daa9a84..eba1205e1 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatements.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatements.java @@ -137,7 +137,7 @@ final public class AssertedStatements extends CollectionBinaryQuery extends CacheEntryBase procedure) throws DatabaseException { return graph.processor.cache.performQuery(graph, request, 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 8e6cbd145..08f0ad8b5 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 @@ -45,6 +45,8 @@ final public class AsyncReadEntry extends CacheEntryBase> { final public void addOrSet(AsyncReadGraph graph, Object item) { +// System.err.println("addOrSet " + request + " " + Thread.currentThread() + " " + item); + assert(isPending()); synchronized(this) { @@ -142,7 +144,7 @@ final public class AsyncReadEntry extends CacheEntryBase> { } - @Override + //@Override public Object compute(ReadGraphImpl graph, AsyncProcedure procedure) throws DatabaseException { ReadGraphImpl queryGraph = graph.withParent(this); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQueryHash.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQueryHash.java index 833eafc4c..b460a22bd 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQueryHash.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/BinaryQueryHash.java @@ -45,11 +45,6 @@ abstract public class BinaryQueryHash extends THash { throw new Error("Not possible!"); } - @Override - public Object compute(ReadGraphImpl graph, Procedure procedure) throws DatabaseException { - throw new Error("Not possible!"); - } - @Override Object performFromCache(ReadGraphImpl graph, Procedure procedure) throws DatabaseException { throw new Error("Not possible!"); 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 1506b54af..dea5de5a7 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 @@ -460,6 +460,6 @@ abstract public class CacheEntryBase extends CacheEntry { public CacheEntryBase() { } - abstract public Object compute(ReadGraphImpl graph, Procedure procedure) throws DatabaseException; + //abstract public Object compute(ReadGraphImpl graph, Procedure procedure) throws DatabaseException; } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java index 9f24ba640..7dd00d29b 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ChildMap.java @@ -32,7 +32,7 @@ final public class ChildMap extends UnaryQuery> procedure) throws DatabaseException { computeForEach(graph, id, this, procedure); return getResult(); 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 ed6039847..008faeea5 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 @@ -38,15 +38,15 @@ public class CodeGen { content.append("\n"); } - public void generateQuery(StringBuilder content, String clazz, String[] signature, boolean runnerShortcut) { - generateGetOrCreate(content, clazz, signature); + public void generateQuery(StringBuilder content, String clazz, String[] signature, boolean runnerShortcut, boolean genAsync) { + generateGetOrCreate(content, clazz, signature, genAsync); generateRemove(content, clazz, signature); - generateRunner(content, clazz, signature, runnerShortcut); + generateRunner(content, clazz, signature, runnerShortcut, genAsync); } - public void generateRunner(StringBuilder content, String clazz, String[] signature, boolean shortcut) { + public void generateRunner(StringBuilder content, String clazz, String[] signature, boolean shortcut, boolean genAsync) { - line(content, "public static void runner" + clazz + "(ReadGraphImpl graph, " + signature[0] + ", CacheEntry parent, ListenerBase listener, " + signature[4] + " procedure) throws DatabaseException {"); + line(content, "public static void runner" + clazz + "(ReadGraphImpl graph, " + signature[0] + ", CacheEntry parent, ListenerBase listener, final " + signature[4] + " procedure" + (genAsync ? ", boolean isSync" : "") + ") throws DatabaseException {"); line(content, " QueryCache cache = graph.processor.cache;"); if(shortcut) { line(content, " if(parent == null && listener == null && !cache.shouldCache(graph.processor, " + signature[1] + ")) {"); @@ -54,13 +54,30 @@ public class CodeGen { line(content, " return;"); line(content, " }"); } - line(content, " if(procedure == null) procedure = emptyProcedure" + clazz + ";"); - line(content, " " + clazz + " entry = (" + clazz + ")cache.getOrCreate" + clazz + "(" + signature[1] + ");"); - line(content, " ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false);"); - line(content, " if(entry.isReady()) entry.performFromCache(graph, procedure);"); + line(content, " " + clazz + " entry = (" + clazz + ")cache.getOrCreate" + clazz + "(" + signature[1] + (genAsync ? ", isSync" : "") + ");"); + if(genAsync) { + line(content, " if(entry == null) {"); + line(content, " graph.processor.schedule(Integer.MIN_VALUE, new SessionTask(r, graph.processor.THREAD_MASK+1, -1) {"); + line(content, " @Override"); + line(content, " public void run(int thread) {"); + line(content, " try {"); + line(content, " assert(!isSync);"); + line(content, " runner" + clazz + "(graph, r, parent, listener, procedure, isSync);"); + line(content, " } catch (DatabaseException e) {"); + line(content, " Logger.defaultLogError(e);"); + line(content, " }"); + line(content, " }"); + line(content, " });"); + line(content, " return;"); + line(content, " }"); + } + line(content, " " + signature[4] + " procedure_ = procedure != null ? procedure : emptyProcedure" + clazz + ";"); + line(content, " ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);"); + line(content, " if(entry.isReady()) entry.performFromCache(graph, procedure_);"); line(content, " else {"); - if(shortcut) line(content, " " + clazz + ".computeForEach(graph, " + signature[1] + ", entry, procedure);"); - else line(content, " entry.compute(graph, procedure);"); + line(content, " assert(entry.isPending());"); + if(shortcut) line(content, " " + clazz + ".computeForEach(graph, " + signature[1] + ", entry, procedure_);"); + else line(content, " entry.compute(graph, procedure_);"); line(content, " if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());"); line(content, " }"); line(content, "}"); @@ -81,11 +98,11 @@ public class CodeGen { } - public void generateGetOrCreate(StringBuilder content, String clazz, String[] signature) { + public void generateGetOrCreate(StringBuilder content, String clazz, String[] signature, boolean genAsync) { String lower = Character.toLowerCase(clazz.charAt(0)) + clazz.substring(1); - line(content, "" + clazz + " getOrCreate" + clazz + "(" + signature[0] + ") throws DatabaseException {"); + line(content, "" + clazz + " getOrCreate" + clazz + "(" + signature[0] + (genAsync ? ", boolean isSync" : "") + ") throws DatabaseException {"); line(content, " " + clazz + " existing = null;"); line(content, " synchronized(" + lower + "Map) {"); line(content, " existing = (" + clazz + ")" + lower + "Map.get(" + signature[1] + ");"); @@ -102,7 +119,14 @@ public class CodeGen { line(content, " return existing;"); line(content, " }"); line(content, " }"); - line(content, " if(existing.isPending()) waitPending(existing);"); + if(genAsync) { + line(content, " if(existing.isPending()) {"); + line(content, " if(isSync) waitPending(existing);"); + line(content, " else return null;"); + line(content, " }"); + } else { + line(content, " if(existing.isPending()) waitPending(existing);"); + } line(content, " return existing;"); line(content, "}"); line(content, ""); @@ -127,9 +151,11 @@ public class CodeGen { content.append("import org.simantics.db.ObjectResourceIdMap;\n"); content.append("import org.simantics.db.RelationInfo;\n"); + content.append("import org.simantics.db.common.utils.Logger;\n"); content.append("import org.simantics.db.exception.DatabaseException;\n"); content.append("import org.simantics.db.impl.graph.ReadGraphImpl;\n"); content.append("import org.simantics.db.impl.procedure.InternalProcedure;\n"); + content.append("import org.simantics.db.impl.query.QueryProcessor.SessionTask;\n"); content.append("import org.simantics.db.procedure.AsyncMultiProcedure;\n"); content.append("import org.simantics.db.procedure.AsyncProcedure;\n"); content.append("import org.simantics.db.procedure.ListenerBase;\n"); @@ -149,31 +175,31 @@ public class CodeGen { line(content,"}"); content.append("\n"); - generateQuery(content, "Objects", signatureR2IP, true); - generateQuery(content, "Statements", signatureR2TIP, true); - generateQuery(content, "DirectObjects", signatureR2IP, true); - generateQuery(content, "RelationInfoQuery", signatureR1RelationInfo, true); - generateQuery(content, "URIToResource", signatureID1, true); - generateQuery(content, "ValueQuery", signatureR1Bytes, true); - generateQuery(content, "OrderedSet", signatureR1IP, true); - generateQuery(content, "PrincipalTypes", signatureR1IP, true); - generateQuery(content, "DirectPredicates", signatureR1IntSet, true); - generateQuery(content, "Predicates", signatureR1IntSet, true); - generateQuery(content, "ReadEntry", signatureRead, true); - generateQuery(content, "AsyncReadEntry", signatureAsyncRead, true); - generateQuery(content, "Types", signatureR1IntSet, true); + generateQuery(content, "Objects", signatureR2IP, true, false); + generateQuery(content, "Statements", signatureR2TIP, true, false); + generateQuery(content, "DirectObjects", signatureR2IP, true, false); + generateQuery(content, "RelationInfoQuery", signatureR1RelationInfo, true, false); + generateQuery(content, "URIToResource", signatureID1, true, false); + generateQuery(content, "ValueQuery", signatureR1Bytes, true, false); + generateQuery(content, "OrderedSet", signatureR1IP, true, false); + generateQuery(content, "PrincipalTypes", signatureR1IP, true, false); + generateQuery(content, "DirectPredicates", signatureR1IntSet, true, false); + generateQuery(content, "Predicates", signatureR1IntSet, true, false); + generateQuery(content, "ReadEntry", signatureRead, true, true); + generateQuery(content, "AsyncReadEntry", signatureAsyncRead, true, true); + generateQuery(content, "Types", signatureR1IntSet, true, false); //generateQuery(content, "NamespaceIndex", signatureID2, true); - generateQuery(content, "ChildMap", signatureChildMap, true); + generateQuery(content, "ChildMap", signatureChildMap, true, false); - generateQuery(content, "AssertedStatements", signatureR2TIP, false); - generateQuery(content, "AssertedPredicates", signatureR1IP, false); - generateQuery(content, "DirectSuperRelations", signatureR1IP, false); - generateQuery(content, "SuperTypes", signatureR1IntSet, false); - generateQuery(content, "TypeHierarchy", signatureR1IntSet, false); - generateQuery(content, "SuperRelations", signatureR1IntSet, false); - generateQuery(content, "MultiReadEntry", signatureMultiRead, false); - generateQuery(content, "AsyncMultiReadEntry", signatureAsyncMultiRead, false); - generateQuery(content, "ExternalReadEntry", signatureExternalRead, false); + generateQuery(content, "AssertedStatements", signatureR2TIP, false, false); + generateQuery(content, "AssertedPredicates", signatureR1IP, false, false); + generateQuery(content, "DirectSuperRelations", signatureR1IP, false, false); + generateQuery(content, "SuperTypes", signatureR1IntSet, false, false); + generateQuery(content, "TypeHierarchy", signatureR1IntSet, false, false); + generateQuery(content, "SuperRelations", signatureR1IntSet, false, false); + generateQuery(content, "MultiReadEntry", signatureMultiRead, false, false); + generateQuery(content, "AsyncMultiReadEntry", signatureAsyncMultiRead, false, false); + generateQuery(content, "ExternalReadEntry", signatureExternalRead, false, false); content.append("}\n"); FileUtils.writeFile(source, content.toString().getBytes()); } catch (MalformedURLException e) { diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjects.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjects.java index c38a50b56..117056410 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjects.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectObjects.java @@ -51,7 +51,7 @@ final public class DirectObjects extends CollectionBinaryQuery { provider.cache.remove(this); } - @Override + //@Override public Object compute(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException { computeForEach(graph, r1(), r2(), this, procedure); return getResult(); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java index feb0533ef..63c54effe 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java @@ -33,7 +33,7 @@ final public class DirectPredicates extends CollectionUnaryQuery procedure) throws DatabaseException { return computeForEach(graph, id, this, procedure); } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectSuperRelations.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectSuperRelations.java index 3932f7da6..621bdad96 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectSuperRelations.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectSuperRelations.java @@ -62,7 +62,7 @@ final public class DirectSuperRelations extends UnaryQuery { } - @Override + //@Override public Object compute(final ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException { QueryProcessor processor = graph.processor; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java index 40b6f6fab..bd99e1bc4 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java @@ -193,7 +193,7 @@ final public class ExternalReadEntry extends CacheEntryBase // Do nothing - the state is already set and cannot be recomputed on demand } - @Override + //@Override public Object compute(ReadGraphImpl graph, AsyncProcedure procedure) throws DatabaseException { return graph.processor.cache.performQuery(graph, request, this, procedure); } 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 8d1003b80..f2fff24cf 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 @@ -204,7 +204,7 @@ final public class MultiReadEntry extends CacheEntryBase procedure) throws DatabaseException { return graph.processor.cache.performQuery(graph, request, this, procedure); } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java index 62fb3bdb8..1883d9c1f 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java @@ -648,7 +648,7 @@ final public class Objects extends CollectionBinaryQuery { } - @Override + //@Override public Object compute(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException { computeForEach(graph, r1(), r2(), this, procedure); return getResult(); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSet.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSet.java index 38c6be6e1..9e7bb5c92 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSet.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/OrderedSet.java @@ -76,7 +76,7 @@ final public class OrderedSet extends CollectionUnaryQuery { setResult(new IntArray()); } - @Override + //@Override public Object compute(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException { computeForEach(graph, id, this, procedure); return getResult(); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PossibleSuperRelation.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PossibleSuperRelation.java index 50e14d962..d391cec9c 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PossibleSuperRelation.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PossibleSuperRelation.java @@ -70,7 +70,7 @@ final public class PossibleSuperRelation extends UnaryQuery { } - @Override + //@Override public Object compute(final ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException { QueryProcessor processor = graph.processor; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java index e5cb6dfa1..03b17bba5 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java @@ -77,7 +77,7 @@ final public class Predicates extends UnaryQuery> { } - @Override + //@Override public Object compute(ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { computeForEach(graph, id, this, procedure); return getResult(); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypes.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypes.java index 81c0efc20..af4d20ebc 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypes.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypes.java @@ -75,7 +75,7 @@ final public class PrincipalTypes extends CollectionUnaryQuery { } - @Override + //@Override public Object compute(final ReadGraphImpl graph, final IntProcedure proc) throws DatabaseException { return computeForEach(graph, id, this, proc); } 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 49e02dece..3e7a25190 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 @@ -2,9 +2,11 @@ package org.simantics.db.impl.query; import org.simantics.db.ObjectResourceIdMap; import org.simantics.db.RelationInfo; +import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.impl.graph.ReadGraphImpl; import org.simantics.db.impl.procedure.InternalProcedure; +import org.simantics.db.impl.query.QueryProcessor.SessionTask; import org.simantics.db.procedure.AsyncMultiProcedure; import org.simantics.db.procedure.AsyncProcedure; import org.simantics.db.procedure.ListenerBase; @@ -49,18 +51,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerObjects(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, IntProcedure procedure) throws DatabaseException { + public static void runnerObjects(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r1,r2)) { Objects.computeForEach(graph, r1,r2, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureObjects; Objects entry = (Objects)cache.getOrCreateObjects(r1,r2); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureObjects; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - Objects.computeForEach(graph, r1,r2, entry, procedure); + assert(entry.isPending()); + Objects.computeForEach(graph, r1,r2, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -92,18 +95,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, TripleIntProcedure procedure) throws DatabaseException { + public static void runnerStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, final TripleIntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r1,r2)) { Statements.computeForEach(graph, r1,r2, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureStatements; Statements entry = (Statements)cache.getOrCreateStatements(r1,r2); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + TripleIntProcedure procedure_ = procedure != null ? procedure : emptyProcedureStatements; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - Statements.computeForEach(graph, r1,r2, entry, procedure); + assert(entry.isPending()); + Statements.computeForEach(graph, r1,r2, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -135,18 +139,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerDirectObjects(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, IntProcedure procedure) throws DatabaseException { + public static void runnerDirectObjects(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r1,r2)) { DirectObjects.computeForEach(graph, r1,r2, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureDirectObjects; DirectObjects entry = (DirectObjects)cache.getOrCreateDirectObjects(r1,r2); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureDirectObjects; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - DirectObjects.computeForEach(graph, r1,r2, entry, procedure); + assert(entry.isPending()); + DirectObjects.computeForEach(graph, r1,r2, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -178,18 +183,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerRelationInfoQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure procedure) throws DatabaseException { + public static void runnerRelationInfoQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { RelationInfoQuery.computeForEach(graph, r, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureRelationInfoQuery; RelationInfoQuery entry = (RelationInfoQuery)cache.getOrCreateRelationInfoQuery(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureRelationInfoQuery; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - RelationInfoQuery.computeForEach(graph, r, entry, procedure); + assert(entry.isPending()); + RelationInfoQuery.computeForEach(graph, r, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -221,18 +227,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerURIToResource(ReadGraphImpl graph, String id, CacheEntry parent, ListenerBase listener, InternalProcedure procedure) throws DatabaseException { + public static void runnerURIToResource(ReadGraphImpl graph, String id, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, id)) { URIToResource.computeForEach(graph, id, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureURIToResource; URIToResource entry = (URIToResource)cache.getOrCreateURIToResource(id); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureURIToResource; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - URIToResource.computeForEach(graph, id, entry, procedure); + assert(entry.isPending()); + URIToResource.computeForEach(graph, id, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -264,18 +271,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerValueQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure procedure) throws DatabaseException { + public static void runnerValueQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { ValueQuery.computeForEach(graph, r, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureValueQuery; ValueQuery entry = (ValueQuery)cache.getOrCreateValueQuery(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureValueQuery; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - ValueQuery.computeForEach(graph, r, entry, procedure); + assert(entry.isPending()); + ValueQuery.computeForEach(graph, r, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -307,18 +315,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerOrderedSet(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, IntProcedure procedure) throws DatabaseException { + public static void runnerOrderedSet(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { OrderedSet.computeForEach(graph, r, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureOrderedSet; OrderedSet entry = (OrderedSet)cache.getOrCreateOrderedSet(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureOrderedSet; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - OrderedSet.computeForEach(graph, r, entry, procedure); + assert(entry.isPending()); + OrderedSet.computeForEach(graph, r, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -350,18 +359,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerPrincipalTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, IntProcedure procedure) throws DatabaseException { + public static void runnerPrincipalTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { PrincipalTypes.computeForEach(graph, r, null, procedure); return; } - if(procedure == null) procedure = emptyProcedurePrincipalTypes; PrincipalTypes entry = (PrincipalTypes)cache.getOrCreatePrincipalTypes(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + IntProcedure procedure_ = procedure != null ? procedure : emptyProcedurePrincipalTypes; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - PrincipalTypes.computeForEach(graph, r, entry, procedure); + assert(entry.isPending()); + PrincipalTypes.computeForEach(graph, r, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -393,18 +403,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerDirectPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure procedure) throws DatabaseException { + public static void runnerDirectPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { DirectPredicates.computeForEach(graph, r, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureDirectPredicates; DirectPredicates entry = (DirectPredicates)cache.getOrCreateDirectPredicates(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureDirectPredicates; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - DirectPredicates.computeForEach(graph, r, entry, procedure); + assert(entry.isPending()); + DirectPredicates.computeForEach(graph, r, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -436,23 +447,24 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure procedure) throws DatabaseException { + public static void runnerPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { Predicates.computeForEach(graph, r, null, procedure); return; } - if(procedure == null) procedure = emptyProcedurePredicates; Predicates entry = (Predicates)cache.getOrCreatePredicates(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedurePredicates; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - Predicates.computeForEach(graph, r, entry, procedure); + assert(entry.isPending()); + Predicates.computeForEach(graph, r, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } - ReadEntry getOrCreateReadEntry(Read r) throws DatabaseException { + ReadEntry getOrCreateReadEntry(Read r, boolean isSync) throws DatabaseException { ReadEntry existing = null; synchronized(readEntryMap) { existing = (ReadEntry)readEntryMap.get(r); @@ -469,7 +481,10 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) { + if(isSync) waitPending(existing); + else return null; + } return existing; } @@ -479,23 +494,38 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, AsyncProcedure procedure) throws DatabaseException { + public static void runnerReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure, boolean isSync) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { ReadEntry.computeForEach(graph, r, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureReadEntry; - ReadEntry entry = (ReadEntry)cache.getOrCreateReadEntry(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + ReadEntry entry = (ReadEntry)cache.getOrCreateReadEntry(r, isSync); + if(entry == null) { + graph.processor.schedule(Integer.MIN_VALUE, new SessionTask(r, graph.processor.THREAD_MASK+1, -1) { + @Override + public void run(int thread) { + try { + assert(!isSync); + runnerReadEntry(graph, r, parent, listener, procedure, isSync); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + } + }); + return; + } + AsyncProcedure procedure_ = procedure != null ? procedure : emptyProcedureReadEntry; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - ReadEntry.computeForEach(graph, r, entry, procedure); + assert(entry.isPending()); + ReadEntry.computeForEach(graph, r, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } - AsyncReadEntry getOrCreateAsyncReadEntry(AsyncRead r) throws DatabaseException { + AsyncReadEntry getOrCreateAsyncReadEntry(AsyncRead r, boolean isSync) throws DatabaseException { AsyncReadEntry existing = null; synchronized(asyncReadEntryMap) { existing = (AsyncReadEntry)asyncReadEntryMap.get(r); @@ -512,7 +542,10 @@ public class QueryCache extends QueryCacheBase { return existing; } } - if(existing.isPending()) waitPending(existing); + if(existing.isPending()) { + if(isSync) waitPending(existing); + else return null; + } return existing; } @@ -522,18 +555,33 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, AsyncProcedure procedure) throws DatabaseException { + public static void runnerAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure, boolean isSync) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { AsyncReadEntry.computeForEach(graph, r, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureAsyncReadEntry; - AsyncReadEntry entry = (AsyncReadEntry)cache.getOrCreateAsyncReadEntry(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + AsyncReadEntry entry = (AsyncReadEntry)cache.getOrCreateAsyncReadEntry(r, isSync); + if(entry == null) { + graph.processor.schedule(Integer.MIN_VALUE, new SessionTask(r, graph.processor.THREAD_MASK+1, -1) { + @Override + public void run(int thread) { + try { + assert(!isSync); + runnerAsyncReadEntry(graph, r, parent, listener, procedure, isSync); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + } + }); + return; + } + AsyncProcedure procedure_ = procedure != null ? procedure : emptyProcedureAsyncReadEntry; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - AsyncReadEntry.computeForEach(graph, r, entry, procedure); + assert(entry.isPending()); + AsyncReadEntry.computeForEach(graph, r, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -565,18 +613,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure procedure) throws DatabaseException { + public static void runnerTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { Types.computeForEach(graph, r, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureTypes; Types entry = (Types)cache.getOrCreateTypes(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureTypes; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - Types.computeForEach(graph, r, entry, procedure); + assert(entry.isPending()); + Types.computeForEach(graph, r, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -608,18 +657,19 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerChildMap(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure> procedure) throws DatabaseException { + public static void runnerChildMap(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure> procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; if(parent == null && listener == null && !cache.shouldCache(graph.processor, r)) { ChildMap.computeForEach(graph, r, null, procedure); return; } - if(procedure == null) procedure = emptyProcedureChildMap; ChildMap entry = (ChildMap)cache.getOrCreateChildMap(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + InternalProcedure> procedure_ = procedure != null ? procedure : emptyProcedureChildMap; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - ChildMap.computeForEach(graph, r, entry, procedure); + assert(entry.isPending()); + ChildMap.computeForEach(graph, r, entry, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -651,14 +701,15 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerAssertedStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, TripleIntProcedure procedure) throws DatabaseException { + public static void runnerAssertedStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, final TripleIntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - if(procedure == null) procedure = emptyProcedureAssertedStatements; AssertedStatements entry = (AssertedStatements)cache.getOrCreateAssertedStatements(r1,r2); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + TripleIntProcedure procedure_ = procedure != null ? procedure : emptyProcedureAssertedStatements; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - entry.compute(graph, procedure); + assert(entry.isPending()); + entry.compute(graph, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -690,14 +741,15 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerAssertedPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, IntProcedure procedure) throws DatabaseException { + public static void runnerAssertedPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - if(procedure == null) procedure = emptyProcedureAssertedPredicates; AssertedPredicates entry = (AssertedPredicates)cache.getOrCreateAssertedPredicates(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureAssertedPredicates; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - entry.compute(graph, procedure); + assert(entry.isPending()); + entry.compute(graph, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -729,14 +781,15 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerDirectSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, IntProcedure procedure) throws DatabaseException { + public static void runnerDirectSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final IntProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - if(procedure == null) procedure = emptyProcedureDirectSuperRelations; DirectSuperRelations entry = (DirectSuperRelations)cache.getOrCreateDirectSuperRelations(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + IntProcedure procedure_ = procedure != null ? procedure : emptyProcedureDirectSuperRelations; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - entry.compute(graph, procedure); + assert(entry.isPending()); + entry.compute(graph, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -768,14 +821,15 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerSuperTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure procedure) throws DatabaseException { + public static void runnerSuperTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - if(procedure == null) procedure = emptyProcedureSuperTypes; SuperTypes entry = (SuperTypes)cache.getOrCreateSuperTypes(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureSuperTypes; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - entry.compute(graph, procedure); + assert(entry.isPending()); + entry.compute(graph, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -807,14 +861,15 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerTypeHierarchy(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure procedure) throws DatabaseException { + public static void runnerTypeHierarchy(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - if(procedure == null) procedure = emptyProcedureTypeHierarchy; TypeHierarchy entry = (TypeHierarchy)cache.getOrCreateTypeHierarchy(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureTypeHierarchy; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - entry.compute(graph, procedure); + assert(entry.isPending()); + entry.compute(graph, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -846,14 +901,15 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure procedure) throws DatabaseException { + public static void runnerSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, final InternalProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - if(procedure == null) procedure = emptyProcedureSuperRelations; SuperRelations entry = (SuperRelations)cache.getOrCreateSuperRelations(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + InternalProcedure procedure_ = procedure != null ? procedure : emptyProcedureSuperRelations; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - entry.compute(graph, procedure); + assert(entry.isPending()); + entry.compute(graph, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -885,14 +941,15 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerMultiReadEntry(ReadGraphImpl graph, MultiRead r, CacheEntry parent, ListenerBase listener, AsyncMultiProcedure procedure) throws DatabaseException { + public static void runnerMultiReadEntry(ReadGraphImpl graph, MultiRead r, CacheEntry parent, ListenerBase listener, final AsyncMultiProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - if(procedure == null) procedure = emptyProcedureMultiReadEntry; MultiReadEntry entry = (MultiReadEntry)cache.getOrCreateMultiReadEntry(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + AsyncMultiProcedure procedure_ = procedure != null ? procedure : emptyProcedureMultiReadEntry; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - entry.compute(graph, procedure); + assert(entry.isPending()); + entry.compute(graph, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -924,14 +981,15 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerAsyncMultiReadEntry(ReadGraphImpl graph, AsyncMultiRead r, CacheEntry parent, ListenerBase listener, AsyncMultiProcedure procedure) throws DatabaseException { + public static void runnerAsyncMultiReadEntry(ReadGraphImpl graph, AsyncMultiRead r, CacheEntry parent, ListenerBase listener, final AsyncMultiProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - if(procedure == null) procedure = emptyProcedureAsyncMultiReadEntry; AsyncMultiReadEntry entry = (AsyncMultiReadEntry)cache.getOrCreateAsyncMultiReadEntry(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + AsyncMultiProcedure procedure_ = procedure != null ? procedure : emptyProcedureAsyncMultiReadEntry; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - entry.compute(graph, procedure); + assert(entry.isPending()); + entry.compute(graph, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } @@ -963,14 +1021,15 @@ public class QueryCache extends QueryCacheBase { } } - public static void runnerExternalReadEntry(ReadGraphImpl graph, ExternalRead r, CacheEntry parent, ListenerBase listener, AsyncProcedure procedure) throws DatabaseException { + public static void runnerExternalReadEntry(ReadGraphImpl graph, ExternalRead r, CacheEntry parent, ListenerBase listener, final AsyncProcedure procedure) throws DatabaseException { QueryCache cache = graph.processor.cache; - if(procedure == null) procedure = emptyProcedureExternalReadEntry; ExternalReadEntry entry = (ExternalReadEntry)cache.getOrCreateExternalReadEntry(r); - ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure, false); - if(entry.isReady()) entry.performFromCache(graph, procedure); + AsyncProcedure procedure_ = procedure != null ? procedure : emptyProcedureExternalReadEntry; + ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false); + if(entry.isReady()) entry.performFromCache(graph, procedure_); else { - entry.compute(graph, procedure); + assert(entry.isPending()); + entry.compute(graph, procedure_); if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult()); } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java index d6924c708..24a2dbe96 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java @@ -2,6 +2,7 @@ package org.simantics.db.impl.query; import java.util.ArrayList; import java.util.Collection; +import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicBoolean; import org.simantics.db.AsyncReadGraph; @@ -640,7 +641,7 @@ public class QueryCacheBase { try { Thread.sleep(1); counter++; - if(counter > 1000) { + if(counter > 5000) { CacheEntryBase base = ((CacheEntryBase)entry); // if(base.created != null) { // System.err.println("created:"); @@ -918,6 +919,7 @@ public class QueryCacheBase { private AsyncProcedure procedure; private T result = null; private Throwable throwable = null; + private Semaphore s = new Semaphore(0); AsyncProcedureWrapper(AsyncProcedure procedure) { this.procedure = procedure; @@ -927,15 +929,22 @@ public class QueryCacheBase { public void execute(AsyncReadGraph graph, T result) { if(procedure != null) procedure.execute(graph, result); this.result = result; + s.release(); } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { if(procedure != null) procedure.exception(graph, throwable); this.throwable = throwable; + s.release(); } public T get() throws DatabaseException { + try { + s.acquire(); + } catch (InterruptedException e) { + e.printStackTrace(); + } if(throwable != null) { if(throwable instanceof DatabaseException) throw (DatabaseException)throwable; else throw new DatabaseException(throwable); @@ -1100,7 +1109,13 @@ public class QueryCacheBase { public static T resultReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, AsyncProcedure procedure) throws DatabaseException { AsyncProcedureWrapper wrap = new AsyncProcedureWrapper<>(procedure); - QueryCache.runnerReadEntry(graph, r, parent, listener, wrap); + QueryCache.runnerReadEntry(graph, r, parent, listener, wrap, true); + return wrap.get(); + } + + public static T resultAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, AsyncProcedure procedure) throws DatabaseException { + AsyncProcedureWrapper wrap = new AsyncProcedureWrapper<>(procedure); + QueryCache.runnerAsyncReadEntry(graph, r, parent, listener, wrap, true); return wrap.get(); } 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 f1e9233eb..2908bd43a 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 @@ -151,7 +151,9 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap QueryThread[] executors; - public ArrayList[] queues; +// public ArrayList[] queues; + + public LinkedList freeScheduling = new LinkedList(); enum ThreadState { @@ -163,11 +165,11 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap public ReentrantLock[] threadLocks; public Condition[] threadConditions; - public ArrayList[] ownTasks; + //public ArrayList[] ownTasks; - public ArrayList[] ownSyncTasks; + //public ArrayList[] ownSyncTasks; - ArrayList[] delayQueues; + //ArrayList[] delayQueues; final Object querySupportLock; @@ -176,19 +178,21 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap public void close() { } - final public void scheduleOwn(int caller, SessionTask request) { - ownTasks[caller].add(request); - } +// final public void scheduleOwn(int caller, SessionTask request) { +// ownTasks[caller].add(request); +// } final public void scheduleAlways(int caller, SessionTask request) { - int performer = request.thread; - if(caller == performer) { - ownTasks[caller].add(request); - } else { - schedule(caller, request); - } +// int performer = request.thread; +// if(caller == performer) { +// ownTasks[caller].add(request); +// } else { +// schedule(caller, request); +// } + schedule(caller, request); + } final public void schedule(int caller, SessionTask request) { @@ -202,19 +206,43 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap assert(request != null); - if(caller == performer) { - request.run(caller); - } else { - ReentrantLock queueLock = threadLocks[performer]; - queueLock.lock(); - queues[performer].add(request); - // This thread could have been sleeping - if(queues[performer].size() == 1) { - if(ThreadState.SLEEP == threadStates[performer]) sleepers.decrementAndGet(); - threadConditions[performer].signalAll(); - } - queueLock.unlock(); - } +// if(caller == performer) { +// request.run(caller); +// } else { + +// if(performer == THREADS) { + + synchronized(querySupportLock) { + + freeScheduling.add(request); + + //System.err.println("schedule free task " + request + " => " + freeScheduling.size()); + + for(int i=0;i(); - } +// for (int i = 0; i < THREADS * THREADS; i++) { +// delayQueues[i] = new ArrayList(); +// } for (int i = 0; i < THREADS; i++) { // tasks[i] = new ArrayList(); - ownTasks[i] = new ArrayList(); - ownSyncTasks[i] = new ArrayList(); - queues[i] = new ArrayList(); +// ownTasks[i] = new ArrayList(); +// ownSyncTasks[i] = new ArrayList(); +// queues[i] = new ArrayList(); threadLocks[i] = new ReentrantLock(); threadConditions[i] = threadLocks[i].newCondition(); // limits[i] = false; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java index a5e79244e..07a390a51 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryThread.java @@ -21,30 +21,32 @@ class QueryThread extends Thread implements SessionThread { private Session session; private QuerySupport querySupport; + final private QueryProcessor processor; final private ArrayList tasks = new ArrayList(); - final private ArrayList own; - final private ArrayList ownSync; - final private ArrayList queue; +// final private ArrayList own; +// final private ArrayList ownSync; +// final private ArrayList queue; final private ReentrantLock lock; final private Condition condition; final private Object querySupportLock; final private int THREADS; final private AtomicInteger sleepers; final private ThreadState[] threadStates; - final private ArrayList[] delayQueues; +// final private ArrayList[] delayQueues; final private QueryThread[] executors; final private ReentrantLock[] threadLocks; - final private ArrayList[] queues; - final private ArrayList[] ownSyncTasks; +// final private ArrayList[] queues; +// final private ArrayList[] ownSyncTasks; public QueryThread(Session session, QueryProcessor processor, int index, String name) { super(QueryProcessor.QueryThreadGroup, null, name); this.session = session; + this.processor = processor; this.index = index; - own = processor.ownTasks[index]; - ownSync = processor.ownSyncTasks[index]; - queue = processor.queues[index]; +// own = processor.ownTasks[index]; +// ownSync = processor.ownSyncTasks[index]; +// queue = processor.queues[index]; lock = processor.threadLocks[index]; condition = processor.threadConditions[index]; querySupportLock = processor.querySupportLock; @@ -52,11 +54,11 @@ class QueryThread extends Thread implements SessionThread { sleepers = processor.sleepers; querySupport = processor.querySupport; threadStates = processor.threadStates; - delayQueues = processor.delayQueues; +// delayQueues = processor.delayQueues; executors = processor.executors; threadLocks = processor.threadLocks; - queues = processor.queues; - ownSyncTasks = processor.ownSyncTasks; +// queues = processor.queues; +// ownSyncTasks = processor.ownSyncTasks; } synchronized void dispose() { @@ -101,37 +103,47 @@ class QueryThread extends Thread implements SessionThread { while(true) { // Perform own tasks first - if(tasks.addAll(own)) { - own.clear(); - } else if (doWait && !ownSync.isEmpty()) { - tasks.add(ownSync.remove(ownSync.size()-1)); - } +// if(tasks.addAll(own)) { +// own.clear(); +// } else if (doWait && !ownSync.isEmpty()) { +// tasks.add(ownSync.remove(ownSync.size()-1)); +// } // Try some queued tasks - lock.lock(); - if(tasks.addAll(queue)) { - queue.clear(); - lock.unlock(); - return tasks; - } else { - lock.unlock(); - } +// lock.lock(); +// if(tasks.addAll(queue)) { +// queue.clear(); +// lock.unlock(); +// return tasks; +// } else { +// lock.unlock(); +// } // Return tasks if some were found if(!tasks.isEmpty()) return tasks; + if(!doWait) return null; synchronized (querySupportLock) { - lock.lock(); +// System.err.println("check free tasks for QT " + index + " (" + processor.freeScheduling + ")"); - // Just maybe someone inserted tasks and notified just before synchronized block - if(tasks.addAll(queue)) { - queue.clear(); - lock.unlock(); + if(!processor.freeScheduling.isEmpty()) { + tasks.add(processor.freeScheduling.removeFirst()); return tasks; } + lock.lock(); + + // Just maybe someone inserted tasks and notified just before synchronized block +// if(tasks.addAll(queue)) { +// queue.clear(); +// lock.unlock(); +// return tasks; +// } + +// System.err.println("QT " + index + ", sleepers = " + sleepers); + // We are the last one awake if(sleepers.incrementAndGet() == THREADS) { @@ -141,9 +153,9 @@ class QueryThread extends Thread implements SessionThread { if(querySupport == null) System.err.println("null qs"); querySupport.ceased(index); - if(tasks.addAll(own)) { - own.clear(); - } +// if(tasks.addAll(own)) { +// own.clear(); +// } // System.err.println("tasks after ceased: " + tasks.size()); if(!tasks.isEmpty()) { lock.unlock(); @@ -170,6 +182,8 @@ class QueryThread extends Thread implements SessionThread { threadStates[index] = ThreadState.SLEEP; condition.await(); + sleepers.decrementAndGet(); + // We are done if(isDisposed()) { threadStates[index] = ThreadState.DISPOSED; @@ -197,17 +211,17 @@ class QueryThread extends Thread implements SessionThread { boolean didExecute = false; - for(int performer=0;performer finished = newTasks(false, tasks); @@ -218,12 +232,13 @@ class QueryThread extends Thread implements SessionThread { SessionTask task = tasks.remove(tasks.size() - 1); - if(task.syncCaller == index) { - ownSyncTasks[index].add(task); - } else { +// if(task.syncCaller == index) { +// ownSyncTasks[index].add(task); +// } else { task.run(index); +// System.err.println("QT(s) " + index + " runs " + task); didExecute = true; - } +// } } @@ -248,21 +263,22 @@ class QueryThread extends Thread implements SessionThread { while(!tasks.isEmpty()) { SessionTask task = tasks.remove(tasks.size()-1); +// System.err.println("QT " + index + " runs " + task); task.run(index); } - for(int performer=0;performer extends CacheEntryBase> { } final public Object addOrSet(AsyncReadGraph graph, Object result) { + +// System.err.println("addOrSet " + request + " " + Thread.currentThread() + " " + result); assert(assertPending()); @@ -100,7 +102,7 @@ final public class ReadEntry extends CacheEntryBase> { } - @Override + //@Override public Object compute(ReadGraphImpl graph, AsyncProcedure procedure) throws DatabaseException { ReadGraphImpl queryGraph = graph.withParent(this); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java index d55768aaa..204a0005a 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java @@ -41,6 +41,7 @@ final public class RelationInfoQuery extends UnaryQuery procedure) throws DatabaseException { computeForEach(graph, id, this, procedure); return getResult(); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java index e1a106aaa..ad4700aa8 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java @@ -135,6 +135,10 @@ final public class Statements extends CollectionBinaryQuery final static private void forSingleAssertion(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final TripleIntProcedure procedure) throws DatabaseException { + if(entry != null) { + assert(entry.isPending()); + } + IntArray map = getAssertionMap(graph, r1, r2, entry); if(map == null) { if(entry != null) entry.finish(graph, procedure); @@ -647,15 +651,13 @@ final public class Statements extends CollectionBinaryQuery } } - - @Override - public Object compute(ReadGraphImpl graph, final TripleIntProcedure procedure) throws DatabaseException { - computeForEach(graph, r1(), r2(), this, procedure); - return getResult(); - } public static void computeForEach(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final TripleIntProcedure procedure) throws DatabaseException { + if(entry != null) { + assert(entry.isPending()); + } + QueryCache.runnerRelationInfoQuery(graph, r2, entry, null, new InternalProcedure() { @Override @@ -690,6 +692,7 @@ final public class Statements extends CollectionBinaryQuery synchronized(this) { setReady(); + //new Exception(toString() + " is READY").printStackTrace(); } IntArray v = (IntArray)getResult(); @@ -761,7 +764,7 @@ final public class Statements extends CollectionBinaryQuery @Override public void recompute(ReadGraphImpl graph) throws DatabaseException { - compute(graph, new TripleIntProcedureAdapter() { + computeForEach(graph, r1(), r2(), this, new TripleIntProcedureAdapter() { @Override public void finished(ReadGraphImpl graph) { diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java index 0f076fb34..b8d29b7e6 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperRelations.java @@ -69,7 +69,7 @@ final public class SuperRelations extends UnaryQuery> } - @Override + //@Override public Object compute(final ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { QueryProcessor processor = graph.processor; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java index 06fabb2d7..a01c84699 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/SuperTypes.java @@ -33,7 +33,7 @@ final public class SuperTypes extends UnaryQuery> { provider.cache.remove(this); } - @Override + //@Override public Object compute(ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { return computeForEach(graph, id, this, procedure); } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java index 9da459469..ad4581bb6 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java @@ -33,7 +33,7 @@ final public class TypeHierarchy extends UnaryQuery> { provider.cache.remove(this); } - @Override + //@Override public IntSet compute(ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { QueryProcessor processor = graph.processor; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java index 155bc209b..512045e17 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java @@ -30,7 +30,7 @@ final public class Types extends UnaryQuery> { provider.cache.remove(this); } - @Override + //@Override public Object compute(final ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { computeForEach(graph, id, this, procedure); return getResult(); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java index b29d518df..794bcc8ed 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/URIToResource.java @@ -30,7 +30,7 @@ public class URIToResource extends StringQuery> { provider.cache.remove(this); } - @Override + //@Override public Object compute(ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { computeForEach(graph, id, this, procedure); return getResult(); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryHash.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryHash.java index fd1035a78..11c2fe6fa 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryHash.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/UnaryQueryHash.java @@ -50,11 +50,6 @@ abstract public class UnaryQueryHash extends THash { throw new Error("Not possible."); } - @Override - public Object compute(ReadGraphImpl graph, Procedure procedure) throws DatabaseException { - throw new Error("Not possible."); - } - @Override Object performFromCache(ReadGraphImpl graph, Procedure procedure) throws DatabaseException { throw new Error("Not possible."); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java index 1521d3193..b96e13d42 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java @@ -43,18 +43,9 @@ final public class ValueQuery extends UnaryQuery> { } - public static byte[] computeForEach(ReadGraphImpl graph, final int r) { - - graph.ensureLoaded(r); - - return graph.getValue(r); - - } - - @Override - public Object compute(ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { - return computeForEach(graph, id, this, procedure); - } +// public Object compute(ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { +// return computeForEach(graph, id, this, procedure); +// } @Override public String toString() { @@ -63,13 +54,13 @@ final public class ValueQuery extends UnaryQuery> { @Override public Object performFromCache(ReadGraphImpl graph, InternalProcedure procedure) throws DatabaseException { - return compute(graph, procedure); + return computeForEach(graph, id, this, procedure); } @Override public void recompute(ReadGraphImpl graph) throws DatabaseException { - compute(graph, new InternalProcedure() { + computeForEach(graph, id, this, new InternalProcedure() { @Override public void execute(ReadGraphImpl graph, byte[] result) { diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest2.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest2.java index 4bbd48002..9faf02cc8 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest2.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest2.java @@ -111,9 +111,11 @@ public class RuntimeEnvironmentRequest2 extends BinaryRead sclModules = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, L0.SCLModule)); - for (Resource sclModule : sclModules) - environmentSpecification.importModule(graph.getURI(sclModule), ""); + if(parameter != null) { + Collection sclModules = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, L0.SCLModule)); + for (Resource sclModule : sclModules) + environmentSpecification.importModule(graph.getURI(sclModule), ""); + } Resource mainModule = Layer0Utils.getPossibleChild(graph, parameter2, "SCLMain"); if(mainModule != null) diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NodeValueRequest.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NodeValueRequest.java index 2bd089d1e..103c3183b 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NodeValueRequest.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NodeValueRequest.java @@ -57,7 +57,7 @@ class NodeValueRequest extends ParametrizedPrimitiveRead procedure) { VariableNode node = parameter.first; - + if(procedure.isDisposed()) { // We are not listening @@ -201,7 +201,11 @@ class NodeValueRequest extends ParametrizedPrimitiveRead T getClusterByResourceKey(final int resourceKey) { + public synchronized final T getClusterByResourceKey(final int resourceKey) { int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey); if (ClusterTraitsBase.isVirtualClusterKey(clusterKey)) throw new RuntimeException("Tried to get a persistent cluster for a virtual resource."); diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java index 242fcfe3d..cf50a09b5 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java @@ -50,6 +50,7 @@ import org.simantics.db.authentication.UserAuthenticationAgent; import org.simantics.db.authentication.UserAuthenticator; import org.simantics.db.common.Indexing; import org.simantics.db.common.TransactionPolicyRelease; +import org.simantics.db.common.procedure.BlockingAsyncProcedure; import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter; import org.simantics.db.common.procedure.adapter.ProcedureAdapter; import org.simantics.db.common.procedure.wrapper.NoneToAsyncListener; @@ -1498,9 +1499,9 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule assert (request != null); assert (procedure != null); - int thread = request.hashCode() & queryProvider2.THREAD_MASK; + //int thread = request.hashCode() & queryProvider2.THREAD_MASK; - requestManager.scheduleRead(new SessionRead(request, throwable, notify, thread, thread) { + requestManager.scheduleRead(new SessionRead(request, throwable, notify, queryProvider2.THREAD_MASK + 1, -1) { @Override public void run(int thread) { @@ -1537,7 +1538,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule }; - QueryCache.runnerReadEntry(newGraph, request, null, listener, ap); + QueryCache.runnerReadEntry(newGraph, request, null, listener, ap, true); } catch (Throwable t) { // This is handled by the AsyncProcedure @@ -1632,7 +1633,8 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule if (listener != null) { try { - QueryCache.runnerAsyncReadEntry(newGraph, request, null, listener, procedure); + QueryCacheBase.resultAsyncReadEntry(newGraph, request, null, listener, procedure); + //QueryCache.runnerAsyncReadEntry(newGraph, request, null, listener, procedure, true); //newGraph.processor.query(newGraph, request, null, procedure, listener); } catch (DatabaseException e) { Logger.defaultLogError(e); @@ -1640,20 +1642,21 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule } else { - final ResultCallWrappedSingleQueryProcedure4 wrapper = new ResultCallWrappedSingleQueryProcedure4( - procedure, "request"); - - try { +// final ResultCallWrappedSingleQueryProcedure4 wrapper = new ResultCallWrappedSingleQueryProcedure4( +// procedure, "request"); -// newGraph.state.barrier.inc(); + BlockingAsyncProcedure wrap = new BlockingAsyncProcedure(procedure, request); - request.perform(newGraph, wrapper); + try { -// newGraph.waitAsync(request); + request.perform(newGraph, wrap); + wrap.get(); } catch (Throwable t) { - wrapper.exception(newGraph, t); + wrap.exception(newGraph, t); + +// wrapper.exception(newGraph, t); // newGraph.waitAsync(request); @@ -3523,7 +3526,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule public int getAmountOfQueryThreads() { // This must be a power of two - return 4; + return 16; // return Integer.highestOneBit(Runtime.getRuntime().availableProcessors()); } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java index 5bdec52e9..06cd5ae9d 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionRequestManager.java @@ -224,6 +224,9 @@ public class SessionRequestManager { if(!session.state.isAlive()) return; WriteState writeState = session.writeState; + + assert(writeState != null); + WriteGraphImpl graph = writeState.getGraph(); if(writeState.isExcepted()) { @@ -318,7 +321,9 @@ public class SessionRequestManager { } else { - throw new IllegalStateException("State in ceased should be WRITE or READ or INIT (was " + state + ")"); + // Spurious wakeup + + //throw new IllegalStateException("State in ceased should be WRITE or READ or INIT (was " + state + ")"); } @@ -371,6 +376,8 @@ public class SessionRequestManager { boolean inUpdate = state == State.WRITE_UPDATE; + //System.err.println("schedule write " + task); + assert(State.INIT != state); //task.combine = combine != null ? combine : inUpdate; if(State.IDLE == state) { diff --git a/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java b/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java index 47a14ddbc..7cc87e30b 100644 --- a/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java +++ b/bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdaptionService2.java @@ -20,6 +20,7 @@ import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.adaption.Adapter; import org.simantics.db.adaption.AdaptionService; +import org.simantics.db.common.procedure.BlockingAsyncProcedure; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.common.procedure.single.SyncReadProcedure; import org.simantics.db.common.request.BinaryRead; @@ -583,11 +584,15 @@ public class AdaptionService2 implements AdaptionService { public T adapt(ReadGraph g, Resource r, C context, Class contextClass, Class targetClass, boolean possible) throws DatabaseException { Adapter adapter = getAdapter(g, r, context, contextClass, targetClass, possible); + if(adapter == null) return null; - SyncReadProcedure procedure = new SyncReadProcedure(); - adapter.adapt(g, r, context, procedure); - procedure.checkAndThrow(); - return procedure.result; + BlockingAsyncProcedure ap = new BlockingAsyncProcedure(null, adapter); + +// SyncReadProcedure procedure = new SyncReadProcedure(); + adapter.adapt(g, r, context, ap); + return ap.get(); +// procedure.checkAndThrow(); +// return procedure.result; } diff --git a/bundles/org.simantics.desktop.product/plugin.xml b/bundles/org.simantics.desktop.product/plugin.xml index c80090f5f..a4495a4b3 100644 --- a/bundles/org.simantics.desktop.product/plugin.xml +++ b/bundles/org.simantics.desktop.product/plugin.xml @@ -7,10 +7,10 @@ + name="TestingStation Server"> + value="TestingStation Server"/> diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java index 56063b990..fe7479e5d 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java @@ -17,13 +17,17 @@ import gnu.trove.procedure.TIntProcedure; import gnu.trove.set.hash.THashSet; import java.util.ArrayList; +import java.util.Collection; import java.util.Set; +import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; +import org.simantics.db.common.primitiverequest.OrderedSet; import org.simantics.db.common.procedure.adapter.ProcedureAdapter; +import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.AsyncMultiProcedure; import org.simantics.db.procedure.AsyncProcedure; @@ -71,124 +75,149 @@ public class DiagramContentRequest extends BaseRequest() { - - @Override - public void execute(AsyncReadGraph graph, final Resource component) { - - // Must add the elements to the result set here in order to - // keep their order the same as in the ordered set. - final int elementIndex = index.getAndIncrement(); - result.elements.add(component); - - graph.forTypes(component, new AsyncProcedure>() { - - @Override - public void exception(AsyncReadGraph graph, Throwable t) { - if (errorHandler != null) - errorHandler.error(t.getMessage(), t); - } - - @Override - public void execute(AsyncReadGraph graph, Set types) { - if (types.contains(DIA.Connection)) { - if (types.contains(DIA.RouteGraphConnection)) { - graph.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component), - new ProcedureAdapter() { - @Override - public void execute(RouteGraphConnectionPartData partData) { - synchronized (result) { - for (EdgeResource link : partData.links) { - result.routeLinks.add(link); - result.partToConnection.put(link, component); - result.connectionToParts.add(component, link); - } - for (Resource line : partData.routeLines) { - result.routeLines.add(line); - result.connectionToParts.add(component, line); - result.partToConnection.put(line, component); - } - for (Resource point : partData.routePoints) { - result.routePoints.add(point); - result.connectionToParts.add(component, point); - result.partToConnection.put(point, component); - } - } - } - }); - - synchronized (result.routeGraphConnectionSet) { - result.routeGraphConnectionSet.add(component); - } - } else { - graph.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component), - new ProcedureAdapter() { - @Override - public void execute(ConnectionPartData partData) { - synchronized (result) { - for (EdgeResource er : partData.edges) { - result.connectionSegments.add(er); - result.partToConnection.put(er, component); - result.connectionToParts.add(component, er); - } - for (Resource bp : partData.branchPoints) { - result.branchPoints.add(bp); - result.connectionToParts.add(component, bp); - result.partToConnection.put(bp, component); - } - } - } - }); - - synchronized (result.connectionSet) { - result.connectionSet.add(component); - } - } - } - else if (types.contains(DIA.Element)) { - synchronized (result.nodeSet) { - result.nodeSet.add(component); - } - } - else { - synchronized (unrecognizedElementIndices) { - // Unrecognized element, mark it to be - // removed after everything is processed. - unrecognizedElementIndices.add(elementIndex); - } - } - } - - }); - - } - + + Collection components = OrderedSetUtils.toList(g, data); + + Semaphore s = new Semaphore(0); + + for(Resource component : components) { + + // Must add the elements to the result set here in order to + // keep their order the same as in the ordered set. + final int elementIndex = index.getAndIncrement(); + result.elements.add(component); + + Set types = g.getTypes(component); + + if (types.contains(DIA.Connection)) { + if (types.contains(DIA.RouteGraphConnection)) { + g.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component), + new ProcedureAdapter() { + @Override + public void execute(RouteGraphConnectionPartData partData) { + synchronized (result) { + for (EdgeResource link : partData.links) { + result.routeLinks.add(link); + result.partToConnection.put(link, component); + result.connectionToParts.add(component, link); + } + for (Resource line : partData.routeLines) { + result.routeLines.add(line); + result.connectionToParts.add(component, line); + result.partToConnection.put(line, component); + } + for (Resource point : partData.routePoints) { + result.routePoints.add(point); + result.connectionToParts.add(component, point); + result.partToConnection.put(point, component); + } + } + s.release(); + } + }); + + synchronized (result.routeGraphConnectionSet) { + result.routeGraphConnectionSet.add(component); + } + } else { + g.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component), + new ProcedureAdapter() { + @Override + public void execute(ConnectionPartData partData) { + synchronized (result) { + for (EdgeResource er : partData.edges) { + result.connectionSegments.add(er); + result.partToConnection.put(er, component); + result.connectionToParts.add(component, er); + } + for (Resource bp : partData.branchPoints) { + result.branchPoints.add(bp); + result.connectionToParts.add(component, bp); + result.partToConnection.put(bp, component); + } + } + s.release(); + } + }); + + synchronized (result.connectionSet) { + result.connectionSet.add(component); + } + } + } + else if (types.contains(DIA.Element)) { + synchronized (result.nodeSet) { + result.nodeSet.add(component); + } + s.release(); + + } + else { + synchronized (unrecognizedElementIndices) { + // Unrecognized element, mark it to be + // removed after everything is processed. + unrecognizedElementIndices.add(elementIndex); + } + s.release(); + } + + } + + try { + s.acquire(components.size()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + // Remove elements that were not recognized in descending order. + unrecognizedElementIndices.sort(); + unrecognizedElementIndices.forEachDescending(new TIntProcedure() { @Override - public void finished(AsyncReadGraph graph) { - // Remove elements that were not recognized in descending order. - unrecognizedElementIndices.sort(); - unrecognizedElementIndices.forEachDescending(new TIntProcedure() { - @Override - public boolean execute(int index) { - result.elements.remove(index); - return true; - } - }); - - // Help successive request executions by remembering the previous - // element count. This will relieve some ArrayList reallocation - // strain down the road. - previousElementCount = result.elements.size(); - } - - @Override - public void exception(AsyncReadGraph graph, Throwable t) { - if (errorHandler != null) - errorHandler.error(t.getMessage(), t); + public boolean execute(int index) { + result.elements.remove(index); + return true; } }); + // Help successive request executions by remembering the previous + // element count. This will relieve some ArrayList reallocation + // strain down the road. + previousElementCount = result.elements.size(); + + +// g.forOrderedSet(data, new AsyncMultiProcedure() { +// +// @Override +// public void execute(AsyncReadGraph graph, final Resource component) { +// +// graph.forTypes(component, new AsyncProcedure>() { +// +// @Override +// public void exception(AsyncReadGraph graph, Throwable t) { +// if (errorHandler != null) +// errorHandler.error(t.getMessage(), t); +// } +// +// @Override +// public void execute(AsyncReadGraph graph, Set types) { +// +// } +// +// }); +// +// } +// +// @Override +// public void finished(AsyncReadGraph graph) { +// } +// +// @Override +// public void exception(AsyncReadGraph graph, Throwable t) { +// if (errorHandler != null) +// errorHandler.error(t.getMessage(), t); +// } +// }); + return result; } } \ No newline at end of file diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java index dd6c9b7d1..3e404cf56 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java @@ -1302,6 +1302,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID // ITask task5 = ThreadLogger.getInstance().begin("DiagramContentRequest2"); ITask task42 = ThreadLogger.getInstance().begin("DiagramContentRequest2"); DiagramContents contents = g.syncRequest(query); + System.err.println("contents: " + contents); task42.finish(); // task5.finish(); monitor.worked(10); @@ -1623,7 +1624,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID this.removedRouteGraphConnections.clear(); } - void processNodes(AsyncReadGraph graph) { + void processNodes(ReadGraph graph) throws DatabaseException { for (Map.Entry entry : changes.elements.entrySet()) { @@ -1635,7 +1636,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID IElement mappedElement = getMappedElement(element); if (mappedElement == null) { if (DebugPolicy.DEBUG_NODE_LOAD) - graph.asyncRequest(new ReadRequest() { + graph.syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { System.out.println(" EXTERNALLY ADDED ELEMENT: " @@ -1699,7 +1700,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID } }; - graph.asyncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure() { + graph.syncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, final IElement e) { if (e == null) @@ -1792,7 +1793,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID }; //System.out.println("NODE REQUEST: " + element); - graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure() { + graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, IElement e) { if (e == null) @@ -1826,7 +1827,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID case REMOVED: { IElement e = getMappedElement(element); if (DebugPolicy.DEBUG_NODE_LOAD) - graph.asyncRequest(new ReadRequest() { + graph.syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { System.out.println(" EXTERNALLY REMOVED ELEMENT: " @@ -1932,7 +1933,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID } } - void processRouteGraphConnections(AsyncReadGraph graph) { + void processRouteGraphConnections(ReadGraph graph) throws DatabaseException { for (Map.Entry entry : changes.routeGraphConnections.entrySet()) { final Resource connection = entry.getKey(); @@ -2010,7 +2011,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID } }; - graph.asyncRequest(new ConnectionRequest(canvas, diagram, connection, errorHandler, loadListener), new Procedure() { + graph.syncRequest(new ConnectionRequest(canvas, diagram, connection, errorHandler, loadListener), new Procedure() { @Override public void execute(final IElement e) { if (e == null) @@ -2052,7 +2053,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID return assertMappedConnection(connection); } - void processBranchPoints(AsyncReadGraph graph) { + void processBranchPoints(ReadGraph graph) throws DatabaseException { for (Map.Entry entry : changes.branchPoints.entrySet()) { final Resource element = entry.getKey(); @@ -2063,7 +2064,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID IElement mappedElement = getMappedElement(element); if (mappedElement == null) { if (DebugPolicy.DEBUG_NODE_LOAD) - graph.asyncRequest(new ReadRequest() { + graph.syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { System.out.println(" EXTERNALLY ADDED BRANCH POINT: " @@ -2115,7 +2116,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID } }; - graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure() { + graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, IElement e) { if (e != null) { @@ -2141,7 +2142,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID case REMOVED: { IElement e = getMappedElement(element); if (DebugPolicy.DEBUG_NODE_LOAD) - graph.asyncRequest(new ReadRequest() { + graph.syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { System.out.println(" EXTERNALLY REMOVED BRANCH POINT: " @@ -2158,7 +2159,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID } } - void processConnectionSegments(AsyncReadGraph graph) { + void processConnectionSegments(ReadGraph graph) throws DatabaseException { ConnectionSegmentAdapter adapter = connectionSegmentAdapter; for (Map.Entry entry : changes.connectionSegments.entrySet()) { @@ -2170,7 +2171,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID IElement mappedElement = getMappedElement(seg); if (mappedElement == null) { if (DebugPolicy.DEBUG_EDGE_LOAD) - graph.asyncRequest(new ReadRequest() { + graph.syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { System.out.println(" EXTERNALLY ADDED CONNECTION SEGMENT: " + seg.toString() @@ -2178,7 +2179,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID } }); - graph.asyncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure() { + graph.syncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, IElement e) { if (DebugPolicy.DEBUG_EDGE_LOAD) @@ -2206,7 +2207,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID case REMOVED: { final IElement e = getMappedElement(seg); if (DebugPolicy.DEBUG_EDGE_LOAD) - graph.asyncRequest(new ReadRequest() { + graph.syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { System.out.println(" EXTERNALLY REMOVED CONNECTION SEGMENT: " + seg.toString() + " - " @@ -2260,9 +2261,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID Object task = Timing.BEGIN("processNodesConnections"); //System.out.println("---- PROCESS NODES & CONNECTIONS BEGIN"); if (!changes.elements.isEmpty()) { - graph.syncRequest(new AsyncReadRequest() { + graph.syncRequest(new ReadRequest() { @Override - public void run(AsyncReadGraph graph) { + public void run(ReadGraph graph) throws DatabaseException { processNodes(graph); } @Override @@ -2277,9 +2278,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID //System.out.println("---- PROCESS BRANCH POINTS BEGIN"); if (!changes.branchPoints.isEmpty()) { - graph.syncRequest(new AsyncReadRequest() { + graph.syncRequest(new ReadRequest() { @Override - public void run(AsyncReadGraph graph) { + public void run(ReadGraph graph) throws DatabaseException { processBranchPoints(graph); } @Override @@ -2295,9 +2296,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID //System.out.println("---- PROCESS CONNECTION SEGMENTS BEGIN"); if (!changes.connectionSegments.isEmpty()) { - graph.syncRequest(new AsyncReadRequest() { + graph.syncRequest(new ReadRequest() { @Override - public void run(AsyncReadGraph graph) { + public void run(ReadGraph graph) throws DatabaseException { processConnectionSegments(graph); } @Override @@ -2312,9 +2313,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID task = Timing.BEGIN("processRouteGraphConnections"); if (!changes.routeGraphConnections.isEmpty()) { - graph.syncRequest(new AsyncReadRequest() { + graph.syncRequest(new ReadRequest() { @Override - public void run(AsyncReadGraph graph) { + public void run(ReadGraph graph) throws DatabaseException { processRouteGraphConnections(graph); } @Override diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/internal/DebugPolicy.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/internal/DebugPolicy.java index 1ca5121ea..5e6eddc71 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/internal/DebugPolicy.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/internal/DebugPolicy.java @@ -20,39 +20,39 @@ import org.simantics.diagram.synchronization.IModifiableSynchronizationContext; */ public final class DebugPolicy { - public static boolean DEBUG = false; + public static boolean DEBUG = true; public static boolean DEBUG_GRAPH_WRITEBACK = false; public static boolean DEBUG_GRAPH_WRITEBACK_MODIFICATION = false; public static boolean DEBUG_TERMINAL_SEARCH = false; - public static boolean DEBUG_LOAD = false; - public static boolean DEBUG_NODE_LOAD = false; - public static boolean DEBUG_CONNECTION_LOAD = false; - public static boolean DEBUG_EDGE_LOAD = false; - public static boolean DEBUG_CONNECTION_VISUALS_LOAD = false; - public static boolean DEBUG_TRANSFORM_LOAD = false; + public static boolean DEBUG_LOAD = true; + public static boolean DEBUG_NODE_LOAD = true; + public static boolean DEBUG_CONNECTION_LOAD = true; + public static boolean DEBUG_EDGE_LOAD = true; + public static boolean DEBUG_CONNECTION_VISUALS_LOAD = true; + public static boolean DEBUG_TRANSFORM_LOAD = true; public static double DETERMINANT_LIMIT_HIGH = 1e24; public static double DETERMINANT_LIMIT_LOW = 1e-24; public static double TRANSLATION_LIMIT_HIGH = 1e32; - public static boolean DEBUG_EDGE_LISTENER = false; - - public static boolean DEBUG_GENERAL_ELEMENT_UPDATE = false; - public static boolean DEBUG_GENERAL_ELEMENT_UPDATE_DETAIL = false; - public static boolean DEBUG_GRAPH_UPDATE = false; - public static boolean DEBUG_DIAGRAM_UPDATE = false; - public static boolean DEBUG_DIAGRAM_UPDATE_DETAIL = false; - public static boolean DEBUG_NODE_UPDATE = false; - public static boolean DEBUG_CONNECTION_UPDATE = false; - public static boolean DEBUG_EDGE_UPDATE = false; - - public static boolean DEBUG_LISTENER_BASE = false; - public static boolean DEBUG_DIAGRAM_LISTENER = false; - public static boolean DEBUG_NODE_LISTENER = false; - public static boolean DEBUG_CONNECTION_LISTENER = false; + public static boolean DEBUG_EDGE_LISTENER = true; + + public static boolean DEBUG_GENERAL_ELEMENT_UPDATE = true; + public static boolean DEBUG_GENERAL_ELEMENT_UPDATE_DETAIL = true; + public static boolean DEBUG_GRAPH_UPDATE = true; + public static boolean DEBUG_DIAGRAM_UPDATE = true; + public static boolean DEBUG_DIAGRAM_UPDATE_DETAIL = true; + public static boolean DEBUG_NODE_UPDATE = true; + public static boolean DEBUG_CONNECTION_UPDATE = true; + public static boolean DEBUG_EDGE_UPDATE = true; + + public static boolean DEBUG_LISTENER_BASE = true; + public static boolean DEBUG_DIAGRAM_LISTENER = true; + public static boolean DEBUG_NODE_LISTENER = true; + public static boolean DEBUG_CONNECTION_LISTENER = true; /** * Enables tracing of diff --git a/bundles/org.simantics.document.server/META-INF/MANIFEST.MF b/bundles/org.simantics.document.server/META-INF/MANIFEST.MF index 016ed9189..cf196e8c8 100644 --- a/bundles/org.simantics.document.server/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.document.server/META-INF/MANIFEST.MF @@ -23,7 +23,8 @@ Require-Bundle: org.simantics.modeling;bundle-version="1.1.1", org.simantics.document.server.io;visibility:=reexport, org.simantics.scl.db;bundle-version="0.1.3", - org.slf4j.api + org.slf4j.api, + org.simantics.threadlog Bundle-ActivationPolicy: lazy Bundle-Activator: org.simantics.document.server.Activator Export-Package: org.simantics.document.server, diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/DocumentRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/DocumentRequest.java index 9a53060be..87b244c88 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/DocumentRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/DocumentRequest.java @@ -6,17 +6,22 @@ import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; import org.simantics.db.ReadGraph; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.request.VariableRead; import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.procedure.Listener; import org.simantics.document.server.JSONObject; +import org.simantics.threadlog.Task; +import org.simantics.threadlog.ThreadLog; public class DocumentRequest extends VariableRead> { - public static boolean PROFILE = false; + public static boolean PROFILE = true; // Thresholds in microseconds public static int PROFILE_THRESHOLD_NODEREQUEST = 2000; public static int PROFILE_THRESHOLD_VALUEREQUEST = 500; @@ -25,48 +30,119 @@ public class DocumentRequest extends VariableRead> { super(var); } + static class NodeRequestE extends NodeRequest { + + static int count1 = 0; + static int count = 0; + + public NodeRequestE(Variable node) { + super(node); + count1++; + System.err.println("create NodeRequest count = " + count1); + if(count1 == 600) + System.err.println("asd"); + } + + @Override + public JSONObject perform(ReadGraph graph) throws DatabaseException { + count++; + System.err.println("perform NodeRequest count = " + count); + + return super.perform(graph); + } + + } + @Override public List perform(ReadGraph graph) throws DatabaseException { + + Task task = ThreadLog.BEGIN("DocumentRequest " + variable.getURI(graph)); - long s = System.nanoTime(); + try { - Set nodes = graph.syncRequest(new NodesRequest(variable), TransientCacheAsyncListener.>instance()); - HashSet rs = new HashSet(); // result - if(nodes.isEmpty()) { - return Collections.emptyList(); - } - - - /*TreeMap nodeMap = new TreeMap(); - - for (Variable node : nodes) { - nodeMap.put(node.getURI(graph), node); - } - System.out.println("*************************************************************************"); - for (Variable node : nodeMap.values()) { - System.out.println(" " + node.getURI(graph)); - }*/ - - for(Variable node : nodes) { - rs.add(graph.syncRequest(new NodeRequest(node), TransientCacheAsyncListener.instance())); - } + long s = System.nanoTime(); + + Set nodes = graph.syncRequest(new NodesRequest(variable), TransientCacheAsyncListener.>instance()); + HashSet rs = new HashSet(); // result + if(nodes.isEmpty()) { + return Collections.emptyList(); + } + + + /*TreeMap nodeMap = new TreeMap(); + + for (Variable node : nodes) { + nodeMap.put(node.getURI(graph), node); + } + System.out.println("*************************************************************************"); + for (Variable node : nodeMap.values()) { + System.out.println(" " + node.getURI(graph)); + }*/ + + Semaphore done = new Semaphore(0); + + for(Variable node : nodes) { + + graph.asyncRequest(new NodeRequestE(node), new Listener() { - ArrayList result = new ArrayList(rs); - Collections.sort(result, new Comparator() { + @Override + public void execute(JSONObject result) { + synchronized(rs) { + rs.add(result); + } + done.release(); + } - @Override - public int compare(JSONObject o1, JSONObject o2) { - return o1.id.compareTo(o2.id); + @Override + public void exception(Throwable t) { + t.printStackTrace(); + done.release(); + } + + @Override + public boolean isDisposed() { + return true; + } + + }); + +// rs.add(graph.syncRequest(new NodeRequest(node), TransientCacheAsyncListener.instance())); + + } + + try { + boolean success = done.tryAcquire(nodes.size(), 10, TimeUnit.MILLISECONDS); + while(!success) { + success = done.tryAcquire(nodes.size(), 10, TimeUnit.MILLISECONDS); + System.err.println("still trying to acquire semaphore, avail = " + done.availablePermits() ); + } + + } catch (InterruptedException e) { + e.printStackTrace(); } + + ArrayList result = new ArrayList(rs); + Collections.sort(result, new Comparator() { + + @Override + public int compare(JSONObject o1, JSONObject o2) { + return o1.id.compareTo(o2.id); + } + + }); + + if(PROFILE) { + long dura = System.nanoTime()-s; + System.err.println("DocumentRequest " + System.identityHashCode(this) + " in " + 1e-6*dura + "ms. " + variable.getURI(graph)); + } + + return result; + + } finally { - }); - - if(PROFILE) { - long dura = System.nanoTime()-s; - System.err.println("DocumentRequest " + System.identityHashCode(this) + " in " + 1e-6*dura + "ms. " + variable.getURI(graph)); - } + task.end(); - return result; + } } } \ No newline at end of file diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequest.java index 50c8827ef..c9dfe8934 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequest.java @@ -1,17 +1,13 @@ package org.simantics.document.server.request; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - import org.simantics.db.ReadGraph; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.request.VariableRead; import org.simantics.db.layer0.variable.Variable; import org.simantics.document.server.DocumentServerUtils.AttributesRequest; import org.simantics.document.server.JSONObject; -import org.simantics.utils.datastructures.Pair; +import org.simantics.threadlog.Task; +import org.simantics.threadlog.ThreadLog; public class NodeRequest extends VariableRead { @@ -28,16 +24,27 @@ public class NodeRequest extends VariableRead { long s = System.nanoTime(); - JSONObject staticContent = graph.syncRequest(new AttributesRequest(variable)); + Task task = ThreadLog.BEGIN("NodeRequest " + variable.getURI(graph)); + + try { - if(DocumentRequest.PROFILE) { - long dura = System.nanoTime()-s; - if(dura > DocumentRequest.PROFILE_THRESHOLD_NODEREQUEST * 1e3) { - System.err.println("NodeRequest " + System.identityHashCode(this) + " in " + 1e-6*dura + "ms. " + variable.getURI(graph)); - } - } + JSONObject staticContent = graph.syncRequest(new AttributesRequest(variable)); + + if(DocumentRequest.PROFILE) { + long dura = System.nanoTime()-s; + if(dura > DocumentRequest.PROFILE_THRESHOLD_NODEREQUEST * 1e3) { + System.err.println("NodeRequest " + System.identityHashCode(this) + " in " + 1e-6*dura + "ms. " + variable.getURI(graph)); + } + } - return staticContent; + + return staticContent; + + } finally { + + task.end(); + + } } diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodesRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodesRequest.java index f3f1177fc..c44febbe4 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodesRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodesRequest.java @@ -15,6 +15,8 @@ import org.simantics.structural.stubs.StructuralResource2; public class NodesRequest extends VariableRead> { + public static boolean PROFILE = false; + public NodesRequest(Variable var) { super(var); } @@ -35,7 +37,7 @@ public class NodesRequest extends VariableRead> { nodes.addAll(childNodes); } - if(DocumentRequest.PROFILE) { + if(PROFILE) { long dura = System.nanoTime()-s; System.err.println("NodesRequest " + System.identityHashCode(this) + " in " + 1e-6*dura + "ms. " + variable.getURI(graph)); } diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodesRequest2.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodesRequest2.java index 0f57a01c0..b3dc73cc9 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodesRequest2.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodesRequest2.java @@ -24,6 +24,8 @@ public class NodesRequest2 extends VariableRead> { DocumentationResource DOC = DocumentationResource.getInstance(graph); + System.err.println("NodesRequest " + variable.getURI(graph)); + Resource type = variable.getPossibleType(graph); if(type == null) return Collections.emptySet(); diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java index 9655e0f86..b2dc03b73 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java @@ -1,5 +1,6 @@ package org.simantics.document.server.request; +import java.util.Collections; import java.util.Map; import org.simantics.databoard.Bindings; @@ -104,10 +105,16 @@ public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest< return Pair.make(type, root); } else { Resource doc = graph.syncRequest(new PossibleTypedParent(component, DocumentationResource.getInstance(graph).Document)); - Resource componentType = graph.getSingleType(doc); - Resource root = graph.syncRequest(new IndexRoot(doc)); - // System.err.println("getComponentTypeAndRoot4 " + graph.getPossibleURI(component) + " => " + graph.getPossibleURI(componentType) + " " + graph.getPossibleURI(root)); - return Pair.make(componentType, root); + if(doc != null) { + Resource componentType = graph.getSingleType(doc); + Resource root = graph.syncRequest(new IndexRoot(doc)); + return Pair.make(componentType, root); + } else { + System.err.println("component = " + component); + Resource root = graph.syncRequest(new IndexRoot(component)); +// Resource componentType = graph.getSingleType(doc); + return Pair.make(null, root); + } } } throw new IllegalStateException(); @@ -161,10 +168,14 @@ public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest< public CompilationContext perform(ReadGraph graph) throws DatabaseException { RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.first, parameter.second)); - Map propertyMap = - graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()), - TransientCacheListener.>instance()); - return new CompilationContext(runtimeEnvironment, propertyMap); + if(parameter.first != null) { + Map propertyMap = + graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()), + TransientCacheListener.>instance()); + return new CompilationContext(runtimeEnvironment, propertyMap); + } else { + return new CompilationContext(runtimeEnvironment, Collections.emptyMap()); + } } }); } diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java index ba575c630..1f2bd2102 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java @@ -140,7 +140,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos final AffineTransform transform, final Rectangle2D bounds, final Color color); } - private static final boolean DEBUG = false; + private static final boolean DEBUG = true; public static final int ELEMENT_PAINT_PRIORITY = 10; diff --git a/bundles/org.simantics.modeling.ui/META-INF/MANIFEST.MF b/bundles/org.simantics.modeling.ui/META-INF/MANIFEST.MF index 2a95d6fc6..fe8b8b9a6 100644 --- a/bundles/org.simantics.modeling.ui/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.modeling.ui/META-INF/MANIFEST.MF @@ -62,7 +62,8 @@ Require-Bundle: org.simantics.project;bundle-version="1.0.0", org.simantics.image.ui;bundle-version="1.0.0", org.simantics.export.core;bundle-version="1.0.0", org.slf4j.api, - org.simantics.graphfile.ontology + org.simantics.graphfile.ontology, + org.simantics.threadlog Export-Package: org.simantics.modeling.ui, org.simantics.modeling.ui.actions, org.simantics.modeling.ui.chart.property, diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerLoadJob.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerLoadJob.java index 85f0dbbe7..926ec6ae3 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerLoadJob.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerLoadJob.java @@ -22,6 +22,8 @@ import org.simantics.db.exception.CancelTransactionException; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.IDiagram; import org.simantics.modeling.ui.Activator; +import org.simantics.threadlog.Task; +import org.simantics.threadlog.ThreadLog; import org.simantics.utils.DataContainer; import org.simantics.utils.threads.ThreadUtils; @@ -42,10 +44,12 @@ public class DiagramViewerLoadJob extends DatabaseJob { try { Object task = BEGIN("DV.loadDiagram"); + System.err.println("foo1"); final IDiagram diagram = viewer.loadDiagram(mon.newChild(100), viewer.diagramResource); if (diagram == null) return Status.CANCEL_STATUS; END(task); + System.err.println("foo2"); // Start an activation for the input resource. // This will activate mapping if necessary. @@ -126,14 +130,14 @@ public class DiagramViewerLoadJob extends DatabaseJob { protected static Object BEGIN(String name) { if (PROFILE) { - //return ThreadLog.BEGIN(name); + return ThreadLog.BEGIN(name); } return null; } protected static void END(Object task) { if (PROFILE) { - //((Task) task).end(); + ((Task) task).end(); } } } diff --git a/bundles/org.simantics.modeling/adapters.xml b/bundles/org.simantics.modeling/adapters.xml index 429cd0d59..d0895900b 100644 --- a/bundles/org.simantics.modeling/adapters.xml +++ b/bundles/org.simantics.modeling/adapters.xml @@ -256,4 +256,10 @@ + + + + + \ No newline at end of file diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentPropertyContentRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentPropertyContentRequest.java index 32db2bb90..61ffac837 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentPropertyContentRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentPropertyContentRequest.java @@ -16,6 +16,7 @@ import org.simantics.db.layer0.request.PropertyInfo; import org.simantics.db.layer0.request.UnescapedPropertyMapOfResource; import org.simantics.db.layer0.variable.ValueAccessor; import org.simantics.db.layer0.variable.Variable; +import org.simantics.diagram.Logger; import org.simantics.layer0.Layer0; import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.function.Function1; @@ -79,9 +80,13 @@ public class ImmutableComponentPropertyContentRequest extends BinaryRead getChildren(ReadGraph graph) throws DatabaseException { + + if(content.procedural) { + return new StandardGraphChildVariable(parent, null, content.resource).getChildren(graph); + } + if(content.children == null) return Collections.emptyList(); ArrayList result = new ArrayList(content.children.size()); for(ImmutableComponentVariableContent c : content.children.values()) { result.add(new ImmutableComponentVariable(this, c)); } return result; + } @Override diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableBuilder.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableBuilder.java index 37c882c64..87a342f13 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableBuilder.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableBuilder.java @@ -3,6 +3,7 @@ package org.simantics.modeling; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.request.PossibleIndexRoot; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.StandardGraphChildVariable; @@ -15,7 +16,17 @@ public class ImmutableComponentVariableBuilder implements VariableBuilder< @Override public Variable buildChild(ReadGraph graph, Variable parent, VariableNode node, Resource child) throws DatabaseException { - if(graph.isImmutable(child)) { + boolean isImmutable = graph.isImmutable(child); + Resource possibleIndexRoot = graph.syncRequest(new PossibleIndexRoot(child)); + if(possibleIndexRoot != null) { +// String puri = graph.getURI(possibleIndexRoot); +// if(puri.contains("ModelBroker")) +// isImmutable = true; +// if(NameUtils.getSafeName(graph, child).equals("Project")) +// isImmutable = false; + } + if(isImmutable) { +// System.err.println("ImmutableComponentVariableContentRequest " + parent.getURI(graph) + " " + NameUtils.getSafeName(graph, child)); ImmutableComponentVariableContent content = graph.syncRequest(new ImmutableComponentVariableContentRequest(child), TransientCacheListener.instance()); return new ImmutableComponentVariable(parent, content); } else { diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContent.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContent.java index 5124228a0..95998f33b 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContent.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContent.java @@ -8,6 +8,7 @@ public class ImmutableComponentVariableContent { final public Resource resource; final public String name; + boolean procedural = false; public Map children; public Map properties; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContentRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContentRequest.java index ac08c945e..cef62c242 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContentRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ImmutableComponentVariableContentRequest.java @@ -12,6 +12,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.request.PropertyInfo; import org.simantics.db.layer0.request.UnescapedPropertyMapOfResource; import org.simantics.layer0.Layer0; +import org.simantics.structural.stubs.StructuralResource2; import org.simantics.structural2.ConnectionImpl; import org.simantics.structural2.Functions.StructuralChildMapOfResource; import org.simantics.structural2.queries.ConnectionPointMapOfResource; @@ -28,6 +29,11 @@ public class ImmutableComponentVariableContentRequest extends ResourceRead pis = graph.syncRequest(new UnescapedPropertyMapOfResource(resource)); diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLExternalValue.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLExternalValue.java new file mode 100644 index 000000000..513d8d697 --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLExternalValue.java @@ -0,0 +1,28 @@ +package org.simantics.modeling; + +import org.simantics.db.ConverterExternalValue; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.scl.reflection.ReflectionUtils; +import org.simantics.scl.reflection.ValueNotFoundException; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.structural2.scl.CompileStructuralValueRequest; + +public class SCLExternalValue implements ConverterExternalValue { + + @Override + public T getValue(ReadGraph graph, Resource resource) throws DatabaseException { + try { + return (T)ReflectionUtils.getValue(ModelingResources.URIs.Functions_sclValue).getValue(); + } catch (ValueNotFoundException e) { + throw new DatabaseException(e); + } + } + + @Override + public Function1 getFunction(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + return CompileStructuralValueRequest.compile(graph, s, o, p); + } + +} diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java index f3f5b9170..9fda66d07 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java @@ -78,7 +78,9 @@ public enum GraphModuleSourceRepository implements ModuleSourceRepository { SCLContext context = SCLContext.getCurrent(); Object oldGraph = context.put("graph", graph); try { - listener.notifyAboutUpdate(); + synchronized(GraphModuleSourceRepository.class) { + listener.notifyAboutUpdate(); + } } finally { listener = null; context.put("graph", oldGraph); diff --git a/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java b/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java index 618d6a91f..1ed044dd2 100644 --- a/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java +++ b/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java @@ -36,6 +36,7 @@ import org.simantics.scl.osgi.SCLOsgi; import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.function.Function; import org.simantics.scl.runtime.function.Function1; +import org.simantics.scl.runtime.reporting.SCLReportingHandler; import org.simantics.scl.runtime.tuple.Tuple; import org.simantics.scl.runtime.tuple.Tuple0; import org.simantics.utils.DataContainer; @@ -114,15 +115,18 @@ public class SCLFunctions { if (graph != null) { return (T)f.apply(Tuple0.INSTANCE); } else { + final SCLReportingHandler printer = (SCLReportingHandler)SCLContext.getCurrent().get(SCLReportingHandler.REPORTING_HANDLER); return Simantics.getSession().syncRequest(new WriteResultRequest() { @Override public T perform(WriteGraph graph) throws DatabaseException { SCLContext.push(context); + SCLReportingHandler oldPrinter = (SCLReportingHandler)context.put(SCLReportingHandler.REPORTING_HANDLER, printer); ReadGraph oldGraph = (ReadGraph)context.put(GRAPH, graph); try { return (T)f.apply(Tuple0.INSTANCE); } finally { context.put(GRAPH, oldGraph); + context.put(SCLReportingHandler.REPORTING_HANDLER, oldPrinter); SCLContext.pop(); } } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileStructuralValueRequest.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileStructuralValueRequest.java index 3b54c0f62..4e1503c2d 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileStructuralValueRequest.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileStructuralValueRequest.java @@ -49,6 +49,10 @@ public class CompileStructuralValueRequest extends AbstractCompileStructuralValu } } + public static Function1 compile(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + return graph.syncRequest(new CompileStructuralValueRequest(s, o, p), TransientCacheListener.>instance()); + } + @Override protected String getExpressionText(ReadGraph graph) throws DatabaseException { diff --git a/bundles/org.simantics.threadlog/build.properties b/bundles/org.simantics.threadlog/build.properties index dfa46571b..3e4e0e1f1 100644 --- a/bundles/org.simantics.threadlog/build.properties +++ b/bundles/org.simantics.threadlog/build.properties @@ -12,4 +12,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ - . + .,\ + scl/ diff --git a/bundles/org.simantics.threadlog/scl/Simantics/ThreadLog.scl b/bundles/org.simantics.threadlog/scl/Simantics/ThreadLog.scl new file mode 100644 index 000000000..fa2c9c587 --- /dev/null +++ b/bundles/org.simantics.threadlog/scl/Simantics/ThreadLog.scl @@ -0,0 +1,4 @@ + +importJava "org.simantics.threadlog.ui.ThreadLogController" where + @JavaName "start" + showThreadLog :: () diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/internal/Activator.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/internal/Activator.java index 309cab556..d58b4abe7 100644 --- a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/internal/Activator.java +++ b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/internal/Activator.java @@ -40,7 +40,7 @@ public class Activator extends Plugin { super.start(context); plugin = this; - ThreadLogController.start(); + //ThreadLogController.start(); } /* diff --git a/features/org.simantics.document.base.feature/feature.xml b/features/org.simantics.document.base.feature/feature.xml index 81d71572a..79a60110f 100644 --- a/features/org.simantics.document.base.feature/feature.xml +++ b/features/org.simantics.document.base.feature/feature.xml @@ -38,4 +38,11 @@ version="0.0.0" unpack="false"/> + +