/******************************************************************************* * Copyright (c) 2007, 2018 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * 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; public final class Types extends UnaryQueryP { Types(int resource) { super(resource); } @Override public final void removeEntry(QueryProcessor provider) { provider.cache.remove(this); } @Override public void compute(final ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { computeForEach(graph, id, this, procedure); } public static void computeForEach(final ReadGraphImpl graph, int id, Types entry, final InternalProcedure procedure_) throws DatabaseException { InternalProcedure procedure = entry != null ? entry : procedure_; computeForEach2(graph, id, entry, procedure); if (entry != null) entry.performFromCache(graph, procedure_); } public static void computeForEach2(final ReadGraphImpl graph, int id, Types parent, final InternalProcedure procedure) throws DatabaseException { QueryProcessor processor = graph.processor; processor.querySupport.ensureLoaded(graph, id); int ret = processor.querySupport.getSingleInstance(id); if (ret > 0) { TypeHierarchy.queryEach(graph, ret, processor, parent, null, new InternalProcedure() { @Override public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException { procedure.execute(graph, types); } @Override public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { procedure.exception(graph, t); } }); return; } 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) { procedure.execute(graph, result); } } @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { result.add(i); inc(); QueryCache.runnerSuperTypes(graph, i, parent, 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) { procedure.execute(graph, result); } } @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { inc(); QueryCache.runnerTypes(graph, i, parent, 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) { procedure.execute(graph, result); } } @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { inc(); QueryCache.runnerTypes(graph, i, parent, 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); } @Override public String toString() { return "Types[" + id + "]"; } }