]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/NamespaceIndex.java
a0a8c19cbef996a68749fd8947c583f10b0a93ff
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / NamespaceIndex.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 gnu.trove.map.hash.TObjectIntHashMap;
15
16 import java.util.concurrent.Semaphore;
17
18 import org.simantics.databoard.binding.Binding;
19 import org.simantics.databoard.serialization.Serializer;
20 import org.simantics.databoard.util.URIStringUtils;
21 import org.simantics.db.common.WriteBindings;
22 import org.simantics.db.common.exception.DebugException;
23 import org.simantics.db.impl.graph.ReadGraphImpl;
24 import org.simantics.db.impl.procedure.InternalProcedure;
25 import org.simantics.db.procedure.ListenerBase;
26
27 final public class NamespaceIndex extends StringQuery<InternalProcedure<TObjectIntHashMap<String>>> {
28         
29     private NamespaceIndex(final String id) {
30         super(id);
31     }
32     
33     final static void runner(ReadGraphImpl graph, final String id, final QueryProcessor provider, NamespaceIndex cached, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<TObjectIntHashMap<String>> procedure) {
34
35         NamespaceIndex entry = cached != null ? cached : (NamespaceIndex)provider.cache.namespaceIndexMap22.get(id); 
36         if(entry == null) {
37                 
38                 entry = new NamespaceIndex(id);
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.isPending()) {
48                 synchronized(entry) {
49                     if(entry.isPending()) {
50                         throw new IllegalStateException();
51 //                      if(entry.procs == null) entry.procs = new ArrayList<InternalProcedure<TObjectIntHashMap<String>>>(); 
52 //                      entry.procs.add(procedure);
53 //                        provider.registerDependencies(graph, entry, parent, listener, procedure, false);
54 //                      return;
55                     }
56                 }
57             }
58             provider.performForEach(graph, entry, parent, listener, procedure);
59         }
60         
61     }
62     
63     final public static void queryEach(ReadGraphImpl graph, final String id, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<TObjectIntHashMap<String>> procedure) {
64
65         final NamespaceIndex entry = (NamespaceIndex)provider.cache.namespaceIndexMap22.get(id);
66         
67         if(parent == null && listener == null && entry != null && entry.isReady()) {
68                 entry.performFromCache(graph, provider, procedure);
69                 return;
70         }
71         
72         runner(graph, id, provider, entry, parent, listener, procedure);
73         
74     }
75      
76         @Override
77         public NamespaceIndex getEntry(QueryProcessor provider) {
78         return provider.cache.namespaceIndexMap22.get(id);
79         }
80         
81         @Override
82         public void putEntry(QueryProcessor provider) {
83         provider.cache.namespaceIndexMap22.put(id, this);
84         }
85
86         @Override
87         final public void removeEntry(QueryProcessor provider) {
88                 provider.cache.namespaceIndexMap22.remove(id);
89         }
90         
91         final private void index(ReadGraphImpl graph, final QueryProcessor provider, int root, final InternalProcedure<TObjectIntHashMap<String>> procedure) {
92                 
93                 if(root == 0) {
94             add2(graph, null);
95             procedure.execute(graph, null);
96 //            System.err.println("NamespaceIndex[" + id + "]->null");
97             return;
98                 }
99
100                 final int consistsOf = provider.getConsistsOf();
101                 final int hasName = provider.getHasName();
102         
103         final TObjectIntHashMap<String> result = new TObjectIntHashMap<String>();
104         
105         Objects.runner(graph, root, consistsOf, graph.parent, null, new SyncIntProcedure() {
106                 
107                 @Override
108                         public void run(ReadGraphImpl graph) {
109                         
110                         if(isPending()) { 
111                     add2(graph, result);
112                     procedure.execute(graph, result);
113 //                    System.err.println("NamespaceIndex[" + id + "]->" + result.size());
114                         } else {
115                                 procedure.exception(graph, (Throwable)statusOrException);
116                         }
117                                 
118                         }
119
120                         @Override
121                         public void finished(ReadGraphImpl graph) {
122                             
123                                 dec(graph);
124                                 
125                         }
126
127                 @Override
128                 public void execute(ReadGraphImpl graph, final int obj) {
129                         
130                         //System.out.println(id + " => " + obj);
131
132                         inc();
133                         
134                         Objects.runner(graph, obj, hasName, graph.parent, null, new IntProcedure() {
135                         
136                         @Override
137                         public void execute(ReadGraphImpl graph, int i) {
138
139                                 inc();
140
141                                 ValueQuery.queryEach(graph, i, NamespaceIndex.this, null, new InternalProcedure<byte[]>() {
142                                         
143                                         @Override
144                                         public void execute(ReadGraphImpl graph, byte[] value) {
145                                                 
146                                                 if(value != null) {
147
148                                         try {
149
150                                                 Binding b = WriteBindings.STRING;
151                                             Serializer serializer = b.serializer();
152                                             final String part = (String)serializer.deserialize(value);
153         
154                                             synchronized(result) {
155                                                 Object previous = result.put(URIStringUtils.escape(part), obj);
156                                                 // TODO: this is not the most elegant solution
157                                                 if(previous != null) previous = "";
158                                             }
159                                             
160                                                 } catch (Throwable e) {
161                                             if(DebugException.DEBUG) new DebugException(e).printStackTrace();
162                                         }
163                                                 
164                                                 }
165                                                 
166                                         dec(graph);
167                                         
168                                         }
169                                         
170                                         @Override
171                                         public void exception(ReadGraphImpl graph, Throwable t) {
172                                                         except(t);
173                                                 dec(graph);
174                             }
175
176                                 });
177                                 
178                         }
179                         
180                         @Override
181                         public void finished(ReadGraphImpl graph) {
182                                 dec(graph);
183                         }
184                                 
185                                 @Override
186                                 public void exception(ReadGraphImpl graph, Throwable t) {
187                                                 except(t);
188                         dec(graph);
189                     }
190
191                 });
192
193                 }
194                 
195         });
196         
197     }
198
199     @Override
200         public void computeForEach(ReadGraphImpl graph, final QueryProcessor processor, final InternalProcedure<TObjectIntHashMap<String>> procedure) {
201         
202 //      System.err.println("NamespaceIndex " + id);
203         
204         if("http://".equals(id) || "http:/".equals(id)) {
205             index(graph, processor, processor.getRootLibrary(), procedure);
206         } else {
207             final String[] parts = URIStringUtils.splitURI(id);
208             if(parts != null) {
209                 NamespaceIndex.queryEach(graph, parts[0], processor, this, null, new InternalProcedure<TObjectIntHashMap<String>>() {
210     
211                     @Override
212                     public void execute(ReadGraphImpl graph, TObjectIntHashMap<String> index) {
213     
214                         if(index != null) {
215                             index(graph, processor, index.get(parts[1]), procedure);
216                         } else {
217                             add2(graph, null);
218                             procedure.execute(graph, null);
219 //                            System.err.println("NamespaceIndex[" + id + "]->null");
220                         }
221                         
222                     }
223     
224                     @Override
225                     public void exception(ReadGraphImpl graph, Throwable t) {
226                         if(DebugException.DEBUG) new DebugException(t).printStackTrace();
227                         except(t);
228                         procedure.exception(graph, t);
229                     }
230     
231                 });
232             } else {
233                 add2(graph, null);
234                 procedure.execute(graph, null);
235 //                System.err.println("NamespaceIndex[" + id + "]->null");
236             }
237
238         }
239         
240     }
241
242     @Override
243     public String toString() {
244         return "NamespaceIndex[" + id + "]";
245     }
246
247     synchronized private void add(TObjectIntHashMap<String> result) {
248         
249         throw new Error("Not possible!");
250         
251     }
252
253     private void add2(ReadGraphImpl graph, TObjectIntHashMap<String> result) {
254         
255         if(!isPending()) {
256                 new Exception(""+hashCode()).printStackTrace();
257         }
258         
259         assert(isPending());
260
261 //        ArrayList<InternalProcedure<TObjectIntHashMap<String>>> p = null;
262
263         synchronized(this) {
264
265             setResult(result);
266                 setReady();
267 //            p = procs;
268 //            procs = null; 
269         
270         }
271         
272 //        if(p != null) {
273 //        
274 //              for(InternalProcedure<TObjectIntHashMap<String>> proc : p) proc.execute(graph, result);
275 //              
276 //        }
277         
278     }
279     
280     @Override
281     public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<TObjectIntHashMap<String>> procedure) {
282         
283         assert(isReady());
284         
285         if(handleException(graph, procedure)) return;
286         
287         procedure.execute(graph, (TObjectIntHashMap<String>)getResult());
288         
289     }
290     
291     @Override
292     public synchronized void recompute(ReadGraphImpl graph, QueryProcessor provider) {
293         
294         final Semaphore s = new Semaphore(0);
295         
296         computeForEach(graph, provider, new InternalProcedure<TObjectIntHashMap<String>>() {
297
298             @Override
299             public void execute(ReadGraphImpl graph, TObjectIntHashMap<String> result) {
300                 s.release();
301             }
302                         
303                         @Override
304                         public void exception(ReadGraphImpl graph, Throwable t) {
305                 if(DebugException.DEBUG) new DebugException(t).printStackTrace();
306                                 throw new Error("Error in recompute.", t);
307             }
308
309         });
310         
311         while(!s.tryAcquire()) {
312                 provider.resume(graph);
313         }
314         
315     }
316     
317 }
318