Skip to content

Commit

Permalink
ARROW-5844: [Java] Support comparison & sort for more numeric types
Browse files Browse the repository at this point in the history
Currently, we only support comparison & sort for 32-bit integers, in this issue, we provide support for more numeric data types:

byte
short
long
float
double

Author: liyafan82 <[email protected]>

Closes #4799 from liyafan82/fly_0704_cmp and squashes the following commits:

a921cdd <liyafan82>  Remove if conditons in default float & double comparators
a4b4099 <liyafan82>  Replace if condition with signum function
30f946b <liyafan82> Merge branch 'master' into fly_0704_cmp
bc880f1 <liyafan82> Merge branch 'master' into fly_0704_cmp
7cbe556 <liyafan82>  Support NaN for float and double
3860c11 <liyafan82>  Support comparison & sort for more numeric types
  • Loading branch information
liyafan82 authored and emkornfield committed Jul 12, 2019
1 parent 5c61263 commit e78ea91
Show file tree
Hide file tree
Showing 2 changed files with 362 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@

package org.apache.arrow.algorithm.sort;

import org.apache.arrow.vector.BigIntVector;
import org.apache.arrow.vector.Float4Vector;
import org.apache.arrow.vector.Float8Vector;
import org.apache.arrow.vector.IntVector;
import org.apache.arrow.vector.SmallIntVector;
import org.apache.arrow.vector.TinyIntVector;
import org.apache.arrow.vector.VarCharVector;
import org.apache.arrow.vector.holders.NullableVarCharHolder;

Expand All @@ -26,6 +31,42 @@
*/
public class DefaultVectorComparators {

/**
* Default comparator for bytes.
* The comparison is based on values, with null comes first.
*/
public static class ByteComparator extends VectorValueComparator<TinyIntVector> {

public ByteComparator() {
super(Byte.SIZE / 8);
}

@Override
public int compareNotNull(int index1, int index2) {
byte value1 = vector1.get(index1);
byte value2 = vector2.get(index2);
return value1 - value2;
}
}

/**
* Default comparator for short integers.
* The comparison is based on values, with null comes first.
*/
public static class ShortComparator extends VectorValueComparator<SmallIntVector> {

public ShortComparator() {
super(Short.SIZE / 8);
}

@Override
public int compareNotNull(int index1, int index2) {
short value1 = vector1.get(index1);
short value2 = vector2.get(index2);
return value1 - value2;
}
}

/**
* Default comparator for 32-bit integers.
* The comparison is based on int values, with null comes first.
Expand All @@ -44,6 +85,89 @@ public int compareNotNull(int index1, int index2) {
}
}

/**
* Default comparator for long integers.
* The comparison is based on values, with null comes first.
*/
public static class LongComparator extends VectorValueComparator<BigIntVector> {

public LongComparator() {
super(Long.SIZE / 8);
}

@Override
public int compareNotNull(int index1, int index2) {
long value1 = vector1.get(index1);
long value2 = vector2.get(index2);

return Long.signum(value1 - value2);
}
}

/**
* Default comparator for float type.
* The comparison is based on values, with null comes first.
*/
public static class Float4Comparator extends VectorValueComparator<Float4Vector> {

public Float4Comparator() {
super(Float.SIZE / 8);
}

@Override
public int compareNotNull(int index1, int index2) {
float value1 = vector1.get(index1);
float value2 = vector2.get(index2);

boolean isNan1 = Float.isNaN(value1);
boolean isNan2 = Float.isNaN(value2);
if (isNan1 || isNan2) {
if (isNan1 && isNan2) {
return 0;
} else if (isNan1) {
// nan is greater than any normal value
return 1;
} else {
return -1;
}
}

return (int) Math.signum(value1 - value2);
}
}

/**
* Default comparator for double type.
* The comparison is based on values, with null comes first.
*/
public static class Float8Comparator extends VectorValueComparator<Float8Vector> {

public Float8Comparator() {
super(Double.SIZE / 8);
}

@Override
public int compareNotNull(int index1, int index2) {
double value1 = vector1.get(index1);
double value2 = vector2.get(index2);

boolean isNan1 = Double.isNaN(value1);
boolean isNan2 = Double.isNaN(value2);
if (isNan1 || isNan2) {
if (isNan1 && isNan2) {
return 0;
} else if (isNan1) {
// nan is greater than any normal value
return 1;
} else {
return -1;
}
}

return (int) Math.signum(value1 - value2);
}
}

/**
* Default comparator for varchars.
* The comparison is in lexicographic order, with null comes first.
Expand Down
Loading

0 comments on commit e78ea91

Please sign in to comment.