Skip to content

Commit

Permalink
ColumnEncodingUtils add comments and test
Browse files Browse the repository at this point in the history
  • Loading branch information
Torch3333 committed Dec 17, 2024
1 parent 523b009 commit 152e196
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 25 deletions.
56 changes: 31 additions & 25 deletions core/src/main/java/com/scalar/db/storage/ColumnEncodingUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,53 +18,59 @@ public static long encode(DateColumn column) {
return column.getDateValue().toEpochDay();
}

public static LocalDate decodeDate(long epochDay) {
return LocalDate.ofEpochDay(epochDay);
}

public static long encode(TimeColumn column) {
assert column.getTimeValue() != null;
return column.getTimeValue().toNanoOfDay();
}

public static LocalTime decodeTime(long nanoOfDay) {
return LocalTime.ofNanoOfDay(nanoOfDay);
}

public static long encode(TimestampColumn column) {
assert column.getTimestampValue() != null;

return encodeInstant(column.getTimestampValue().toInstant(ZoneOffset.UTC));
}

@SuppressWarnings("JavaInstantGetSecondsGetNano")
public static LocalDateTime decodeTimestamp(long longTimestamp) {
long nanoOfSeconds = longTimestamp % 1000 * 1_000_000;
// Invert the nanoOfSeconds when the encoded instant is negative, that is for a date before 1970
if (longTimestamp < 0) {
nanoOfSeconds *= -1;
}
return LocalDateTime.ofEpochSecond(
longTimestamp / 1000, Math.toIntExact(nanoOfSeconds), ZoneOffset.UTC);
}

public static long encode(TimestampTZColumn column) {
assert column.getTimestampTZValue() != null;

return encodeInstant(column.getTimestampTZValue());
}

@SuppressWarnings("JavaInstantGetSecondsGetNano")
private static long encodeInstant(Instant instant) {
// Encoding format : <epochSecond><millisecondOfSecond>
// The rightmost three digits are the number of milliseconds from the start of the
// second, the other digits on the left are the epochSecond
// For example:
// - if epochSecond=12345 and millisecondOfSecond=789, then the encoded value will be 12345789
// - if epochSecond=-12345 and millisecondOfSecond=789, then the encoded value will be -12345789

long encoded = instant.getEpochSecond() * 1000;
// Subtract the nanoOfSeconds when the epochSecond is negative, that is for a date before 1970
if (encoded >= 0) {
encoded += instant.getNano() / 1_000_000;
} else {
// Subtract the millisecondOfSeconds when the epochSecond is negative, that is for a date before
// 1970
if (encoded < 0) {
encoded -= instant.getNano() / 1_000_000;
} else {
encoded += instant.getNano() / 1_000_000;
}
return encoded;
}

public static LocalDate decodeDate(long epochDay) {
return LocalDate.ofEpochDay(epochDay);
}

public static LocalTime decodeTime(long nanoOfDay) {
return LocalTime.ofNanoOfDay(nanoOfDay);
}

public static LocalDateTime decodeTimestamp(long longTimestamp) {
long nanoOfSeconds = longTimestamp % 1000 * 1_000_000;
// Invert the nanoOfSeconds when the encoded instant is negative, that is for a date before 1970
if (longTimestamp < 0) {
nanoOfSeconds *= -1;
}
return LocalDateTime.ofEpochSecond(
longTimestamp / 1000, Math.toIntExact(nanoOfSeconds), ZoneOffset.UTC);
}

public static Instant decodeTimestampTZ(long longTimestampTZ) {
long nanoOfSeconds = longTimestampTZ % 1000 * 1_000_000;
// Invert the nanoOfSeconds when the encoded instant is negative, that is for a date before 1970
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,30 @@ public void decodeTimestampTZ_ShouldWorkProperly() {
.isEqualTo(LocalDateTime.of(1234, 10, 1, 12, 34, 56, 0).toInstant(ZoneOffset.UTC));
assertThat(epoch).isEqualTo(Instant.EPOCH);
}

@Test
public void encodeThenDecodeTimestamp_WithMinAndMaxValues_ShouldWorkProperly() {
// Arrange
TimestampColumn min = TimestampColumn.of("timestamp", TimestampColumn.MIN_VALUE);
TimestampColumn max = TimestampColumn.of("timestamp", TimestampColumn.MAX_VALUE);

// Act Assert
assertThat(ColumnEncodingUtils.decodeTimestamp(ColumnEncodingUtils.encode(min)))
.isEqualTo(TimestampColumn.MIN_VALUE);
assertThat(ColumnEncodingUtils.decodeTimestamp(ColumnEncodingUtils.encode(max)))
.isEqualTo(TimestampColumn.MAX_VALUE);
}

@Test
public void encodeThenDecodeTimestampTZ_WithMinAndMaxValues_ShouldWorkProperly() {
// Arrange
TimestampTZColumn min = TimestampTZColumn.of("timestampTZ", TimestampTZColumn.MIN_VALUE);
TimestampTZColumn max = TimestampTZColumn.of("timestampTZ", TimestampTZColumn.MAX_VALUE);

// Act Assert
assertThat(ColumnEncodingUtils.decodeTimestampTZ(ColumnEncodingUtils.encode(min)))
.isEqualTo(TimestampTZColumn.MIN_VALUE);
assertThat(ColumnEncodingUtils.decodeTimestampTZ(ColumnEncodingUtils.encode(max)))
.isEqualTo(TimestampTZColumn.MAX_VALUE);
}
}

0 comments on commit 152e196

Please sign in to comment.