Skip to content

Commit 06b44db

Browse files
jinmeiliaoKen Howe
authored and
Ken Howe
committed
GEODE-2936: Refactoring OrderByComparator and updating OrderByComparatorJUnitTest
This closes apache#580
1 parent 6267809 commit 06b44db

File tree

5 files changed

+134
-168
lines changed

5 files changed

+134
-168
lines changed

geode-core/src/main/java/org/apache/geode/cache/query/internal/CompiledSortCriterion.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public int getType() {
5656
* evaluates sort criteria in order by clause
5757
*/
5858
public Object evaluate(Object data, ExecutionContext context) {
59-
Object value = null;
59+
Object value;
6060
if (this.columnIndex > 0) {
6161
value = ((Object[]) data)[this.columnIndex];
6262
} else if (this.columnIndex == 0) {
@@ -113,7 +113,7 @@ private void substituteExpressionWithProjectionField(int columnIndex) {
113113
}
114114

115115
private CompiledValue getReconstructedExpression(String projAttribStr, ExecutionContext context)
116-
throws AmbiguousNameException, TypeMismatchException, NameResolutionException {
116+
throws TypeMismatchException, NameResolutionException {
117117
List<CompiledValue> expressions = PathUtils.collectCompiledValuesInThePath(expr, context);
118118
StringBuilder tempBuff = new StringBuilder();
119119
ListIterator<CompiledValue> listIter = expressions.listIterator(expressions.size());
@@ -180,7 +180,7 @@ private CompiledValue getReconstructedExpression(String projAttribStr, Execution
180180
}
181181

182182
boolean mapExpressionToProjectionField(List projAttrs, ExecutionContext context)
183-
throws AmbiguousNameException, TypeMismatchException, NameResolutionException {
183+
throws TypeMismatchException, NameResolutionException {
184184
boolean mappedColumn = false;
185185
this.originalCorrectedExpression = expr;
186186
if (projAttrs != null) {

geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparator.java

+85-123
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package org.apache.geode.cache.query.internal;
1616

1717
import java.util.Comparator;
18-
import java.util.Iterator;
1918
import java.util.List;
2019

2120
import org.apache.geode.cache.query.FunctionDomainException;
@@ -28,9 +27,8 @@
2827
import org.apache.geode.pdx.internal.PdxString;
2928

3029
/**
31-
* A generic comparator class which compares two Object/StructImpl according to their sort criterion
32-
* specified in order by clause
33-
*
30+
* A generic comparator class which compares two Object/StructImpl according to their sort criteria
31+
* specified in order by clause.
3432
*/
3533
public class OrderByComparator implements Comparator {
3634
private final ObjectType objType;
@@ -45,78 +43,44 @@ public OrderByComparator(List<CompiledSortCriterion> orderByAttrs, ObjectType ob
4543
}
4644

4745
/**
48-
* Yogesh : This methods evaluates sort criteria and returns a ArrayList of Object[] arrays of
49-
* evaluated criteria
46+
* This method evaluates sort criteria and returns an ArrayList of Object[] arrays of the
47+
* evaluated criteria.
5048
*
51-
* @param value
52-
* @return Object[]
49+
* @param value the criteria to be evaluated.
50+
* @return an Object array of Object arrays of the evaluated criteria.
5351
*/
5452
protected Object[] evaluateSortCriteria(Object value) {
55-
56-
CompiledSortCriterion csc;
5753
Object[] array = null;
5854
if (orderByAttrs != null) {
5955
array = new Object[orderByAttrs.size()];
60-
Iterator orderiter = orderByAttrs.iterator();
6156
int i = 0;
62-
while (orderiter.hasNext()) {
63-
csc = (CompiledSortCriterion) orderiter.next();
64-
Object[] arr = new Object[2];
65-
arr[0] = csc.evaluate(value, context);
66-
arr[1] = Boolean.valueOf(csc.getCriterion());
57+
for (CompiledSortCriterion csc : orderByAttrs) {
58+
Object[] arr = {csc.evaluate(value, context), csc.getCriterion()};
6759
array[i++] = arr;
6860
}
69-
7061
}
7162
return array;
7263
}
7364

65+
/**
66+
* This method evaluates sort criteria and returns the resulting integer value of comparing the
67+
* two objects passed into it based on these criteria.
68+
*
69+
* @param value1 the first object to be compared.
70+
* @param value2 the second object to be compared.
71+
* @return a negative integer, zero, or a positive integer if the first argument is less than,
72+
* equal to, or greater than the second, based on the evaluated sort criteria.
73+
*/
7474
protected int evaluateSortCriteria(Object value1, Object value2) {
7575
int result = -1;
76-
CompiledSortCriterion csc;
7776
if (orderByAttrs != null) {
78-
Iterator orderiter = orderByAttrs.iterator();
79-
while (orderiter.hasNext()) {
80-
csc = (CompiledSortCriterion) orderiter.next();
77+
for (CompiledSortCriterion csc : orderByAttrs) {
8178
Object sortCriteriaForValue1 = csc.evaluate(value1, context);
8279
Object sortCriteriaForValue2 = csc.evaluate(value2, context);
83-
84-
if (sortCriteriaForValue1 == null || sortCriteriaForValue2 == null) {
85-
if (sortCriteriaForValue1 == null) {
86-
result = (sortCriteriaForValue2 == null ? 0 : -1);
87-
} else {
88-
result = 1;
89-
}
90-
} else if (sortCriteriaForValue1 == QueryService.UNDEFINED
91-
|| sortCriteriaForValue2 == QueryService.UNDEFINED) {
92-
if (sortCriteriaForValue1 == QueryService.UNDEFINED) {
93-
result = (sortCriteriaForValue2 == QueryService.UNDEFINED ? 0 : -1);
94-
} else {
95-
result = 1;
96-
}
97-
} else {
98-
if (sortCriteriaForValue1 instanceof Number && sortCriteriaForValue2 instanceof Number) {
99-
double diff = ((Number) sortCriteriaForValue1).doubleValue()
100-
- ((Number) sortCriteriaForValue2).doubleValue();
101-
result = diff > 0 ? 1 : diff < 0 ? -1 : 0;
102-
} else {
103-
if (sortCriteriaForValue1 instanceof PdxString
104-
&& sortCriteriaForValue2 instanceof String) {
105-
sortCriteriaForValue2 = new PdxString((String) sortCriteriaForValue2);
106-
} else if (sortCriteriaForValue2 instanceof PdxString
107-
&& sortCriteriaForValue1 instanceof String) {
108-
sortCriteriaForValue1 = new PdxString((String) sortCriteriaForValue1);
109-
}
110-
result = ((Comparable) sortCriteriaForValue1).compareTo(sortCriteriaForValue2);
111-
}
112-
113-
}
114-
115-
if (result == 0) {
116-
continue;
117-
} else {
118-
if (Boolean.valueOf(csc.getCriterion())) {
119-
result = (result * (-1));
80+
result = compareHelperMethod(sortCriteriaForValue1, sortCriteriaForValue2);
81+
if (result != 0) {
82+
if (csc.getCriterion()) {
83+
result *= -1;
12084
}
12185
break;
12286
}
@@ -137,89 +101,35 @@ protected int evaluateSortCriteria(Object value1, Object value2) {
137101
* Comparator.
138102
*/
139103
public int compare(Object obj1, Object obj2) {
140-
int result = -1;
104+
int result;
141105
if (obj1 == null && obj2 == null) {
142106
return 0;
143107
}
144108
assert !(obj1 instanceof VMCachedDeserializable || obj2 instanceof VMCachedDeserializable);
145-
146109
if ((this.objType.isStructType() && obj1 instanceof Object[] && obj2 instanceof Object[])
147-
|| !this.objType.isStructType()) { // obj1 instanceof Object && obj2
148-
// instanceof Object){
149-
if ((result = evaluateSortCriteria(obj1, obj2)) != 0) {
110+
|| !this.objType.isStructType()) {
111+
if (((result = evaluateSortCriteria(obj1, obj2)) != 0) && (orderByAttrs != null)) {
150112
return result;
151113
}
152-
153-
QueryObserver observer = QueryObserverHolder.getInstance();
154-
if (observer != null) {
155-
observer.orderByColumnsEqual();
114+
if (QueryObserverHolder.getInstance() != null) {
115+
QueryObserverHolder.getInstance().orderByColumnsEqual();
156116
}
157-
// The comparable fields are equal, so we check if the overall keys are
158-
// equal or not
117+
// Comparable fields are equal - check if overall keys are equal
159118
if (this.objType.isStructType()) {
160119
int i = 0;
161120
for (Object o1 : (Object[]) obj1) {
162121
Object o2 = ((Object[]) obj2)[i++];
163-
164-
// Check for null value.
165-
if (o1 == null || o2 == null) {
166-
if (o1 == null) {
167-
if (o2 == null) {
168-
continue;
169-
}
170-
return -1;
171-
} else {
172-
return 1;
173-
}
174-
} else if (o1 == QueryService.UNDEFINED || o2 == QueryService.UNDEFINED) {
175-
if (o1 == QueryService.UNDEFINED) {
176-
if (o2 == QueryService.UNDEFINED) {
177-
continue;
178-
}
179-
return -1;
180-
} else {
181-
return 1;
182-
}
183-
}
184-
185-
if (o1 instanceof Comparable) {
186-
final int rslt;
187-
if (o1 instanceof Number && o2 instanceof Number) {
188-
double diff = ((Number) o1).doubleValue() - ((Number) o2).doubleValue();
189-
rslt = diff > 0 ? 1 : diff < 0 ? -1 : 0;
190-
} else {
191-
if (o1 instanceof PdxString && o2 instanceof String) {
192-
o2 = new PdxString((String) o2);
193-
} else if (o2 instanceof PdxString && o1 instanceof String) {
194-
o1 = new PdxString((String) o1);
195-
}
196-
rslt = ((Comparable) o1).compareTo(o2);
197-
}
198-
if (rslt == 0) {
199-
continue;
200-
} else {
201-
return rslt;
202-
}
203-
} else if (!o1.equals(o2)) {
204-
return -1;
122+
result = compareHelperMethod(o1, o2);
123+
if (result != 0) {
124+
return result;
205125
}
206126
}
207127
return 0;
208128
} else {
209-
if (obj1 instanceof PdxString && obj2 instanceof String) {
210-
obj2 = new PdxString((String) obj2);
211-
} else if (obj2 instanceof PdxString && obj1 instanceof String) {
212-
obj1 = new PdxString((String) obj1);
213-
}
214-
215-
if (obj1 instanceof Comparable) {
216-
return ((Comparable) obj1).compareTo(obj2);
217-
} else {
218-
return obj1.equals(obj2) ? 0 : -1;
219-
}
129+
return compareTwoStrings(obj1, obj2);
220130
}
221131
}
222-
return -1;
132+
throw new ClassCastException(); // throw exception if args can't be compared w/this comparator
223133
}
224134

225135
void addEvaluatedSortCriteria(Object row, ExecutionContext context)
@@ -228,4 +138,56 @@ void addEvaluatedSortCriteria(Object row, ExecutionContext context)
228138
// No op
229139
}
230140

141+
private int compareHelperMethod(Object obj1, Object obj2) {
142+
if (obj1 == null || obj2 == null) {
143+
return compareIfOneOrMoreNull(obj1, obj2);
144+
} else if (obj1 == QueryService.UNDEFINED || obj2 == QueryService.UNDEFINED) {
145+
return compareIfOneOrMoreQueryServiceUndefined(obj1, obj2);
146+
} else {
147+
return compareTwoObjects(obj1, obj2);
148+
}
149+
}
150+
151+
private int compareIfOneOrMoreNull(Object obj1, Object obj2) {
152+
if (obj1 == null) {
153+
return obj2 == null ? 0 : -1;
154+
} else {
155+
return 1;
156+
}
157+
}
158+
159+
private int compareIfOneOrMoreQueryServiceUndefined(Object obj1, Object obj2) {
160+
if (obj1 == QueryService.UNDEFINED) {
161+
return obj2 == QueryService.UNDEFINED ? 0 : -1;
162+
} else {
163+
return 1;
164+
}
165+
}
166+
167+
private int compareTwoObjects(Object obj1, Object obj2) {
168+
if (obj1 instanceof Number && obj2 instanceof Number) {
169+
return compareTwoNumbers(obj1, obj2);
170+
} else {
171+
return compareTwoStrings(obj1, obj2);
172+
}
173+
}
174+
175+
private int compareTwoNumbers(Object obj1, Object obj2) {
176+
Number num1 = (Number) obj1;
177+
Number num2 = (Number) obj2;
178+
return Double.compare(num1.doubleValue(), num2.doubleValue());
179+
}
180+
181+
private int compareTwoStrings(Object obj1, Object obj2) {
182+
if (obj1 instanceof PdxString && obj2 instanceof String) {
183+
obj2 = new PdxString((String) obj2);
184+
} else if (obj2 instanceof PdxString && obj1 instanceof String) {
185+
obj1 = new PdxString((String) obj1);
186+
}
187+
if (obj1 instanceof Comparable) {
188+
return ((Comparable) obj1).compareTo(obj2);
189+
} else {
190+
return obj1.equals(obj2) ? 0 : -1;
191+
}
192+
}
231193
}

geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparatorUnmapped.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
*/
1515
package org.apache.geode.cache.query.internal;
1616

17-
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
18-
1917
import java.util.HashMap;
2018
import java.util.Iterator;
2119
import java.util.List;
2220
import java.util.Map;
2321

22+
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
23+
2424
import org.apache.geode.cache.query.FunctionDomainException;
2525
import org.apache.geode.cache.query.NameResolutionException;
2626
import org.apache.geode.cache.query.QueryInvocationTargetException;
@@ -113,7 +113,7 @@ public int evaluateSortCriteria(Object obj1, Object obj2) {
113113

114114
@Override
115115
protected Object[] evaluateSortCriteria(Object row) {
116-
return (Object[]) orderByMap.get(row);
116+
return orderByMap.get(row);
117117
}
118118

119119

geode-core/src/test/java/org/apache/geode/cache/query/functional/StructSetOrResultsSet.java

+7-6
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
*/
1919
package org.apache.geode.cache.query.functional;
2020

21-
import static org.junit.Assert.*;
21+
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.assertTrue;
23+
import static org.junit.Assert.fail;
2224

2325
import java.lang.reflect.Field;
2426
import java.lang.reflect.InvocationTargetException;
@@ -93,8 +95,8 @@ public void CompareQueryResultsWithoutAndWithIndexes(Object[][] r, int len, Stri
9395
public void CompareQueryResultsWithoutAndWithIndexes(Object[][] r, int len, boolean checkOrder,
9496
String queries[]) {
9597

96-
Collection coll1 = null;
97-
Collection coll2 = null;
98+
Collection coll1;
99+
Collection coll2;
98100
for (int j = 0; j < len; j++) {
99101
checkSelectResultTypes((SelectResults) r[j][0], (SelectResults) r[j][1], queries[j]);
100102
checkResultSizes((SelectResults) r[j][0], (SelectResults) r[j][1], queries[j]);
@@ -113,7 +115,7 @@ public void CompareQueryResultsWithoutAndWithIndexes(Object[][] r, int len, bool
113115
public void compareExternallySortedQueriesWithOrderBy(String[] queries, Object[][] baseResults)
114116
throws Exception {
115117
for (int i = 0; i < queries.length; i++) {
116-
Query q = null;
118+
Query q;
117119
try {
118120
String query = queries[i];
119121
int indexOfOrderBy = query.indexOf("order ");
@@ -124,7 +126,7 @@ public void compareExternallySortedQueriesWithOrderBy(String[] queries, Object[]
124126
int unorderedResultsSize = ((SelectResults) baseResults[i][1]).size();
125127
if (unorderedResultsSize == 0) {
126128
fail(
127-
"The test results size is 0 , it possibly is not validating anything. rewrite the test");
129+
"The test results size is 0. It may not be validating anything. Please rewrite the test.");
128130
}
129131
Wrapper wrapper = getOrderByComparatorAndLimitForQuery(queries[i], unorderedResultsSize);
130132
if (wrapper.validationLevel != ValidationLevel.NONE) {
@@ -230,7 +232,6 @@ public Wrapper getOrderByComparatorAndLimitForQuery(String orderByQuery, int uno
230232
@Override
231233
public int compare(Struct o1, Struct o2) {
232234
return obc.compare(o1.getFieldValues(), o2.getFieldValues());
233-
234235
}
235236
};
236237
}

0 commit comments

Comments
 (0)