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