]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ValueQuery.java
d85595831851a5b87916d0edba978d2c67acef36
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / ValueQuery.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.impl.query;
13
14 import java.util.concurrent.Semaphore;
15
16 import org.simantics.db.impl.graph.ReadGraphImpl;
17 import org.simantics.db.impl.procedure.InternalProcedure;
18 import org.simantics.db.procedure.ListenerBase;
19
20 final public class ValueQuery extends UnaryQuery<InternalProcedure<byte[]>> {
21     
22     private ValueQuery(final int resource) {
23         super(resource);
24     }
25     
26     final static ValueQuery entry(final QueryProcessor provider, final int r) {
27         return (ValueQuery)provider.valueMap.get(r);
28     }
29
30     final static byte[] runner(final ReadGraphImpl graph, final int r, CacheEntry parent, final ListenerBase listener, final InternalProcedure<byte[]> procedure) {
31
32         QueryProcessor processor = graph.processor;
33         
34         ValueQuery entry = (ValueQuery)processor.valueMap.get(r); 
35         if(entry == null) {
36                 
37                 entry = new ValueQuery(r);
38                 entry.setPending();
39                 entry.clearResult(processor.querySupport);
40                 entry.putEntry(processor);
41                 
42                 return (byte[])processor.performForEach(graph, entry, parent, listener, procedure);
43             
44         } else {
45                 
46                 return (byte[])processor.performForEach(graph, entry, parent, listener, procedure);
47             
48         }
49
50     }
51     
52     final public static byte[] queryEach(ReadGraphImpl graph, final int r, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<byte[]> procedure) {
53         
54         assert(r != 0);
55         
56         if(graph.parent == null && listener == null) {
57                 return ValueQuery.computeForEach(graph, r, null, procedure);
58         } else {
59                 return runner(graph, r, parent, listener, procedure);
60         }
61          
62     }
63
64     final public static byte[] queryEach(ReadGraphImpl graph, final int r, final CacheEntry parent) {
65         
66         assert(r != 0);
67         
68         if(graph.parent == null) {
69             return ValueQuery.computeForEach(graph, r);
70         } else {
71             return runner(graph, r, parent, null, null);
72         }
73          
74     }
75     
76         @Override
77         public UnaryQuery<InternalProcedure<byte[]>> getEntry(QueryProcessor provider) {
78         return provider.valueMap.get(id);
79         }
80         
81         @Override
82         public void putEntry(QueryProcessor provider) {
83         provider.valueMap.put(id, this);
84         }
85
86         @Override
87         final public void removeEntry(QueryProcessor provider) {
88                 provider.valueMap.remove(id);
89         }
90         
91                 
92         public static byte[] computeForEach(ReadGraphImpl graph, final int r, final ValueQuery entry, final InternalProcedure<byte[]> procedure) {
93
94                 graph.ensureLoaded(r);
95                 
96                 byte[] value = graph.getValue(r);
97                 if(entry != null) {
98                         entry.setResult(value);
99                         entry.setReady();
100                 }
101                 if(procedure != null) {
102                         procedure.execute(graph, value);
103                 }
104                 
105                 return value;
106                 
107         }
108
109     public static byte[] computeForEach(ReadGraphImpl graph, final int r) {
110
111         graph.ensureLoaded(r);
112         
113         return graph.getValue(r);
114         
115     }
116         
117         @Override
118         public Object computeForEach(ReadGraphImpl graph, final QueryProcessor queryProvider, final InternalProcedure<byte[]> procedure, final boolean store) {
119                 return computeForEach(graph, id, this, procedure);
120     }
121     
122     @Override
123     public String toString() {
124         return "Value[" + id + "]";
125     }
126
127     @Override
128     public Object performFromCache(ReadGraphImpl graph, QueryProcessor queryProvider, InternalProcedure<byte[]> procedure) {
129         return computeForEach(graph, queryProvider, procedure, false);
130     }
131     
132     @Override
133     public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
134
135         final Semaphore s = new Semaphore(0);
136         
137         computeForEach(graph, provider, new InternalProcedure<byte[]>() {
138
139             @Override
140             public void execute(ReadGraphImpl graph, byte[] result) {
141                 s.release();
142             }
143                         
144                         @Override
145                         public void exception(ReadGraphImpl graph, Throwable t) {
146                                 throw new Error("Error in recompute.", t);
147             }
148
149         }, true);
150         
151         while(!s.tryAcquire()) {
152                 provider.resume(graph);
153         }
154         
155     }
156     
157     @Override
158     boolean isImmutable(ReadGraphImpl graph) {
159         return graph.processor.isImmutable(id);
160     }    
161     
162 }