Github user xwu0226 commented on a diff in the pull request: https://github.com/apache/spark/pull/14842#discussion_r77226814 --- Diff: core/src/main/java/org/apache/spark/util/collection/unsafe/sort/PrefixComparators.java --- @@ -69,49 +100,161 @@ public static long computePrefix(double value) { * ordering they define is compatible with radix sort. */ public abstract static class RadixSortSupport extends PrefixComparator { + /** @return Whether the sort should be descending in binary sort order. */ public abstract boolean sortDescending(); /** @return Whether the sort should take into account the sign bit. */ public abstract boolean sortSigned(); + + /** @return Whether the sort should put null first or last. */ + public abstract NullOrder nullOrder(); } // // Standard prefix comparator implementations // + // unsigned asc null first (default) public static final class UnsignedPrefixComparator extends RadixSortSupport { @Override public boolean sortDescending() { return false; } @Override public boolean sortSigned() { return false; } - @Override + @Override public NullOrder nullOrder() { return NullOrder.FIRST; } public int compare(long aPrefix, long bPrefix) { + if (aPrefix == 0L && bPrefix == 0L) { + return 0; + } + if (aPrefix == 0L) { + return -1; + } else if (bPrefix == 0L) { + return 1; + } return UnsignedLongs.compare(aPrefix, bPrefix); } } + // unsigned asc null last + public static final class UnsignedPrefixComparatorNullLast extends RadixSortSupport { + @Override public boolean sortDescending() { return false; } + @Override public boolean sortSigned() { return false; } + @Override public NullOrder nullOrder() { return NullOrder.LAST; } + public int compare(long aPrefix, long bPrefix) { + if (aPrefix == 0L && bPrefix == 0L) { + return 0; + } + if (aPrefix == 0L) { + return 1; + } else if (bPrefix == 0L) { + return -1; + } + return UnsignedLongs.compare(aPrefix, bPrefix); + } + } + + // unsigned desc null first + public static final class UnsignedPrefixComparatorDescNullFirst extends RadixSortSupport { + @Override public boolean sortDescending() { return true; } + @Override public boolean sortSigned() { return false; } + @Override public NullOrder nullOrder() { return NullOrder.FIRST; } + public int compare(long bPrefix, long aPrefix) { + if (aPrefix == 0L && bPrefix == 0L) { + return 0; + } + if (bPrefix == 0L) { + return -1; + } else if (aPrefix == 0L) { + return 1; + } + return UnsignedLongs.compare(aPrefix, bPrefix); + } + } + + // unsigned desc null last (default) public static final class UnsignedPrefixComparatorDesc extends RadixSortSupport { @Override public boolean sortDescending() { return true; } @Override public boolean sortSigned() { return false; } - @Override + @Override public NullOrder nullOrder() { return NullOrder.LAST; } public int compare(long bPrefix, long aPrefix) { + if (aPrefix == 0L && bPrefix == 0L) { + return 0; + } + if (bPrefix == 0L) { + return 1; + } else if (aPrefix == 0L) { + return -1; + } return UnsignedLongs.compare(aPrefix, bPrefix); } } + // signed asc null first (default) public static final class SignedPrefixComparator extends RadixSortSupport { @Override public boolean sortDescending() { return false; } @Override public boolean sortSigned() { return true; } - @Override + @Override public NullOrder nullOrder() { return NullOrder.FIRST; } + public int compare(long a, long b) { + if (a == Long.MIN_VALUE && b == Long.MIN_VALUE) { + return 0; + } + if (a == Long.MIN_VALUE) { + return -1; + } else if (b == Long.MIN_VALUE) { + return 1; + } + return (a < b) ? -1 : (a > b) ? 1 : 0; + } + } + + // signed asc null last + public static final class SignedPrefixComparatorNullLast extends RadixSortSupport { + @Override public boolean sortDescending() { return false; } + @Override public boolean sortSigned() { return true; } + @Override public NullOrder nullOrder() { return NullOrder.LAST; } public int compare(long a, long b) { + if (a == Long.MIN_VALUE && b == Long.MIN_VALUE) { + return 0; + } + if (a == Long.MIN_VALUE) { + return 1; + } else if (b == Long.MIN_VALUE) { + return -1; + } + return (a < b) ? -1 : (a > b) ? 1 : 0; + } + } + + // signed desc null first + public static final class SignedPrefixComparatorDescNullFirst extends RadixSortSupport { + @Override public boolean sortDescending() { return true; } + @Override public boolean sortSigned() { return true; } + @Override public NullOrder nullOrder() { return NullOrder.FIRST; } + public int compare(long b, long a) { + if (a == Long.MIN_VALUE && b == Long.MIN_VALUE) { --- End diff -- The fact that MIN_VALUE could be also literal min value was also my concern too. I will check what I can in SortOrder.scala. Thanks!
--- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. --- --------------------------------------------------------------------- To unsubscribe, e-mail: reviews-unsubscr...@spark.apache.org For additional commands, e-mail: reviews-h...@spark.apache.org