]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectPredicates.java
606afa430c1e35e870aaed5e35abbb51612aa0ef
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / DirectPredicates.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.common.exception.DebugException;
17 import org.simantics.db.impl.graph.ReadGraphImpl;
18 import org.simantics.db.impl.procedure.IntProcedureAdapter;
19 import org.simantics.db.procedure.ListenerBase;
20
21 final public class DirectPredicates extends CollectionUnaryQuery<IntProcedure> {
22
23         private DirectPredicates(final int resource) {
24                 super(resource);
25         }
26
27         final static DirectPredicates entry(final QueryProcessor provider, final int r) {
28
29                 return (DirectPredicates)provider.directPredicatesMap.get(r);
30
31         }
32
33         final static void runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
34
35                 DirectPredicates entry = (DirectPredicates)provider.directPredicatesMap.get(r);
36                 if(entry == null) {
37
38                         entry = new DirectPredicates(r);
39                 entry.setPending();
40                 entry.clearResult(provider.querySupport);
41                 entry.putEntry(provider);
42                         
43                         provider.performForEach(graph, entry, parent, listener, procedure);
44                         
45                 } else {
46                         
47                         if(!entry.isReady()) {
48                                 synchronized(entry) {
49                                         if(!entry.isReady()) {
50                                                 provider.registerDependencies(graph, entry, parent, listener, procedure, false);
51                                                 entry.computeForEach(graph, provider, procedure, true);
52                                                 return;
53                                         }
54                                 }
55                         }
56                         
57                         provider.performForEach(graph, entry, parent, listener, procedure);
58                         
59                 }
60
61         }
62
63         final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
64
65                 if(parent == null && listener == null) {
66                         DirectPredicates entry = (DirectPredicates)provider.directPredicatesMap.get(r);
67                         if(entry != null && entry.isReady()) { 
68                                 entry.performFromCache(graph, provider, procedure);
69                                 return;
70                         } else {
71                             computeForEach(graph, r, null, procedure, false);
72                             return;
73                         }
74                 }
75
76                 runner(graph, r, provider, parent, listener, procedure);
77
78         }
79
80         
81         @Override
82         public void clearResult(QuerySupport support) {
83                 // The cached result is never used
84                 setResult(INVALID_RESULT);
85         }
86         
87         @Override
88         public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
89                 return provider.directPredicatesMap.get(id);
90         }
91
92         @Override
93         public void putEntry(QueryProcessor provider) {
94                 provider.directPredicatesMap.put(id, this);
95         }
96
97         @Override
98         final public void removeEntry(QueryProcessor provider) {
99                 provider.directPredicatesMap.remove(id);
100         }
101
102         @Override
103         public Object computeForEach(ReadGraphImpl graph, QueryProcessor provider, IntProcedure procedure, boolean store) {
104             return computeForEach(graph, id, this, procedure, store);
105         }
106         
107         public static Object computeForEach(ReadGraphImpl graph, int id, final DirectPredicates entry, final IntProcedure procedure, final boolean store) {
108
109                 graph.processor.querySupport.ensureLoaded(graph, id);
110                 
111                 final IntArray list = new IntArray();
112
113                 graph.processor.querySupport.getPredicates(graph, id, new IntProcedure() {
114
115                         @Override
116                         public void execute(ReadGraphImpl graph, int i) {
117                                 list.add(i);
118                         }
119
120                         @Override
121                         public void finished(ReadGraphImpl graph) {
122                         }
123
124                         @Override
125                         public void exception(ReadGraphImpl graph, Throwable t) {
126                                 if(DebugException.DEBUG) new DebugException(t).printStackTrace();
127                         }
128
129                 });
130
131                 if(entry != null)
132                     entry.finish(graph, graph.processor);
133
134                 if(list.data == null) {
135                         if(list.sizeOrData != IntArray.NO_DATA) procedure.execute(graph, list.sizeOrData);
136                 } else {
137                         for(int i = 0;i < list.sizeOrData ; i++) procedure.execute(graph, list.data[i]);
138                 }
139
140                 procedure.finished(graph);
141                 
142                 return list;
143
144         }
145
146         @Override
147         public String toString() {
148                 return "DirectPredicates[" + id + "]";
149         }
150
151         @Override
152         public void setReady() {
153                 statusOrException = READY;
154         }
155         
156         final private void finish(ReadGraphImpl graph, QueryProcessor provider) {
157
158                 setReady();
159
160         }
161
162         @Override
163         public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, IntProcedure procedure) {
164
165                 assert(isReady());
166
167                 return computeForEach(graph, provider, procedure, false);
168
169         }
170
171         @Override
172         public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
173
174                 final Semaphore s = new Semaphore(0);
175
176                 computeForEach(graph, provider, new IntProcedureAdapter() {
177
178                         @Override
179                         public void finished(ReadGraphImpl graph) {
180                                 s.release();
181                         }
182
183                         @Override
184                         public void exception(ReadGraphImpl graph, Throwable t) {
185                                 s.release();
186                                 new Error("Error in recompute.", t).printStackTrace();
187                         }
188
189                 }, true);
190
191         while(!s.tryAcquire()) {
192                 provider.resume(graph);
193         }
194
195         }
196
197
198     @Override
199     boolean isImmutable(ReadGraphImpl graph) {
200         return graph.processor.isImmutable(id);
201     }
202
203 }