public final int compareTo()

in phoenix-core-client/src/main/java/org/apache/phoenix/schema/types/PDataType.java [166:260]


    public final int compareTo(byte[] lhs, int lhsOffset, int lhsLength, SortOrder lhsSortOrder, byte[] rhs,
            int rhsOffset, int rhsLength, SortOrder rhsSortOrder, PDataType rhsType) {
        Preconditions.checkNotNull(lhsSortOrder);
        Preconditions.checkNotNull(rhsSortOrder);
        if (this.isBytesComparableWith(rhsType)) { // directly compare the bytes
            // Special case as we may be comparing two arrays that have different separator characters due to PHOENIX-2067
            if (!this.isArrayType() || !rhsType.isArrayType() || 
                    PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength) == PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength)) {
                // Ignore trailing zero bytes if fixed byte length (for example TIMESTAMP compared to DATE)
                if (lhsLength != rhsLength && this.isFixedWidth() && rhsType.isFixedWidth() && this.getByteSize() != null && rhsType.getByteSize() != null) {
                    if (lhsLength > rhsLength) {
                        int minOffset = lhsOffset + rhsLength;
                        for (int i = lhsOffset + lhsLength - 1; i >= minOffset && lhsSortOrder.normalize(lhs[i]) == 0; i--,lhsLength--) {
                        }
                    } else {
                        int minOffset = rhsOffset + lhsLength;
                        for (int i = rhsOffset + rhsLength - 1; i >= minOffset && rhsSortOrder.normalize(rhs[i]) == 0; i--,rhsLength--) {
                        }
                    }
                }
                return compareTo(lhs, lhsOffset, lhsLength, lhsSortOrder, rhs, rhsOffset, rhsLength, rhsSortOrder);
            }
        }
        PDataCodec lhsCodec = this.getCodec();
        if ( lhsCodec == null ) {
            byte[] rhsConverted;
            Object o = this.toObject(rhs, rhsOffset, rhsLength, rhsType, rhsSortOrder);
            
            // No lhs native type representation, so convert rhsType to bytes representation of lhs type
            // Due to PHOENIX-2067, favor the array that is already in the new format so we don't have to convert both.
            if ( this.isArrayType() && PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength) == PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength)) {
                rhsConverted = ((PArrayDataType)this).toBytes(o, PArrayDataType.arrayBaseType(this), lhsSortOrder, PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength));
            } else {
                rhsConverted = this.toBytes(o);
                if (lhsSortOrder == SortOrder.DESC) {
                    lhs = SortOrder.invert(lhs, lhsOffset, new byte[lhsLength], 0, lhsLength);
                    lhsOffset = 0;
                }
            }
            return Bytes.compareTo(lhs, lhsOffset, lhsLength, rhsConverted, 0, rhsConverted.length);
        }
        PDataCodec rhsCodec = rhsType.getCodec();
        if (rhsCodec == null) {
            byte[] lhsConverted;
            Object o = rhsType.toObject(lhs, lhsOffset, lhsLength, this, lhsSortOrder);
            
            // No rhs native type representation, so convert lhsType to bytes representation of rhs type
            // Due to PHOENIX-2067, favor the array that is already in the new format so we don't have to convert both.
            if ( rhsType.isArrayType() && PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength) == PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength)) {
                lhsConverted = ((PArrayDataType)rhsType).toBytes(o, PArrayDataType.arrayBaseType(rhsType), rhsSortOrder, PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength));
            } else {
                lhsConverted = rhsType.toBytes(o);
                if (rhsSortOrder == SortOrder.DESC) {
                    rhs = SortOrder.invert(rhs, rhsOffset, new byte[rhsLength], 0, rhsLength);
                }
            }
            return Bytes.compareTo(lhsConverted, 0, lhsConverted.length, rhs, rhsOffset, rhsLength);
        }
        // convert to native and compare
        if ( (this.isCoercibleTo(PLong.INSTANCE) || this.isCoercibleTo(PDate.INSTANCE)) && 
             (rhsType.isCoercibleTo(PLong.INSTANCE) || rhsType.isCoercibleTo(PDate.INSTANCE)) ) {
            return Longs.compare(this.getCodec().decodeLong(lhs, lhsOffset, lhsSortOrder), rhsType.getCodec()
                    .decodeLong(rhs, rhsOffset, rhsSortOrder));
        } else if (isDoubleOrFloat(this) && isDoubleOrFloat(rhsType)) { // native double to double comparison
            return Doubles.compare(this.getCodec().decodeDouble(lhs, lhsOffset, lhsSortOrder), rhsType.getCodec()
                    .decodeDouble(rhs, rhsOffset, rhsSortOrder));
        } else { // native float/double to long comparison
            float fvalue = 0.0F;
            double dvalue = 0.0;
            long lvalue = 0;
            boolean isFloat = false;
            int invert = 1;

            if (this.isCoercibleTo(PLong.INSTANCE)) {
                lvalue = this.getCodec().decodeLong(lhs, lhsOffset, lhsSortOrder);
            } else if (this.getClass() == PFloat.class) {
                isFloat = true;
                fvalue = this.getCodec().decodeFloat(lhs, lhsOffset, lhsSortOrder);
            } else if (this.isCoercibleTo(PDouble.INSTANCE)) {
                dvalue = this.getCodec().decodeDouble(lhs, lhsOffset, lhsSortOrder);
            }
            if (rhsType.isCoercibleTo(PLong.INSTANCE)) {
                lvalue = rhsType.getCodec().decodeLong(rhs, rhsOffset, rhsSortOrder);
            } else if (rhsType == PFloat.INSTANCE) {
                invert = -1;
                isFloat = true;
                fvalue = rhsType.getCodec().decodeFloat(rhs, rhsOffset, rhsSortOrder);
            } else if (rhsType.isCoercibleTo(PDouble.INSTANCE)) {
                invert = -1;
                dvalue = rhsType.getCodec().decodeDouble(rhs, rhsOffset, rhsSortOrder);
            }
            // Invert the comparison if float/double value is on the RHS
            return invert * (isFloat ? compareFloatToLong(fvalue, lvalue) : compareDoubleToLong(dvalue, lvalue));
        }
    }