Repository: geode Updated Branches: refs/heads/develop 52dadee32 -> b3fc0c814
GEODE-2587: Refactored the OrderByComparator's compare method * This prevents creation of extra data structures like arrays of arrays * Hence let number of GC, faster execution of queries with ORDER BY This closes #517 Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/b3fc0c81 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/b3fc0c81 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/b3fc0c81 Branch: refs/heads/develop Commit: b3fc0c814948cdfeb3181fcb57d07886aba8691e Parents: 52dadee Author: nabarunnag <n...@cs.wisc.edu> Authored: Sun May 14 22:19:26 2017 -0700 Committer: nabarun <n...@pivotal.io> Committed: Wed May 17 16:49:31 2017 -0700 ---------------------------------------------------------------------- .../cache/query/internal/OrderByComparator.java | 212 ++++++++++--------- .../internal/OrderByComparatorUnmapped.java | 60 ++++++ 2 files changed, 170 insertions(+), 102 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/b3fc0c81/geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparator.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparator.java index 3fdb11b..59eb493 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparator.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparator.java @@ -71,6 +71,60 @@ public class OrderByComparator implements Comparator { return array; } + protected int evaluateSortCriteria(Object value1, Object value2) { + int result = -1; + CompiledSortCriterion csc; + if (orderByAttrs != null) { + Iterator orderiter = orderByAttrs.iterator(); + while (orderiter.hasNext()) { + csc = (CompiledSortCriterion) orderiter.next(); + Object sortCriteriaForValue1 = csc.evaluate(value1, context); + Object sortCriteriaForValue2 = csc.evaluate(value2, context); + + if (sortCriteriaForValue1 == null || sortCriteriaForValue2 == null) { + if (sortCriteriaForValue1 == null) { + result = (sortCriteriaForValue2 == null ? 0 : -1); + } else { + result = 1; + } + } else if (sortCriteriaForValue1 == QueryService.UNDEFINED + || sortCriteriaForValue2 == QueryService.UNDEFINED) { + if (sortCriteriaForValue1 == QueryService.UNDEFINED) { + result = (sortCriteriaForValue2 == QueryService.UNDEFINED ? 0 : -1); + } else { + result = 1; + } + } else { + if (sortCriteriaForValue1 instanceof Number && sortCriteriaForValue2 instanceof Number) { + double diff = ((Number) sortCriteriaForValue1).doubleValue() + - ((Number) sortCriteriaForValue2).doubleValue(); + result = diff > 0 ? 1 : diff < 0 ? -1 : 0; + } else { + if (sortCriteriaForValue1 instanceof PdxString + && sortCriteriaForValue2 instanceof String) { + sortCriteriaForValue2 = new PdxString((String) sortCriteriaForValue2); + } else if (sortCriteriaForValue2 instanceof PdxString + && sortCriteriaForValue1 instanceof String) { + sortCriteriaForValue1 = new PdxString((String) sortCriteriaForValue1); + } + result = ((Comparable) sortCriteriaForValue1).compareTo(sortCriteriaForValue2); + } + + } + + if (result == 0) { + continue; + } else { + if (Boolean.valueOf(csc.getCriterion())) { + result = (result * (-1)); + } + break; + } + } + } + return result; + } + /** * Compares its two arguments for order. Returns a negative integer, zero, or a positive integer * as the first argument is less than, equal to, or greater than the second. @@ -92,122 +146,76 @@ public class OrderByComparator implements Comparator { if ((this.objType.isStructType() && obj1 instanceof Object[] && obj2 instanceof Object[]) || !this.objType.isStructType()) { // obj1 instanceof Object && obj2 // instanceof Object){ - Object[] list1 = this.evaluateSortCriteria(obj1); - Object[] list2 = this.evaluateSortCriteria(obj2); + if ((result = evaluateSortCriteria(obj1, obj2)) != 0) { + return result; + } - if (list1.length != list2.length) { - Support.assertionFailed("Error Occurred due to improper sort criteria evaluation "); - } else { - for (int i = 0; i < list1.length; i++) { - Object arr1[] = (Object[]) list1[i]; - Object arr2[] = (Object[]) list2[i]; - // check for null. - if (arr1[0] == null || arr2[0] == null) { - if (arr1[0] == null) { - result = (arr2[0] == null ? 0 : -1); + QueryObserver observer = QueryObserverHolder.getInstance(); + if (observer != null) { + observer.orderByColumnsEqual(); + } + // The comparable fields are equal, so we check if the overall keys are + // equal or not + if (this.objType.isStructType()) { + int i = 0; + for (Object o1 : (Object[]) obj1) { + Object o2 = ((Object[]) obj2)[i++]; + + // Check for null value. + if (o1 == null || o2 == null) { + if (o1 == null) { + if (o2 == null) { + continue; + } + return -1; } else { - result = 1; + return 1; } - } else if (arr1[0] == QueryService.UNDEFINED || arr2[0] == QueryService.UNDEFINED) { - if (arr1[0] == QueryService.UNDEFINED) { - result = (arr2[0] == QueryService.UNDEFINED ? 0 : -1); + } else if (o1 == QueryService.UNDEFINED || o2 == QueryService.UNDEFINED) { + if (o1 == QueryService.UNDEFINED) { + if (o2 == QueryService.UNDEFINED) { + continue; + } + return -1; } else { - result = 1; + return 1; } - } else { - if (arr1[0] instanceof Number && arr2[0] instanceof Number) { - double diff = ((Number) arr1[0]).doubleValue() - ((Number) arr2[0]).doubleValue(); - result = diff > 0 ? 1 : diff < 0 ? -1 : 0; + } + + if (o1 instanceof Comparable) { + final int rslt; + if (o1 instanceof Number && o2 instanceof Number) { + double diff = ((Number) o1).doubleValue() - ((Number) o2).doubleValue(); + rslt = diff > 0 ? 1 : diff < 0 ? -1 : 0; } else { - if (arr1[0] instanceof PdxString && arr2[0] instanceof String) { - arr2[0] = new PdxString((String) arr2[0]); - } else if (arr2[0] instanceof PdxString && arr1[0] instanceof String) { - arr1[0] = new PdxString((String) arr1[0]); + if (o1 instanceof PdxString && o2 instanceof String) { + o2 = new PdxString((String) o2); + } else if (o2 instanceof PdxString && o1 instanceof String) { + o1 = new PdxString((String) o1); } - result = ((Comparable) arr1[0]).compareTo(arr2[0]); + rslt = ((Comparable) o1).compareTo(o2); } - - } - - // equals. - if (result == 0) { - continue; - } else { - // not equal, change the sign based on the order by type (asc, - // desc). - if (((Boolean) arr1[1]).booleanValue()) { - result = (result * -1); + if (rslt == 0) { + continue; + } else { + return rslt; } - return result; + } else if (!o1.equals(o2)) { + return -1; } } - QueryObserver observer = QueryObserverHolder.getInstance(); - if (observer != null) { - observer.orderByColumnsEqual(); + return 0; + } else { + if (obj1 instanceof PdxString && obj2 instanceof String) { + obj2 = new PdxString((String) obj2); + } else if (obj2 instanceof PdxString && obj1 instanceof String) { + obj1 = new PdxString((String) obj1); } - // The comparable fields are equal, so we check if the overall keys are - // equal or not - if (this.objType.isStructType()) { - int i = 0; - for (Object o1 : (Object[]) obj1) { - Object o2 = ((Object[]) obj2)[i++]; - - // Check for null value. - if (o1 == null || o2 == null) { - if (o1 == null) { - if (o2 == null) { - continue; - } - return -1; - } else { - return 1; - } - } else if (o1 == QueryService.UNDEFINED || o2 == QueryService.UNDEFINED) { - if (o1 == QueryService.UNDEFINED) { - if (o2 == QueryService.UNDEFINED) { - continue; - } - return -1; - } else { - return 1; - } - } - if (o1 instanceof Comparable) { - final int rslt; - if (o1 instanceof Number && o2 instanceof Number) { - double diff = ((Number) o1).doubleValue() - ((Number) o2).doubleValue(); - rslt = diff > 0 ? 1 : diff < 0 ? -1 : 0; - } else { - if (o1 instanceof PdxString && o2 instanceof String) { - o2 = new PdxString((String) o2); - } else if (o2 instanceof PdxString && o1 instanceof String) { - o1 = new PdxString((String) o1); - } - rslt = ((Comparable) o1).compareTo(o2); - } - if (rslt == 0) { - continue; - } else { - return rslt; - } - } else if (!o1.equals(o2)) { - return -1; - } - } - return 0; + if (obj1 instanceof Comparable) { + return ((Comparable) obj1).compareTo(obj2); } else { - if (obj1 instanceof PdxString && obj2 instanceof String) { - obj2 = new PdxString((String) obj2); - } else if (obj2 instanceof PdxString && obj1 instanceof String) { - obj1 = new PdxString((String) obj1); - } - - if (obj1 instanceof Comparable) { - return ((Comparable) obj1).compareTo(obj2); - } else { - return obj1.equals(obj2) ? 0 : -1; - } + return obj1.equals(obj2) ? 0 : -1; } } } http://git-wip-us.apache.org/repos/asf/geode/blob/b3fc0c81/geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparatorUnmapped.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparatorUnmapped.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparatorUnmapped.java index edd1d89..a695a42 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparatorUnmapped.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/OrderByComparatorUnmapped.java @@ -24,8 +24,10 @@ import java.util.Map; import org.apache.geode.cache.query.FunctionDomainException; import org.apache.geode.cache.query.NameResolutionException; import org.apache.geode.cache.query.QueryInvocationTargetException; +import org.apache.geode.cache.query.QueryService; import org.apache.geode.cache.query.TypeMismatchException; import org.apache.geode.cache.query.types.ObjectType; +import org.apache.geode.pdx.internal.PdxString; @Deprecated public class OrderByComparatorUnmapped extends OrderByComparator { @@ -53,6 +55,64 @@ public class OrderByComparatorUnmapped extends OrderByComparator { } @Override + public int evaluateSortCriteria(Object obj1, Object obj2) { + int result = -1; + Object[] list1 = this.evaluateSortCriteria(obj1); + Object[] list2 = this.evaluateSortCriteria(obj2); + + if (list1.length != list2.length) { + Support.assertionFailed("Error Occurred due to improper sort criteria evaluation "); + } else { + for (int i = 0; i < list1.length; i++) { + Object arr1[] = (Object[]) list1[i]; + Object arr2[] = (Object[]) list2[i]; + // check for null. + if (arr1[0] == null || arr2[0] == null) { + if (arr1[0] == null) { + result = (arr2[0] == null ? 0 : -1); + } else { + result = 1; + } + } else if (arr1[0] == QueryService.UNDEFINED || arr2[0] == QueryService.UNDEFINED) { + if (arr1[0] == QueryService.UNDEFINED) { + result = (arr2[0] == QueryService.UNDEFINED ? 0 : -1); + } else { + result = 1; + } + } else { + if (arr1[0] instanceof Number && arr2[0] instanceof Number) { + double diff = ((Number) arr1[0]).doubleValue() - ((Number) arr2[0]).doubleValue(); + result = diff > 0 ? 1 : diff < 0 ? -1 : 0; + } else { + if (arr1[0] instanceof PdxString && arr2[0] instanceof String) { + arr2[0] = new PdxString((String) arr2[0]); + } else if (arr2[0] instanceof PdxString && arr1[0] instanceof String) { + arr1[0] = new PdxString((String) arr1[0]); + } + result = ((Comparable) arr1[0]).compareTo(arr2[0]); + } + + } + + // equals. + if (result == 0) { + continue; + } else { + // not equal, change the sign based on the order by type (asc, + // desc). + if (((Boolean) arr1[1]).booleanValue()) { + result = (result * -1); + } + break; + } + } + } + return result; + } + + + + @Override protected Object[] evaluateSortCriteria(Object row) { return (Object[]) orderByMap.get(row); }