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.Collections;
27 import java.util.Comparator;
28 import java.util.Iterator;
29 import java.util.LinkedList;
30 import java.util.List;
31 import org.modeshape.graph.query.QueryContext;
32 import org.modeshape.graph.query.QueryResults.Columns;
33
34
35
36 public class ExceptComponent extends SetOperationComponent {
37
38 private final Comparator<Object[]> comparator;
39
40 public ExceptComponent( QueryContext context,
41 Columns columns,
42 Iterable<ProcessingComponent> sources,
43 boolean alreadySorted,
44 boolean all ) {
45 super(context, columns, sources, alreadySorted, all);
46 this.comparator = createSortComparator(context, columns);
47 }
48
49
50
51
52
53
54 @Override
55 public List<Object[]> execute() {
56 Iterator<ProcessingComponent> sources = sources().iterator();
57 if (!sources.hasNext()) return emptyTuples();
58
59
60
61 List<List<Object[]>> allTuples = new LinkedList<List<Object[]>>();
62 while (sources.hasNext()) {
63 List<Object[]> tuples = sources.next().execute();
64 if (tuples == null) continue;
65 if (tuples.isEmpty()) return emptyTuples();
66 allTuples.add(tuples);
67 }
68 if (allTuples.isEmpty()) return emptyTuples();
69 if (allTuples.size() == 1) return allTuples.get(0);
70
71 Collections.sort(allTuples, new Comparator<List<Object[]>>() {
72 public int compare( List<Object[]> tuples1,
73 List<Object[]> tuples2 ) {
74 return tuples1.size() - tuples2.size();
75 }
76 });
77
78
79 Iterator<List<Object[]>> iter = allTuples.iterator();
80 List<Object[]> tuples = iter.next();
81 assert iter.hasNext();
82
83 while (iter.hasNext()) {
84 List<Object[]> next = iter.next();
85
86 Iterator<Object[]> tupleIter = tuples.iterator();
87 Iterator<Object[]> nextIter = next.iterator();
88
89 Object[] tuple1 = tupleIter.next();
90 Object[] tuple2 = nextIter.next();
91 while (true) {
92 int comparison = comparator.compare(tuple1, tuple2);
93 if (comparison == 0) {
94
95 tupleIter.remove();
96 continue;
97 }
98
99 if (comparison < 0) {
100
101 if (!tupleIter.hasNext()) {
102
103 break;
104 }
105 tuple1 = tupleIter.next();
106 continue;
107 }
108 assert comparison > 0;
109
110 if (!nextIter.hasNext()) {
111
112 break;
113 }
114 tuple2 = nextIter.next();
115 continue;
116 }
117 }
118
119 removeDuplicatesIfRequested(tuples);
120
121 return tuples;
122 }
123 }