1
1
package org .dataloader ;
2
2
3
3
import org .dataloader .annotations .PublicApi ;
4
+ import org .dataloader .registries .DispatchPredicate ;
4
5
import org .dataloader .stats .Statistics ;
5
6
6
7
import java .util .ArrayList ;
21
22
@ PublicApi
22
23
public class DataLoaderRegistry {
23
24
protected final Map <String , DataLoader <?, ?>> dataLoaders = new ConcurrentHashMap <>();
25
+ protected final Map <DataLoader <?, ?>, DispatchPredicate > dataLoaderPredicates = new ConcurrentHashMap <>();
26
+ protected final DispatchPredicate dispatchPredicate ;
27
+
24
28
25
29
public DataLoaderRegistry () {
30
+ this .dispatchPredicate = DispatchPredicate .DISPATCH_ALWAYS ;
26
31
}
27
32
28
- private DataLoaderRegistry (Builder builder ) {
33
+ protected DataLoaderRegistry (Builder <?> builder ) {
29
34
this .dataLoaders .putAll (builder .dataLoaders );
35
+ this .dispatchPredicate = builder .dispatchPredicate ;
30
36
}
31
37
32
38
@@ -43,6 +49,21 @@ public DataLoaderRegistry register(String key, DataLoader<?, ?> dataLoader) {
43
49
return this ;
44
50
}
45
51
52
+ /**
53
+ * This will register a new dataloader and dispatch predicate associated with that data loader
54
+ *
55
+ * @param key the key to put the data loader under
56
+ * @param dataLoader the data loader to register
57
+ * @param dispatchPredicate the dispatch predicate to associate with this data loader
58
+ *
59
+ * @return this registry
60
+ */
61
+ public DataLoaderRegistry register (String key , DataLoader <?, ?> dataLoader , DispatchPredicate dispatchPredicate ) {
62
+ dataLoaders .put (key , dataLoader );
63
+ dataLoaderPredicates .put (dataLoader , dispatchPredicate );
64
+ return this ;
65
+ }
66
+
46
67
/**
47
68
* Computes a data loader if absent or return it if it was
48
69
* already registered at that key.
@@ -76,6 +97,8 @@ public DataLoaderRegistry combine(DataLoaderRegistry registry) {
76
97
77
98
this .dataLoaders .forEach (combined ::register );
78
99
registry .dataLoaders .forEach (combined ::register );
100
+ combined .dataLoaderPredicates .putAll (this .dataLoaderPredicates );
101
+ combined .dataLoaderPredicates .putAll (registry .dataLoaderPredicates );
79
102
return combined ;
80
103
}
81
104
@@ -101,7 +124,10 @@ public DataLoaderRegistry combine(DataLoaderRegistry registry) {
101
124
* @return this registry
102
125
*/
103
126
public DataLoaderRegistry unregister (String key ) {
104
- dataLoaders .remove (key );
127
+ DataLoader <?, ?> dataLoader = dataLoaders .remove (key );
128
+ if (dataLoader != null ) {
129
+ dataLoaderPredicates .remove (dataLoader );
130
+ }
105
131
return this ;
106
132
}
107
133
@@ -131,7 +157,7 @@ public Set<String> getKeys() {
131
157
* {@link org.dataloader.DataLoader}s
132
158
*/
133
159
public void dispatchAll () {
134
- getDataLoaders (). forEach ( DataLoader :: dispatch );
160
+ dispatchAllWithCount ( );
135
161
}
136
162
137
163
/**
@@ -142,8 +168,12 @@ public void dispatchAll() {
142
168
*/
143
169
public int dispatchAllWithCount () {
144
170
int sum = 0 ;
145
- for (DataLoader <?, ?> dataLoader : getDataLoaders ()) {
146
- sum += dataLoader .dispatchWithCounts ().getKeysCount ();
171
+ for (Map .Entry <String , DataLoader <?, ?>> entry : dataLoaders .entrySet ()) {
172
+ DataLoader <?, ?> dataLoader = entry .getValue ();
173
+ String key = entry .getKey ();
174
+ if (shouldDispatch (key , dataLoader )) {
175
+ sum += dataLoader .dispatchWithCounts ().getKeysCount ();
176
+ }
147
177
}
148
178
return sum ;
149
179
}
@@ -154,12 +184,59 @@ public int dispatchAllWithCount() {
154
184
*/
155
185
public int dispatchDepth () {
156
186
int totalDispatchDepth = 0 ;
157
- for (DataLoader <?, ?> dataLoader : getDataLoaders ()) {
158
- totalDispatchDepth += dataLoader .dispatchDepth ();
187
+ for (Map .Entry <String , DataLoader <?, ?>> entry : dataLoaders .entrySet ()) {
188
+ DataLoader <?, ?> dataLoader = entry .getValue ();
189
+ String key = entry .getKey ();
190
+ if (shouldDispatch (key , dataLoader )) {
191
+ totalDispatchDepth += dataLoader .dispatchDepth ();
192
+ }
159
193
}
160
194
return totalDispatchDepth ;
161
195
}
162
196
197
+ /**
198
+ * This will immediately dispatch the {@link DataLoader}s in the registry
199
+ * without testing the predicate
200
+ */
201
+ public void dispatchAllImmediately () {
202
+ dispatchAllWithCountImmediately ();
203
+ }
204
+
205
+ /**
206
+ * This will immediately dispatch the {@link DataLoader}s in the registry
207
+ * without testing the predicate
208
+ *
209
+ * @return total number of entries that were dispatched from registered {@link org.dataloader.DataLoader}s.
210
+ */
211
+ public int dispatchAllWithCountImmediately () {
212
+ int sum = 0 ;
213
+ for (Map .Entry <String , DataLoader <?, ?>> entry : dataLoaders .entrySet ()) {
214
+ DataLoader <?, ?> dataLoader = entry .getValue ();
215
+ sum += dataLoader .dispatchWithCounts ().getKeysCount ();
216
+ }
217
+ return sum ;
218
+ }
219
+
220
+
221
+ /**
222
+ * Returns true if the dataloader has a predicate which returned true, OR the overall
223
+ * registry predicate returned true.
224
+ *
225
+ * @param dataLoaderKey the key in the dataloader map
226
+ * @param dataLoader the dataloader
227
+ *
228
+ * @return true if it should dispatch
229
+ */
230
+ protected boolean shouldDispatch (String dataLoaderKey , DataLoader <?, ?> dataLoader ) {
231
+ DispatchPredicate dispatchPredicate = dataLoaderPredicates .get (dataLoader );
232
+ if (dispatchPredicate != null ) {
233
+ if (dispatchPredicate .test (dataLoaderKey , dataLoader )) {
234
+ return true ;
235
+ }
236
+ }
237
+ return this .dispatchPredicate .test (dataLoaderKey , dataLoader );
238
+ }
239
+
163
240
/**
164
241
* @return a combined set of statistics for all data loaders in this registry presented
165
242
* as the sum of all their statistics
@@ -175,13 +252,22 @@ public Statistics getStatistics() {
175
252
/**
176
253
* @return A builder of {@link DataLoaderRegistry}s
177
254
*/
178
- public static Builder newRegistry () {
255
+ public static Builder <?> newRegistry () {
256
+ //noinspection rawtypes
179
257
return new Builder ();
180
258
}
181
259
182
- public static class Builder {
260
+ public static class Builder < B extends Builder < B >> {
183
261
184
262
private final Map <String , DataLoader <?, ?>> dataLoaders = new HashMap <>();
263
+ private final Map <DataLoader <?, ?>, DispatchPredicate > dataLoaderPredicates = new ConcurrentHashMap <>();
264
+
265
+ private DispatchPredicate dispatchPredicate = DispatchPredicate .DISPATCH_ALWAYS ;
266
+
267
+ private B self () {
268
+ //noinspection unchecked
269
+ return (B ) this ;
270
+ }
185
271
186
272
/**
187
273
* This will register a new dataloader
@@ -191,22 +277,51 @@ public static class Builder {
191
277
*
192
278
* @return this builder for a fluent pattern
193
279
*/
194
- public Builder register (String key , DataLoader <?, ?> dataLoader ) {
280
+ public B register (String key , DataLoader <?, ?> dataLoader ) {
195
281
dataLoaders .put (key , dataLoader );
196
- return this ;
282
+ return self () ;
197
283
}
198
284
199
285
/**
200
- * This will combine together the data loaders in this builder with the ones
286
+ * This will register a new dataloader with a specific {@link DispatchPredicate}
287
+ *
288
+ * @param key the key to put the data loader under
289
+ * @param dataLoader the data loader to register
290
+ * @param dispatchPredicate the dispatch predicate
291
+ *
292
+ * @return this builder for a fluent pattern
293
+ */
294
+ public B register (String key , DataLoader <?, ?> dataLoader , DispatchPredicate dispatchPredicate ) {
295
+ register (key , dataLoader );
296
+ dataLoaderPredicates .put (dataLoader , dispatchPredicate );
297
+ return self ();
298
+ }
299
+
300
+ /**
301
+ * This will combine the data loaders in this builder with the ones
201
302
* from a previous {@link DataLoaderRegistry}
202
303
*
203
304
* @param otherRegistry the previous {@link DataLoaderRegistry}
204
305
*
205
306
* @return this builder for a fluent pattern
206
307
*/
207
- public Builder registerAll (DataLoaderRegistry otherRegistry ) {
308
+ public B registerAll (DataLoaderRegistry otherRegistry ) {
208
309
dataLoaders .putAll (otherRegistry .dataLoaders );
209
- return this ;
310
+ dataLoaderPredicates .putAll (otherRegistry .dataLoaderPredicates );
311
+ return self ();
312
+ }
313
+
314
+ /**
315
+ * This sets a predicate on the {@link DataLoaderRegistry} that will control
316
+ * whether all {@link DataLoader}s in the {@link DataLoaderRegistry }should be dispatched.
317
+ *
318
+ * @param dispatchPredicate the predicate
319
+ *
320
+ * @return this builder for a fluent pattern
321
+ */
322
+ public B dispatchPredicate (DispatchPredicate dispatchPredicate ) {
323
+ this .dispatchPredicate = dispatchPredicate ;
324
+ return self ();
210
325
}
211
326
212
327
/**
0 commit comments