/******************************************************************************* * 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.impl.query; import java.util.concurrent.atomic.AtomicInteger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.impl.graph.ReadGraphImpl; import org.simantics.db.impl.procedure.InternalProcedure; import gnu.trove.procedure.TIntProcedure; final public class Types extends UnaryQuery> { Types(final int resource) { super(resource); } @Override final public void removeEntry(QueryProcessor provider) { provider.cache.remove(this); } @Override public Object compute(final ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { computeForEach(graph, id, this, procedure); return getResult(); } public static void computeForEach(final ReadGraphImpl graph, int id, Types entry, final InternalProcedure procedure) throws DatabaseException { if(entry != null) if(entry.isReady()) System.err.println("asd"); assert(procedure != null); QueryProcessor processor = graph.processor; processor.querySupport.ensureLoaded(graph, id); int ret = processor.querySupport.getSingleInstance(id); if(ret > 0) { TypeHierarchy.queryEach(graph, ret, processor, entry, null, new InternalProcedure() { @Override public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException { if(entry != null) entry.addOrSet(graph, types, processor); procedure.execute(graph, types); } @Override public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { procedure.exception(graph, t); } }); } final int instanceOf = processor.getInstanceOf(); final int inherits = processor.getInherits(); final int subrelationOf = processor.getSubrelationOf(); final IntSet result = new IntSet(processor.querySupport); final TIntProcedure addToResult = new TIntProcedure() { @Override public boolean execute(int r) { synchronized(result) { result.add(r); } return true; } }; final AtomicInteger finishes = new AtomicInteger(0); SyncIntProcedure instanceOfProcedure = new SyncIntProcedure() { @Override public void run(ReadGraphImpl graph) throws DatabaseException { if(finishes.addAndGet(1) == 3) { if(entry != null) entry.addOrSet(graph, result, processor); procedure.execute(graph, result); } } @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { synchronized(result) { result.add(i); } inc(); QueryCache.runnerSuperTypes(graph, i, entry, null, new InternalProcedure() { @Override public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException { types.forEach(addToResult); dec(graph); } @Override public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { procedure.exception(graph, t); dec(graph); } }); } @Override public void finished(ReadGraphImpl graph) throws DatabaseException { dec(graph); } }; SyncIntProcedure inheritsProcedure = new SyncIntProcedure() { @Override public void run(ReadGraphImpl graph) throws DatabaseException { int current = finishes.addAndGet(1); if(current == 3) { if(entry != null) entry.addOrSet(graph, result, processor); procedure.execute(graph, result); } } @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { inc(); QueryCache.runnerTypes(graph, i, entry, null, new InternalProcedure() { @Override public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException { types.forEach(addToResult); dec(graph); } @Override public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { procedure.exception(graph, t); dec(graph); } }); } @Override public void finished(ReadGraphImpl graph) throws DatabaseException { dec(graph); } }; SyncIntProcedure subrelationOfProcedure = new SyncIntProcedure() { @Override public void run(ReadGraphImpl graph) throws DatabaseException { int current = finishes.addAndGet(1); if(current == 3) { if(entry != null) entry.addOrSet(graph, result, processor); procedure.execute(graph, result); } } @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { inc(); QueryCache.runnerTypes(graph, i, entry, null, new InternalProcedure() { @Override public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException { types.forEach(addToResult); dec(graph); } @Override public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { procedure.exception(graph, t); dec(graph); } }); } @Override public void finished(ReadGraphImpl graph) throws DatabaseException { dec(graph); } }; processor.querySupport.getObjects(graph, id, instanceOf, instanceOfProcedure); instanceOfProcedure.finished(graph); processor.querySupport.getObjects(graph, id, inherits, inheritsProcedure); inheritsProcedure.finished(graph); processor.querySupport.getObjects(graph, id, subrelationOf, subrelationOfProcedure); subrelationOfProcedure.finished(graph); if(entry != null) entry.finish(); } @Override public String toString() { return "Types[" + id + "]"; } private void addOrSet(ReadGraphImpl graph, final IntSet value, QueryProcessor provider) { assert(!isReady()); setResult(value); } void finish() { IntSet result = getResult(); result.trim(); setReady(); } @Override final public Object performFromCache(ReadGraphImpl graph, InternalProcedure procedure) throws DatabaseException { assert(isReady()); if(handleException(graph, procedure)) return EXCEPTED; IntSet result = getResult(); procedure.execute(graph, result); return result; } @Override public void recompute(ReadGraphImpl graph) throws DatabaseException { compute(graph, new InternalProcedure() { @Override public void execute(ReadGraphImpl graph, IntSet result) { } @Override public void exception(ReadGraphImpl graph, Throwable t) { new Error("Error in recompute.", t).printStackTrace(); } }); } @Override boolean isImmutable(ReadGraphImpl graph) { return graph.processor.isImmutable(id); } }