]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/TypeHierarchy.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / TypeHierarchy.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.db.impl.query;\r
13 \r
14 import gnu.trove.procedure.TIntProcedure;\r
15 \r
16 import java.util.concurrent.Semaphore;\r
17 \r
18 import org.simantics.db.impl.graph.ReadGraphImpl;\r
19 import org.simantics.db.impl.procedure.InternalProcedure;\r
20 import org.simantics.db.procedure.ListenerBase;\r
21 \r
22 final public class TypeHierarchy extends UnaryQuery<InternalProcedure<IntSet>> {\r
23     \r
24 //      public ArrayList<InternalProcedure<IntSet>> procs = null;\r
25         \r
26     private TypeHierarchy(final int resource) {\r
27         super(resource);\r
28     }\r
29     \r
30     final static void runner(ReadGraphImpl graph, final int r, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {\r
31 \r
32         TypeHierarchy entry = (TypeHierarchy)provider.typeHierarchyMap.get(r);\r
33         if(entry == null) {\r
34 \r
35                 entry = new TypeHierarchy(r);\r
36                 entry.setPending();\r
37                 entry.clearResult(provider.querySupport);\r
38                 entry.putEntry(provider);\r
39                 \r
40             provider.performForEach(graph, entry, parent, listener, procedure);\r
41             \r
42         } else {\r
43                 \r
44             if(!entry.isReady()) {\r
45                 synchronized(entry) {\r
46                     if(!entry.isReady()) {\r
47                         throw new IllegalStateException();\r
48 //                      if(entry.procs == null) entry.procs = new ArrayList<InternalProcedure<IntSet>>();\r
49 //                      entry.procs.add(procedure);\r
50 //                                              provider.registerDependencies(graph, entry, parent, listener, procedure, false);\r
51 //                      return;\r
52                     }\r
53                 }\r
54             }\r
55             provider.performForEach(graph, entry, parent, listener, procedure);\r
56         }\r
57 \r
58     }\r
59     \r
60     final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {\r
61         \r
62         if(parent == null && listener == null) {\r
63                 TypeHierarchy entry = (TypeHierarchy)provider.typeHierarchyMap.get(r);\r
64                 if(entry != null && entry.isReady()) { \r
65                         entry.performFromCache(graph, provider, procedure);\r
66                         return;\r
67                 }\r
68         }\r
69         \r
70         runner(graph, r, parent, provider, listener, procedure);\r
71          \r
72     }\r
73         \r
74         @Override\r
75         public UnaryQuery<InternalProcedure<IntSet>> getEntry(QueryProcessor provider) {\r
76         return provider.typeHierarchyMap.get(id);\r
77         }\r
78         \r
79         @Override\r
80         public void putEntry(QueryProcessor provider) {\r
81         provider.typeHierarchyMap.put(id, this);\r
82         }\r
83 \r
84         @Override\r
85         final public void removeEntry(QueryProcessor provider) {\r
86                 provider.typeHierarchyMap.remove(id);\r
87         }\r
88 \r
89         @Override\r
90         public IntSet computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final InternalProcedure<IntSet> procedure, boolean store) {\r
91 \r
92         final IntSet result = new IntSet(provider.querySupport, id);\r
93         \r
94         final TIntProcedure addToResult = new TIntProcedure() {\r
95             @Override\r
96             public boolean execute(int r) {\r
97                 result.add(r);\r
98                 return true;\r
99             }\r
100         };\r
101         \r
102         SuperTypes.queryEach(graph, id, provider, TypeHierarchy.this, null, new InternalProcedure<IntSet>() {\r
103 \r
104                 @Override\r
105                 public void execute(ReadGraphImpl graph, IntSet types) {\r
106 \r
107                         types.forEach(addToResult);\r
108                         addOrSet(graph, result, provider);\r
109                         procedure.execute(graph, result); \r
110 \r
111                 }\r
112 \r
113                 @Override\r
114                 public void exception(ReadGraphImpl graph, Throwable t) {\r
115                         procedure.exception(graph, t);\r
116                 }\r
117 \r
118         });\r
119         \r
120         return result;\r
121                         \r
122     }\r
123     \r
124     @Override\r
125     public String toString() {\r
126         return "TypeHierarchy[" + id + "]";\r
127     }\r
128 \r
129     private void addOrSet(ReadGraphImpl graph, final IntSet value, QueryProcessor provider) {\r
130         \r
131         assert(!isReady());\r
132 \r
133 //        ArrayList<InternalProcedure<IntSet>> p = null;\r
134 \r
135         synchronized(this) {\r
136         \r
137             value.trim();\r
138             setResult(value);\r
139             setReady();\r
140 //            p = procs;\r
141 //            procs = null; \r
142         \r
143         }\r
144 \r
145 //        if(p != null) {\r
146 //              IntSet v = (IntSet)getResult();\r
147 //              if(v != null) {\r
148 //                  for(InternalProcedure<IntSet> proc : p) proc.execute(graph, v);\r
149 //              }\r
150 //        }\r
151         \r
152     }\r
153 \r
154     @Override\r
155     public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<IntSet> procedure) {\r
156         \r
157         assert(isReady());\r
158 \r
159         if(handleException(graph, procedure)) return null;\r
160         \r
161         IntSet result = getResult();\r
162         \r
163         procedure.execute(graph, result);\r
164         \r
165         return result;\r
166         \r
167     }\r
168     \r
169     @Override\r
170     public void recompute(ReadGraphImpl graph, QueryProcessor provider) {\r
171         \r
172         final Semaphore s = new Semaphore(0);\r
173 \r
174         computeForEach(graph, provider, new InternalProcedure<IntSet>() {\r
175 \r
176                 @Override\r
177                 public void execute(ReadGraphImpl graph, IntSet result) {\r
178                 s.release();\r
179                 }\r
180 \r
181             @Override\r
182             public void exception(ReadGraphImpl graph, Throwable t) {\r
183                 s.release();\r
184                 new Error("Error in recompute.", t).printStackTrace();\r
185             }\r
186 \r
187         }, true);\r
188 \r
189         while(!s.tryAcquire()) {\r
190                 provider.resume(graph);\r
191         }\r
192         \r
193     }\r
194     \r
195     @Override\r
196     boolean isImmutable(ReadGraphImpl graph) {\r
197         return graph.processor.isImmutable(id);\r
198     }    \r
199 }\r