1 | package com.hammurapi.eventbus; |
2 | |
3 | import java.lang.reflect.Array; |
4 | import java.util.Arrays; |
5 | import java.util.HashSet; |
6 | import java.util.Map; |
7 | import java.util.Set; |
8 | |
9 | import com.hammurapi.eventbus.AbstractEventBus.Handle; |
10 | import com.hammurapi.extract.ComparisonResult; |
11 | import com.hammurapi.extract.Extractor; |
12 | import com.hammurapi.extract.Predicate; |
13 | |
14 | public class MappedHandlePredicate<T, P extends Comparable<P>, C, K, H extends EventBus.Handle<T, P, C>, S extends EventStore<T,P,C,H,S>> implements Predicate<Handle<T,P,C,K>[], CompositeContext<T, P, C, K, H, S>> { |
15 | |
16 | private Predicate<T, C> target; |
17 | private Mapper<Handle<T,P,C,K>>[] mappers; |
18 | private int maxIndex; |
19 | private Set<Integer> parameterIndices = new HashSet<Integer>(); |
20 | private Class<T> targetClass; |
21 | |
22 | public MappedHandlePredicate(Predicate<T, C> target, Mapper<Handle<T,P,C,K>>[] mappers, Class<T> targetClass) { |
23 | this.target = target; |
24 | this.targetClass = targetClass; |
25 | this.mappers = mappers; |
26 | for (Integer idx:target.parameterIndices()) { |
27 | if (idx>maxIndex) { |
28 | maxIndex = idx; |
29 | } |
30 | for (int i=0; i<mappers.length; ++i) { |
31 | if (mappers[i].mapsTo(idx)) { |
32 | parameterIndices.add(i); |
33 | } |
34 | } |
35 | } |
36 | } |
37 | |
38 | @SuppressWarnings("unchecked") |
39 | @Override |
40 | public Boolean extract( |
41 | CompositeContext<T, P, C, K, H, S> context, |
42 | Map<CompositeContext<T, P, C, K, H, S>, Map<Extractor<Handle<T,P,C,K>[], ? super Boolean, CompositeContext<T, P, C, K, H, S>>, ? super Boolean>> cache, |
43 | Handle<T,P,C,K>[]... handles) { |
44 | Handle<T,P,C,K>[] predicateInputHandles = new Handle[maxIndex+1]; |
45 | for (int i=0; i<mappers.length; ++i) { |
46 | mappers[i].map(handles[i], predicateInputHandles); |
47 | } |
48 | |
49 | T[] predicateInput = (T[]) Array.newInstance(targetClass, maxIndex+1); |
50 | |
51 | for (int i=0; i<predicateInputHandles.length; ++i) { |
52 | Handle<T,P,C,K> handle = predicateInputHandles[i]; |
53 | if (handle!=null) { |
54 | if (!handle.isValid()) { |
55 | return Boolean.FALSE; |
56 | } |
57 | predicateInput[i] = handle.getEvent(); |
58 | } |
59 | } |
60 | |
61 | // TODO - associate cache for a tuple with Handle[] using a special class instead of |
62 | // handle array. |
63 | return target.extract(context.getHandlerContext(), null, predicateInput); |
64 | } |
65 | |
66 | @Override |
67 | public ComparisonResult compareTo(Extractor<Handle<T,P,C,K>[], Boolean, CompositeContext<T, P, C, K, H, S>> otherPredicate) { |
68 | // TODO Implement proper comparison for merging of join networks. |
69 | return ComparisonResult.NOT_EQUAL_NM; |
70 | } |
71 | |
72 | @Override |
73 | public boolean isContextDependent() { |
74 | return target.isContextDependent(); |
75 | } |
76 | |
77 | @Override |
78 | public Set<Integer> parameterIndices() { |
79 | return parameterIndices; |
80 | } |
81 | |
82 | @Override |
83 | public double getCost() { |
84 | return target.getCost(); |
85 | } |
86 | |
87 | @Override |
88 | public String toString() { |
89 | return "MappedHandlePredicate [target=" + target + ", mappers=" |
90 | + Arrays.toString(mappers) + ", maxIndex=" + maxIndex |
91 | + ", parameterIndices=" + parameterIndices + ", targetClass=" |
92 | + targetClass + "]"; |
93 | } |
94 | |
95 | } |