]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ExternalReadEntry.java
Some enhancements made by Antti for multiple readers
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / ExternalReadEntry.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.ArrayList;
15 import java.util.LinkedList;
16
17 import org.simantics.db.exception.DatabaseException;
18 import org.simantics.db.impl.DebugPolicy;
19 import org.simantics.db.impl.graph.ReadGraphImpl;
20 import org.simantics.db.procedure.AsyncProcedure;
21 import org.simantics.db.procedure.Procedure;
22 import org.simantics.db.request.ExternalRead;
23 import org.simantics.db.request.RequestFlags;
24
25 final public class ExternalReadEntry<T> extends CacheEntryBase<AsyncProcedure<T>> {
26
27     final LinkedList<T> items = new LinkedList<T>();
28
29     protected ExternalRead<T> request;
30
31     @Override
32     int makeHash() {
33         return request.hashCode();
34     }
35     
36     @Override
37     public Object getOriginalRequest() {
38         return request;
39     }
40     
41     @Override
42     public void clearResult(QuerySupport support) {
43     }
44     
45     @Override
46     public void discard() {
47         request.unregistered();
48         request = null;
49         super.discard();
50     }
51
52     @Override
53     public void setPending() {
54         if(result != NO_RESULT) {
55             //new Exception("result = " + result).printStackTrace();
56         }
57         statusOrException = PENDING;
58         result = REQUIRES_COMPUTATION;
59     }
60     
61     public ExternalReadEntry(ExternalRead<T> request) {
62         assert request != null;
63         this.request = request;
64     }
65     
66     final public void queue(T item) {
67         synchronized(items) {
68                 items.addLast(item);
69                 // TODO: implement flags/logic in ExternalRead to state that all but the latest request result can be evaporated
70                 // In some cases where data is produced really fast this might be necessary but currently this queueing will do.
71         }
72     }
73     
74     final public void addOrSet(QueryProcessor processor, Object item) {
75
76         try {
77         
78             assert(isPending());
79
80             ArrayList<Procedure<T>> p = null;
81
82             synchronized(this) {
83
84                 setResult(item);
85                 setReady();
86 //                p = procs;
87 //                procs = null;
88
89             }
90
91 //            if(p != null)
92 //                for(Procedure proc : p) {
93 //                    proc.execute((T)item);
94 //                }
95
96         } catch (Throwable t) {
97             t.printStackTrace();
98         }
99         
100     }
101     
102     @Override
103     public void except(Throwable t) {
104         if(DebugPolicy.QUERY_STATE) System.out.println("[QUERY STATE]: excepted " + this);
105         if(statusOrException != DISCARDED) {
106             statusOrException = EXCEPTED;
107             result = t;
108         } else {
109             result = t;
110         }
111         assert(isExcepted());
112     }
113     
114     @Override
115     public void setResult(Object result) {
116         super.setResult(result);
117         assert(!(result instanceof Throwable));
118         assert(!isExcepted());
119     }
120
121     @Override
122     final public Query getQuery() {
123         
124         return new Query() {
125
126                         @Override
127                         public void recompute(ReadGraphImpl graph) {
128
129                                 synchronized(items) {
130
131
132                                         // Update
133                                         if(!items.isEmpty()) {
134                                             setReady();
135                                                 setResult(items.removeFirst());
136                                         }
137                                         // Reschedule
138                                         if(!items.isEmpty()) {
139                                                 graph.processor.updatePrimitive(request);
140                                         }
141
142                                 }
143                                 
144                         }
145
146                         @Override
147                         public void removeEntry(QueryProcessor processor) {
148                                 processor.cache.remove(ExternalReadEntry.this);
149                         }
150
151                         @Override
152                         public int type() {
153                                 return RequestFlags.IMMEDIATE_UPDATE;
154                         }
155                         
156                         @Override
157                         public String toString() {
158                                 if(request == null) return "DISCARDED ExternalRead";
159                                 else return request.toString();
160                         }
161                 
162         };
163         
164     }
165
166         @Override
167         public String toString() {
168                 if(request == null) return "DISCARDED ExternalRead " + System.identityHashCode(this);
169                 else return request.toString() + " " + + System.identityHashCode(this);
170         }
171
172     @Override
173     public Object performFromCache(ReadGraphImpl graph, AsyncProcedure<T> procedure) {
174         
175         AsyncProcedure<T> proc = (AsyncProcedure<T>)procedure;
176
177             if(isExcepted()) {
178             
179             proc.exception(graph, (Throwable)getResult());
180             
181         } else {
182             
183             proc.execute(graph, (T)getResult());
184
185         }
186             
187             return getResult();
188         
189     }
190     
191     @Override
192     void prepareRecompute(QuerySupport querySupport) {
193         // Do nothing - the state is already set and cannot be recomputed on demand
194     }
195
196         @Override
197         public Object compute(ReadGraphImpl graph, AsyncProcedure<T> procedure) throws DatabaseException {
198         return graph.processor.cache.performQuery(graph, request, this, procedure);
199         }
200
201 }