public int compare()

in core/src/main/java/com/jetbrains/youtrackdb/internal/core/serialization/serializer/record/binary/BinaryComparatorV0.java [691:1325]


  public int compare(DatabaseSessionInternal session, final BinaryField iField1,
      final BinaryField iField2) {
    final var fieldValue1 = iField1.bytes;
    final var offset1 = fieldValue1.offset;

    final var fieldValue2 = iField2.bytes;
    final var offset2 = fieldValue2.offset;

    try {
      switch (iField1.type) {
        case INTEGER: {
          final var value1 = VarIntSerializer.readAsInteger(fieldValue1);

          switch (iField2.type) {
            case INTEGER: {
              final var value2 = VarIntSerializer.readAsInteger(fieldValue2);
              return Integer.compare(value1, value2);
            }
            case LONG:
            case DATETIME: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case DATE: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case SHORT: {
              final var value2 = VarIntSerializer.readAsShort(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case BYTE: {
              final var value2 = readByte(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case FLOAT: {
              final var value2 = Float.intBitsToFloat(readInteger(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case DOUBLE: {
              final var value2 = Double.longBitsToDouble(readLong(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case STRING: {
              final var value2 = readString(fieldValue2);
              return Integer.toString(value1).compareTo(value2);
            }
            case DECIMAL: {
              final var value2 =
                  DecimalSerializer.INSTANCE
                      .deserialize(session.getSerializerFactory(), fieldValue2.bytes,
                          fieldValue2.offset)
                      .intValue();
              return Integer.compare(value1, value2);
            }
          }
          break;
        }

        case LONG: {
          final var value1 = VarIntSerializer.readAsLong(fieldValue1);

          switch (iField2.type) {
            case INTEGER: {
              final var value2 = VarIntSerializer.readAsInteger(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case LONG:
            case DATETIME: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2);
              return Long.compare(value1, value2);
            }
            case DATE: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
              return Long.compare(value1, value2);
            }
            case SHORT: {
              final var value2 = VarIntSerializer.readAsShort(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case BYTE: {
              final var value2 = readByte(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case FLOAT: {
              final var value2 = Float.intBitsToFloat(readInteger(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case DOUBLE: {
              final var value2 = Double.longBitsToDouble(readLong(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case STRING: {
              final var value2 = readString(fieldValue2);
              return Long.toString(value1).compareTo(value2);
            }
            case DECIMAL: {
              final var value2 =
                  DecimalSerializer.INSTANCE
                      .deserialize(session.getSerializerFactory(), fieldValue2.bytes,
                          fieldValue2.offset)
                      .longValue();
              return Long.compare(value1, value2);
            }
          }
          break;
        }

        case SHORT: {
          final var value1 = VarIntSerializer.readAsShort(fieldValue1);

          switch (iField2.type) {
            case INTEGER: {
              final var value2 = VarIntSerializer.readAsInteger(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case LONG:
            case DATETIME: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case DATE: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case SHORT: {
              final var value2 = VarIntSerializer.readAsShort(fieldValue2);
              return Short.compare(value1, value2);
            }
            case BYTE: {
              final var value2 = readByte(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case FLOAT: {
              final var value2 = Float.intBitsToFloat(readInteger(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case DOUBLE: {
              final var value2 = Double.longBitsToDouble(readLong(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case STRING: {
              final var value2 = readString(fieldValue2);
              return Short.toString(value1).compareTo(value2);
            }
            case DECIMAL: {
              final var value2 =
                  DecimalSerializer.INSTANCE
                      .deserialize(session.getSerializerFactory(), fieldValue2.bytes,
                          fieldValue2.offset)
                      .shortValue();
              return Short.compare(value1, value2);
            }
          }
          break;
        }

        case STRING: {
          final var value1 = readString(fieldValue1);

          switch (iField2.type) {
            case INTEGER: {
              final var value2 = VarIntSerializer.readAsInteger(fieldValue2);
              return value1.compareTo(Integer.toString(value2));
            }
            case LONG:
            case DATETIME: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2);
              return value1.compareTo(Long.toString(value2));
            }
            case DATE: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
              return value1.compareTo(Long.toString(value2));
            }
            case SHORT: {
              final var value2 = VarIntSerializer.readAsShort(fieldValue2);
              return value1.compareTo(Short.toString(value2));
            }
            case BYTE: {
              final var value2 = readByte(fieldValue2);
              return value1.compareTo(Byte.toString(value2));
            }
            case FLOAT: {
              final var value2 = Float.intBitsToFloat(readInteger(fieldValue2));
              return value1.compareTo(Float.toString(value2));
            }
            case DOUBLE: {
              final var value2 = Double.longBitsToDouble(readLong(fieldValue2));
              return value1.compareTo(Double.toString(value2));
            }
            case STRING: {
              final var value2 = readString(fieldValue2);

              final Collate collate;
              if (iField1.collate != null
                  && !DefaultCollate.NAME.equals(iField1.collate.getName())) {
                collate = iField1.collate;
              } else if (iField2.collate != null
                  && !DefaultCollate.NAME.equals(iField2.collate.getName())) {
                collate = iField2.collate;
              } else {
                collate = null;
              }

              if (collate != null) {
                final var str1 = (String) collate.transform(value1);
                final var str2 = (String) collate.transform(value2);
                return str1.compareTo(str2);
              }

              return value1.compareTo(value2);
            }
            case BOOLEAN: {
              final var value2 = readByte(fieldValue2) == 1;
              return value1.compareTo(Boolean.toString(value2));
            }
            case DECIMAL: {
              final var value2 =
                  DecimalSerializer.INSTANCE.deserialize(session.getSerializerFactory(),
                      fieldValue2.bytes, fieldValue2.offset);
              return new BigDecimal(value1).compareTo(value2);
            }
          }
          break;
        }

        case DOUBLE: {
          final var value1 = Double.longBitsToDouble(readLong(fieldValue1));

          switch (iField2.type) {
            case INTEGER: {
              final var value2 = VarIntSerializer.readAsInteger(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case LONG:
            case DATETIME: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case SHORT: {
              final var value2 = VarIntSerializer.readAsShort(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case BYTE: {
              final var value2 = readByte(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case FLOAT: {
              final var value2 = Float.intBitsToFloat(readInteger(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case DOUBLE: {
              final var value2 = Double.longBitsToDouble(readLong(fieldValue2));
              return Double.compare(value1, value2);
            }
            case STRING: {
              final var value2 = readString(fieldValue2);
              return Double.toString(value1).compareTo(value2);
            }
            case DECIMAL: {
              final var value2 =
                  DecimalSerializer.INSTANCE
                      .deserialize(session.getSerializerFactory(), fieldValue2.bytes,
                          fieldValue2.offset)
                      .doubleValue();
              return Double.compare(value1, value2);
            }
          }
          break;
        }

        case FLOAT: {
          final var value1 = Float.intBitsToFloat(readInteger(fieldValue1));

          switch (iField2.type) {
            case INTEGER: {
              final var value2 = VarIntSerializer.readAsInteger(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case LONG:
            case DATETIME: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case SHORT: {
              final var value2 = VarIntSerializer.readAsShort(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case BYTE: {
              final var value2 = readByte(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case FLOAT: {
              final var value2 = Float.intBitsToFloat(readInteger(fieldValue2));
              return Float.compare(value1, value2);
            }
            case DOUBLE: {
              final var value2 = Double.longBitsToDouble(readLong(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case STRING, DECIMAL: {
              final var value2 = readString(fieldValue2);
              return Float.toString(value1).compareTo(value2);
            }
          }
          break;
        }

        case BYTE: {
          final var value1 = readByte(fieldValue1);

          switch (iField2.type) {
            case INTEGER: {
              final var value2 = VarIntSerializer.readAsInteger(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case LONG:
            case DATETIME: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case SHORT: {
              final var value2 = VarIntSerializer.readAsShort(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case BYTE: {
              final var value2 = readByte(fieldValue2);
              return Byte.compare(value1, value2);
            }
            case FLOAT: {
              final var value2 = Float.intBitsToFloat(readInteger(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case DOUBLE: {
              final var value2 = Double.longBitsToDouble(readLong(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case STRING: {
              final var value2 = readString(fieldValue2);
              return Byte.toString(value1).compareTo(value2);
            }
            case DECIMAL: {
              final var value2 =
                  DecimalSerializer.INSTANCE
                      .deserialize(session.getSerializerFactory(), fieldValue2.bytes,
                          fieldValue2.offset)
                      .byteValue();
              return Byte.compare(value1, value2);
            }
          }
          break;
        }

        case BOOLEAN: {
          final var value1 = readByte(fieldValue1) == 1;

          switch (iField2.type) {
            case BOOLEAN: {
              final var value2 = readByte(fieldValue2) == 1;
              return (value1 == value2) ? 0 : value1 ? 1 : -1;
            }
            case STRING: {
              final var value2 = Boolean.parseBoolean(readString(fieldValue2));
              return (value1 == value2) ? 0 : value1 ? 1 : -1;
            }
          }
          break;
        }

        case DATETIME: {
          final var value1 = VarIntSerializer.readAsLong(fieldValue1);

          switch (iField2.type) {
            case INTEGER: {
              final var value2 = VarIntSerializer.readAsInteger(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case LONG:
            case DATETIME: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2);
              return Long.compare(value1, value2);
            }
            case DATE: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
              return Long.compare(value1, value2);
            }
            case SHORT: {
              final var value2 = VarIntSerializer.readAsShort(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case BYTE: {
              final var value2 = readByte(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case FLOAT: {
              final var value2 = Float.intBitsToFloat(readInteger(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case DOUBLE: {
              final var value2 = Double.longBitsToDouble(readLong(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case STRING: {
              final var value2AsString = readString(fieldValue2);

              if (IOUtils.isLong(value2AsString)) {
                final var value2 = Long.parseLong(value2AsString);
                return Long.compare(value1, value2);
              }
              try {
                final var dateFormat = DateHelper.getDateTimeFormatInstance(session);
                final var value2AsDate = dateFormat.parse(value2AsString);
                final var value2 = value2AsDate.getTime();
                return Long.compare(value1, value2);
              } catch (ParseException ignored) {
                try {
                  var dateFormat = DateHelper.getDateFormatInstance(session);

                  final var value2AsDate = dateFormat.parse(value2AsString);
                  final var value2 = value2AsDate.getTime();
                  return Long.compare(value1, value2);
                } catch (ParseException ignore) {
                  return new Date(value1).toString().compareTo(value2AsString);
                }
              }
            }
            case DECIMAL: {
              final var value2 =
                  DecimalSerializer.INSTANCE
                      .deserialize(session.getSerializerFactory(), fieldValue2.bytes,
                          fieldValue2.offset)
                      .longValue();
              return Long.compare(value1, value2);
            }
          }
          break;
        }

        case DATE: {
          final var value1 = VarIntSerializer.readAsLong(fieldValue1) * MILLISEC_PER_DAY;

          switch (iField2.type) {
            case INTEGER: {
              final var value2 = VarIntSerializer.readAsInteger(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case LONG:
            case DATETIME: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2);
              return Long.compare(value1, value2);
            }
            case DATE: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
              return Long.compare(value1, value2);
            }
            case SHORT: {
              final var value2 = VarIntSerializer.readAsShort(fieldValue2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case FLOAT: {
              final var value2 = Float.intBitsToFloat(readInteger(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case DOUBLE: {
              final var value2 = Double.longBitsToDouble(readLong(fieldValue2));
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            }
            case STRING: {
              final var value2AsString = readString(fieldValue2);

              if (IOUtils.isLong(value2AsString)) {
                final var value2 = Long.parseLong(value2AsString);
                return Long.compare(value1, value2);
              }

              try {
                final DateFormat dateFormat;
                if (session != null) {
                  dateFormat = DateHelper.getDateFormatInstance(session);
                } else {
                  dateFormat = new SimpleDateFormat(StorageConfiguration.DEFAULT_DATE_FORMAT);
                }
                final var value2AsDate = dateFormat.parse(value2AsString);
                var value2 = value2AsDate.getTime();
                value2 =
                    convertDayToTimezone(
                        DateHelper.getDatabaseTimeZone(session), TimeZone.getTimeZone("GMT"),
                        value2);
                return Long.compare(value1, value2);
              } catch (ParseException ignore) {
                try {
                  final DateFormat dateFormat;
                  if (session != null) {
                    dateFormat = DateHelper.getDateFormatInstance(session);
                  } else {
                    dateFormat =
                        new SimpleDateFormat(StorageConfiguration.DEFAULT_DATETIME_FORMAT);
                  }

                  final var value2AsDate = dateFormat.parse(value2AsString);
                  var value2 = value2AsDate.getTime();
                  value2 =
                      convertDayToTimezone(
                          DateHelper.getDatabaseTimeZone(session),
                          TimeZone.getTimeZone("GMT"),
                          value2);
                  return Long.compare(value1, value2);
                } catch (ParseException ignored) {
                  return new Date(value1).toString().compareTo(value2AsString);
                }
              }
            }
            case DECIMAL: {
              final var value2 =
                  DecimalSerializer.INSTANCE
                      .deserialize(session.getSerializerFactory(), fieldValue2.bytes,
                          fieldValue2.offset)
                      .longValue();
              return Long.compare(value1, value2);
            }
          }
          break;
        }

        case BINARY: {
          if (Objects.requireNonNull(iField2.type) == PropertyTypeInternal.BINARY) {
            final var length1 = VarIntSerializer.readAsInteger(fieldValue1);
            final var length2 = VarIntSerializer.readAsInteger(fieldValue2);

            final var max = Math.min(length1, length2);
            for (var i = 0; i < max; ++i) {
              final var b1 = fieldValue1.bytes[fieldValue1.offset + i];
              final var b2 = fieldValue2.bytes[fieldValue2.offset + i];

              if (b1 > b2) {
                return 1;
              } else if (b2 > b1) {
                return -1;
              }
            }

            if (length1 > length2) {
              return 1;
            } else if (length2 > length1) {
              return -1;
            }

            // EQUALS
            return 0;
          }
          break;
        }

        case LINK: {
          switch (iField2.type) {
            case LINK: {
              final var collectionId1 = VarIntSerializer.readAsInteger(fieldValue1);
              final var collectionId2 = VarIntSerializer.readAsInteger(fieldValue2);
              if (collectionId1 > collectionId2) {
                return 1;
              } else if (collectionId1 < collectionId2) {
                return -1;
              } else {
                final var collectionPos1 = VarIntSerializer.readAsLong(fieldValue1);
                final var collectionPos2 = VarIntSerializer.readAsLong(fieldValue2);
                if (collectionPos1 > collectionPos2) {
                  return 1;
                } else if (collectionPos1 < collectionPos2) {
                  return -1;
                }
                return 0;
              }
            }

            case STRING: {
              return readOptimizedLink(fieldValue1, false)
                  .compareTo(RecordIdInternal.fromString(readString(fieldValue2), false));
            }
          }
          break;
        }

        case DECIMAL: {
          final var value1 =
              DecimalSerializer.INSTANCE.deserialize(session.getSerializerFactory(),
                  fieldValue1.bytes, fieldValue1.offset);

          switch (iField2.type) {
            case INTEGER: {
              final var value2 = VarIntSerializer.readAsInteger(fieldValue2);
              return value1.compareTo(new BigDecimal(value2));
            }
            case LONG:
            case DATETIME: {
              final var value2 = VarIntSerializer.readAsLong(fieldValue2);
              return value1.compareTo(new BigDecimal(value2));
            }
            case SHORT: {
              final var value2 = VarIntSerializer.readAsShort(fieldValue2);
              return value1.compareTo(new BigDecimal(value2));
            }
            case FLOAT: {
              final var value2 = Float.intBitsToFloat(readInteger(fieldValue2));
              return value1.compareTo(new BigDecimal(value2));
            }
            case DOUBLE: {
              final var value2 = Double.longBitsToDouble(readLong(fieldValue2));
              return value1.compareTo(new BigDecimal(value2));
            }
            case STRING: {
              final var value2 = readString(fieldValue2);
              return value1.toString().compareTo(value2);
            }
            case DECIMAL: {
              final var value2 =
                  DecimalSerializer.INSTANCE.deserialize(session.getSerializerFactory(),
                      fieldValue2.bytes, fieldValue2.offset);
              return value1.compareTo(value2);
            }
            case BYTE: {
              final var value2 = readByte(fieldValue2);
              return value1.compareTo(new BigDecimal(value2));
            }
          }
          break;
        }
      }
    } finally {
      fieldValue1.offset = offset1;
      fieldValue2.offset = offset2;
    }

    // NO COMPARE SUPPORTED, RETURN NON EQUALS
    return 1;
  }