1 /*******************************************************************************
2 * Copyright (c) 2007, 2018 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.impl.query;
14 import java.util.concurrent.atomic.AtomicInteger;
16 import org.simantics.db.common.utils.Logger;
17 import org.simantics.db.exception.DatabaseException;
18 import org.simantics.db.impl.graph.ReadGraphImpl;
19 import org.simantics.db.impl.procedure.InternalProcedure;
21 import gnu.trove.procedure.TIntProcedure;
22 import gnu.trove.set.hash.TIntHashSet;
24 public final class SuperRelations extends UnaryQueryP<IntSet> {
26 SuperRelations(final int resource) {
30 static final SuperRelations entry(final QueryProcessor provider, final int r) {
31 return (SuperRelations)provider.cache.superRelationsMap.get(r);
35 public final void removeEntry(QueryProcessor provider) {
36 provider.cache.remove(this);
41 private TIntHashSet set = null;
42 public int single = 0;
44 public boolean add(int val) {
45 if(single == val) return false;
50 if(set == null) set = new TIntHashSet(4);
56 if(single == 0) return 0;
57 if(set == null) return 1;
58 return set.size() + 1;
62 public void forEach(TIntProcedure proc) {
63 if(single > 0) proc.execute(single);
64 if(set != null) set.forEach(proc);
69 public void compute(final ReadGraphImpl graph, final InternalProcedure<IntSet> procedure) throws DatabaseException {
70 computeForEach(graph, id, this, procedure);
73 static class DirectProcedure extends Ints implements IntProcedure, TIntProcedure, InternalProcedure<IntSet> {
76 InternalProcedure<IntSet> proc;
78 public DirectProcedure(IntSet result, InternalProcedure<IntSet> proc) {
84 final public boolean execute(int r) {
89 final public void execute(ReadGraphImpl graph, int r) {
97 public final void execute(ReadGraphImpl graph, IntSet set) throws DatabaseException {
99 proc.execute(graph, result);
102 public void finished(ReadGraphImpl graph) {
105 public void exception(ReadGraphImpl graph, Throwable t) {
106 throw new Error("Errors are not supported.", t);
111 public static Object computeForEach(final ReadGraphImpl graph, int id, SuperRelations entry, final InternalProcedure<IntSet> procedure_) throws DatabaseException {
113 InternalProcedure<IntSet> procedure = entry != null ? entry : procedure_;
115 QueryProcessor processor = graph.processor;
117 processor.querySupport.ensureLoaded(graph, id);
119 final InternalProcedure<IntSet> proc = (InternalProcedure<IntSet>)procedure;
121 final int subrelationOf = processor.getSubrelationOf();
123 final IntSet result = new IntSet(processor.querySupport);
125 final DirectProcedure directProc = new DirectProcedure(result, proc);
127 processor.querySupport.getObjects(graph, id, subrelationOf, directProc);
129 int size = directProc.size();
132 proc.execute(graph, IntSet.EMPTY);
133 } else if (size == 1) {
134 result.add(directProc.single);
135 QueryCache.runnerSuperRelations(graph, directProc.single, entry, null, directProc);
138 final TIntProcedure addToResult = new TIntProcedure() {
140 public boolean execute(int r) {
141 synchronized(result) {
148 final AtomicInteger finishes = new AtomicInteger(0);
150 directProc.forEach(new TIntProcedure() {
153 public boolean execute(int arg0) {
155 return execute0(arg0);
156 } catch (DatabaseException e) {
157 Logger.defaultLogError(e);
162 public boolean execute0(int arg0) throws DatabaseException {
164 synchronized(result) {
168 QueryCache.runnerSuperRelations(graph, arg0, entry, null, new InternalProcedure<IntSet>() {
171 public void execute(ReadGraphImpl graph, IntSet set) throws DatabaseException {
172 set.forEach(addToResult);
173 int current = finishes.addAndGet(1);
174 if(current == directProc.size()) {
175 proc.execute(graph, result);
181 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
182 proc.exception(graph, t);
195 if(entry != null) entry.performFromCache(graph, procedure_);
202 public String toString() {
203 return "SuperRelations[" + id + "]";