1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.graph.query.process;
25
26 import java.util.Comparator;
27 import java.util.Iterator;
28 import java.util.LinkedList;
29 import java.util.List;
30 import org.modeshape.graph.query.QueryContext;
31 import org.modeshape.graph.query.QueryResults.Columns;
32
33
34
35 public abstract class SetOperationComponent extends ProcessingComponent {
36
37 private final Iterable<ProcessingComponent> sources;
38 protected final Comparator<Object[]> removeDuplicatesComparator;
39
40 protected SetOperationComponent( QueryContext context,
41 Columns columns,
42 Iterable<ProcessingComponent> sources,
43 boolean alreadySorted,
44 boolean all ) {
45 super(context, columns);
46 assert unionCompatible(columns, sources);
47 this.sources = wrapWithLocationOrdering(sources, alreadySorted);
48 this.removeDuplicatesComparator = all ? null : createSortComparator(context, columns);
49 }
50
51 protected static boolean unionCompatible( Columns columns,
52 Iterable<ProcessingComponent> sources ) {
53 for (ProcessingComponent source : sources) {
54 if (!columns.isUnionCompatible(source.getColumns())) return false;
55 }
56 return true;
57 }
58
59
60
61
62 protected Iterable<ProcessingComponent> sources() {
63 return sources;
64 }
65
66
67
68
69
70
71
72
73
74 protected static Iterable<ProcessingComponent> wrapWithLocationOrdering( Iterable<ProcessingComponent> sources,
75 boolean alreadySorted ) {
76 assert sources != null;
77 if (alreadySorted) return sources;
78 List<ProcessingComponent> wrapped = new LinkedList<ProcessingComponent>();
79 for (ProcessingComponent source : sources) {
80 wrapped.add(new SortLocationsComponent(source));
81 }
82 return wrapped;
83 }
84
85 protected void removeDuplicatesIfRequested( List<Object[]> tuples ) {
86 if (removeDuplicatesComparator != null) {
87 Iterator<Object[]> iter = tuples.iterator();
88 Object[] previous = null;
89 while (iter.hasNext()) {
90 Object[] current = iter.next();
91 if (previous != null && removeDuplicatesComparator.compare(previous, current) == 0) {
92 iter.remove();
93 } else {
94 previous = current;
95 }
96 }
97 }
98 }
99 }