1 | package com.hammurapi.store; |
2 | |
3 | import java.util.Comparator; |
4 | import java.util.Iterator; |
5 | import java.util.concurrent.locks.ReadWriteLock; |
6 | |
7 | import com.hammurapi.extract.Extractor; |
8 | import com.hammurapi.extract.Predicate; |
9 | |
10 | /** |
11 | * Abstraction of object store. |
12 | * @author Pavel Vlasov. |
13 | * |
14 | * @param <T> Object type. |
15 | * @param <PK> Primary key type. |
16 | * @param <S> Self-type - sub-type of store. Generic parameter for predicates, extractors, update tasks and views. |
17 | */ |
18 | public interface Store<T, PK, S extends Store<T,PK,S>> extends ReadWriteLock, Iterable<T> { |
19 | |
20 | enum ViewType { |
21 | /** |
22 | * Live perform all operations on the master data, they |
23 | * do not create an intermediary store for view data. |
24 | */ |
25 | LIVE, |
26 | /** |
27 | * Lazy views create intermediary store which contains only |
28 | * data visible by the view. Updates from the main store |
29 | * are queued up and get applied to the intermediary store when |
30 | * one of view data retrieval methods is invoked. |
31 | */ |
32 | LAZY, |
33 | /** |
34 | * Asynchronous views create intermediary store which contains only |
35 | * data visible by the view. Updates from the main store |
36 | * are queued up and get applied to the intermediary store in a |
37 | * background task, or when |
38 | * one of view data retrieval methods is invoked. |
39 | */ |
40 | ASYNCHRONOUS, |
41 | /** |
42 | * Synchronous views create intermediary store which contains only |
43 | * data visible by the view. Updates from the main store |
44 | * get applied to the view store as part of update operation. |
45 | */ |
46 | SYNCHRONOUS |
47 | } |
48 | |
49 | /** |
50 | * Object handle. |
51 | * @author Pavel Vlasov |
52 | * |
53 | * @param <T> |
54 | */ |
55 | interface Handle<T, PK, S extends Store<T,PK,S>> { |
56 | |
57 | /** |
58 | * Updates object referenced by this handle. Clears cache and updates |
59 | * indexes. The new object shall have the same primary key if the store |
60 | * has primary key extractor. |
61 | * @param obj New object for the handle (for immutable objects). |
62 | */ |
63 | void update(T obj); |
64 | |
65 | /** |
66 | * Clears cache and updates |
67 | * indexes. Updated object shall have the same primary key if the store |
68 | * has primary key extractor. |
69 | */ |
70 | void update(); |
71 | |
72 | /** |
73 | * Removes object referenced by this handle. |
74 | */ |
75 | void remove(); |
76 | |
77 | /** |
78 | * @return Object referenced by this handle. |
79 | */ |
80 | T get(); |
81 | |
82 | /** |
83 | * @return Primary key if object store is configured with primary |
84 | * key extractor. |
85 | */ |
86 | PK getPrimaryKey(); |
87 | |
88 | /** |
89 | * @return True if object referenced by this handle is present in the store. |
90 | */ |
91 | boolean isValid(); |
92 | |
93 | /** |
94 | * Extracts value from handle's object using given extractor |
95 | * and internal handle's cache. |
96 | * @param <V> Value type |
97 | * @param extractor Extractor |
98 | * @return extracted value. |
99 | */ |
100 | <V> V extract(Extractor<T, V, S> extractor); |
101 | } |
102 | |
103 | // CRUDI |
104 | |
105 | /** |
106 | * Puts object to the store. |
107 | * If object is already present in the store, it gets |
108 | * updated in the store. |
109 | * @param obj Object to put to the store. |
110 | * @param validators Predicate(s) which are checked when object is retrieved from the store. |
111 | * If there is more than one predicate, predicates are connected with AND. If validator(s) evaluate to |
112 | * false, the object handle is considered invalid, i.e. object is considered removed from the store. |
113 | * Once validator(s) evaluate to false, they shall always evaluate to false. One of use of validators |
114 | * can be to expire object in the store, i.e. after some time validator returns false and object is cleared |
115 | * from the database. If validators evaluate to false at put time, object is not put to the store and |
116 | * put() returns null. Validators evaluation result is not cached. |
117 | * @return Object handle or null if validator(s) evaluate to false. |
118 | */ |
119 | Handle<T, PK, S> put(T obj, Predicate<T, S>... validators); |
120 | |
121 | /** |
122 | * Retrieves all objects from the store. |
123 | * @return |
124 | */ |
125 | Iterable<T> getAll(); |
126 | |
127 | /** |
128 | * Processes all objects in the store. |
129 | * @param processor |
130 | * @return number of object queried. |
131 | */ |
132 | int queryAll(QueryTask<T, PK, S> processor); |
133 | |
134 | /** |
135 | * Retrieves object with given primary key. |
136 | * @param primaryKey |
137 | * @return |
138 | * @throws IllegalStateException if object store is configured without |
139 | * primary key. |
140 | */ |
141 | T getByPrimaryKey(PK primaryKey); |
142 | |
143 | /** |
144 | * Some stores may return StoreIterator, which |
145 | * needs to be closed if iterator operation is |
146 | * terminated before hasNext() returns false. |
147 | * @author Pavel Vlasov. |
148 | * |
149 | * @param <T> |
150 | */ |
151 | interface StoreIterator<T> extends Iterator<T> { |
152 | void close(); |
153 | } |
154 | |
155 | /** |
156 | * Retrieves objects matching the predicate. |
157 | * @param selector |
158 | * @return |
159 | */ |
160 | Iterable<T> get(Predicate<T, S> selector); |
161 | |
162 | /** |
163 | * Processes objects matching the predicate. |
164 | * @param selector |
165 | * @return Number of objects queried. |
166 | */ |
167 | int query(Predicate<T, S> selector, QueryTask<T, PK, S> processor); |
168 | |
169 | /** |
170 | * Processes values extracted from objects matching the predicate. |
171 | * @param selector |
172 | * @param extractor Extractor. |
173 | * @param processor Processor of query results. |
174 | * @return Number of objects queried. |
175 | */ |
176 | <V> int query(Predicate<T, S> selector, Extractor<T, V, S> extractor, QueryTask<V, PK, S> processor); |
177 | |
178 | /** |
179 | * Processes multiple values extracted from objects matching the predicate. |
180 | * @param selector Objects shall match this predicate. If null, all objects match. |
181 | * @param extractor Extractor |
182 | * @param valueSelector Values from matched objects shall match this predicate. If null, all values match. |
183 | * Value selectors are executed in separate tasks from extractor. |
184 | * Separation of value selection logic from value extraction logic makes |
185 | * sense if value selection logic is relatively heavy and parallelization of its |
186 | * execution will reduce overall query execution time. |
187 | * @param processor Processor of query results. |
188 | * @return Number of objects queried. |
189 | */ |
190 | <V> int queryMultiple(Predicate<T, S> selector, Extractor<T, Iterable<V>, S> extractor, Predicate<V, S> valueSelector, QueryTask<V, PK, S> processor); |
191 | |
192 | /** |
193 | * Retrieves values from objects matching the predicate. |
194 | * @param <V> |
195 | * @param selector Object selector. |
196 | * @param extractor Value extractor. If null, then object itself is returned. |
197 | * @param ordered If true, then returned result is ordered by comparator or by natural order if |
198 | * comparator is null. |
199 | * @param comparator Comparator to use for ordering. |
200 | * @return |
201 | */ |
202 | <V> Iterable<V> get(Predicate<T, S> selector, Extractor<T, V, S> extractor, boolean ordered, Comparator<V> comparator); |
203 | |
204 | /** |
205 | * Retrieves values from objects matching the predicate. Multiple values are retrieved from each object. |
206 | * @param <V> |
207 | * @param selector Objects shall match this predicate. If null, all objects match. |
208 | * @param extractor Value extractor. |
209 | * @param valueSelector Values from matched objects shall match this predicate. If null, all values match. |
210 | * Value selectors are executed in separate tasks from extractor. |
211 | * Separation of value selection logic from value extraction logic makes |
212 | * sense if value selection logic is relatively heavy and parallelization of its |
213 | * execution will reduce overall query execution time. |
214 | * @param ordered If true, then returned result is ordered by comparator or by natural order if |
215 | * comparator is null. |
216 | * @param comparator Comparator to use for ordering. |
217 | * @return |
218 | */ |
219 | <V> Iterable<V> getMultiple(Predicate<T, S> selector, Extractor<T, Iterable<V>, S> extractor, Predicate<V, S> valueSelector, boolean ordered, Comparator<V> comparator); |
220 | |
221 | /** |
222 | * Removes all entries from the store. |
223 | */ |
224 | void clear(); |
225 | |
226 | /** |
227 | * Removes specified object from the store. |
228 | * @param obj Object to remove. |
229 | * @return true if object was removed. |
230 | */ |
231 | boolean remove(T obj); |
232 | |
233 | /** |
234 | * Removes object by primary key. |
235 | * @param primaryKey |
236 | * @return |
237 | */ |
238 | boolean removeByPrimaryKey(PK primaryKey); |
239 | |
240 | /** |
241 | * Removes objects matching the predicate. |
242 | * @param predicate |
243 | * @return number of returned objects or -1 if number is unknown. |
244 | */ |
245 | int remove(Predicate<T, S> selector); |
246 | |
247 | |
248 | /** |
249 | * Task to update objects. |
250 | * @author Pavel Vlasov. |
251 | * |
252 | * @param <T> Object type. |
253 | */ |
254 | interface UpdateTask<T, PK, S extends Store<T,PK,S>> { |
255 | |
256 | /** |
257 | * Executes update. |
258 | * @param store Store to perform joins, sub-queries, etc. |
259 | * @param obj |
260 | * @param primaryKey |
261 | * @return Undo task to rollback changes done by this task or null if there are no changes. |
262 | */ |
263 | Runnable execute(S store, Handle<T,PK,S> handle); |
264 | } |
265 | |
266 | /** |
267 | * Task to perform processing on objects (without updating). |
268 | * @author Pavel Vlasov. |
269 | * |
270 | * @param <T> Object type. |
271 | */ |
272 | interface QueryTask<T, PK, S extends Store<?,PK,S>> { |
273 | |
274 | /** |
275 | * Performs querying. |
276 | * @param store Store to perform joins, sub-queries, etc. |
277 | * @param obj |
278 | * @param primaryKey |
279 | */ |
280 | void execute(S store, T obj, PK primaryKey); |
281 | } |
282 | |
283 | /** |
284 | * Updates objects matching the predicate. |
285 | * @param selector |
286 | * @param updater |
287 | * @return |
288 | */ |
289 | int update(Predicate<T, S> selector, UpdateTask<T, PK, S> updater); |
290 | |
291 | /** |
292 | * Adds index to the store to speed-up extraction operations. |
293 | * @param predicate Only store items matching the predicate are indexed. |
294 | * @param extractor Extractor of the index key. |
295 | * @param Index type. |
296 | * @param ordered If true index is ordered. |
297 | * @param comparator Comparator to use for ordering. If null, then natural order is used. |
298 | * @return A "mix" of Index sub-interfaces corresponding to the |
299 | * index creation parameters. |
300 | */ |
301 | <V> Index<T,PK,V,S> addIndex( |
302 | Predicate<T, S> predicate, |
303 | Extractor<T, V, S> extractor, |
304 | Index.Type type, |
305 | boolean ordered, |
306 | Comparator<V> comparator); |
307 | |
308 | /** |
309 | * If primary key is set, then the store shall use equals on the |
310 | * value returned from the primaryKeyExtractor |
311 | * instead of equals on the object to compare objects for removal and update (put). |
312 | * @param primaryKeyExtractor Primary key extractor. |
313 | * @throws IllegalStateException If primary key is already set. |
314 | */ |
315 | Extractor<T, PK, S> getPrimaryKeyExtractor(); |
316 | |
317 | /** |
318 | * Creates a view - a store which sees only objects matching the given selector. |
319 | * @param selector View selector. |
320 | * @param materialized If true, view elements are calculated at modify time instead of query time. |
321 | * @return Store which sees only objects matching give selector. The returned store is backed by the master store. |
322 | */ |
323 | S createView(Predicate<T, S> selector, ViewType viewType); |
324 | |
325 | /** |
326 | * Creates unmodifiable facade for this store. |
327 | * @return |
328 | */ |
329 | S createUnmodifiableFacade(); |
330 | |
331 | } |