1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 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.Semaphore;
16 import org.simantics.db.impl.graph.ReadGraphImpl;
17 import org.simantics.db.impl.procedure.InternalProcedure;
18 import org.simantics.db.procedure.ListenerBase;
20 final public class ValueQuery extends UnaryQuery<InternalProcedure<byte[]>> {
22 private ValueQuery(final int resource) {
26 final static ValueQuery entry(final QueryProcessor provider, final int r) {
27 return (ValueQuery)provider.valueMap.get(r);
30 final static byte[] runner(final ReadGraphImpl graph, final int r, CacheEntry parent, final ListenerBase listener, final InternalProcedure<byte[]> procedure) {
32 QueryProcessor processor = graph.processor;
34 ValueQuery entry = (ValueQuery)processor.valueMap.get(r);
37 entry = new ValueQuery(r);
39 entry.clearResult(processor.querySupport);
40 entry.putEntry(processor);
42 return (byte[])processor.performForEach(graph, entry, parent, listener, procedure);
46 return (byte[])processor.performForEach(graph, entry, parent, listener, procedure);
52 final public static byte[] queryEach(ReadGraphImpl graph, final int r, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<byte[]> procedure) {
56 if(graph.parent == null && listener == null) {
57 return ValueQuery.computeForEach(graph, r, null, procedure);
59 return runner(graph, r, parent, listener, procedure);
64 final public static byte[] queryEach(ReadGraphImpl graph, final int r, final CacheEntry parent) {
68 if(graph.parent == null) {
69 return ValueQuery.computeForEach(graph, r);
71 return runner(graph, r, parent, null, null);
77 public UnaryQuery<InternalProcedure<byte[]>> getEntry(QueryProcessor provider) {
78 return provider.valueMap.get(id);
82 public void putEntry(QueryProcessor provider) {
83 provider.valueMap.put(id, this);
87 final public void removeEntry(QueryProcessor provider) {
88 provider.valueMap.remove(id);
92 public static byte[] computeForEach(ReadGraphImpl graph, final int r, final ValueQuery entry, final InternalProcedure<byte[]> procedure) {
94 graph.ensureLoaded(r);
96 byte[] value = graph.getValue(r);
98 entry.setResult(value);
101 if(procedure != null) {
102 procedure.execute(graph, value);
109 public static byte[] computeForEach(ReadGraphImpl graph, final int r) {
111 graph.ensureLoaded(r);
113 return graph.getValue(r);
118 public Object computeForEach(ReadGraphImpl graph, final QueryProcessor queryProvider, final InternalProcedure<byte[]> procedure, final boolean store) {
119 return computeForEach(graph, id, this, procedure);
123 public String toString() {
124 return "Value[" + id + "]";
128 public Object performFromCache(ReadGraphImpl graph, QueryProcessor queryProvider, InternalProcedure<byte[]> procedure) {
129 return computeForEach(graph, queryProvider, procedure, false);
133 public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
135 final Semaphore s = new Semaphore(0);
137 computeForEach(graph, provider, new InternalProcedure<byte[]>() {
140 public void execute(ReadGraphImpl graph, byte[] result) {
145 public void exception(ReadGraphImpl graph, Throwable t) {
146 throw new Error("Error in recompute.", t);
151 while(!s.tryAcquire()) {
152 provider.resume(graph);
158 boolean isImmutable(ReadGraphImpl graph) {
159 return graph.processor.isImmutable(id);