Skip to content

Commit

Permalink
Refactor KeyBytesEncoder to use ColumnVisitor instead of ValueVisitor
Browse files Browse the repository at this point in the history
  • Loading branch information
Torch3333 committed Oct 2, 2024
1 parent e1e9828 commit c988a99
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 113 deletions.
25 changes: 0 additions & 25 deletions core/src/main/java/com/scalar/db/io/ValueVisitor.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,25 @@
import static com.scalar.db.storage.dynamo.bytes.BytesUtils.mask;

import com.scalar.db.api.Scan.Ordering.Order;
import com.scalar.db.io.BigIntValue;
import com.scalar.db.io.BigIntColumn;
import java.nio.ByteBuffer;
import javax.annotation.concurrent.ThreadSafe;

@ThreadSafe
public class BigIntBytesEncoder implements BytesEncoder<BigIntValue> {
public class BigIntBytesEncoder implements BytesEncoder<BigIntColumn> {

BigIntBytesEncoder() {}

@Override
public int encodedLength(BigIntValue value, Order order) {
public int encodedLength(BigIntColumn column, Order order) {
return 8;
}

@Override
public void encode(BigIntValue value, Order order, ByteBuffer dst) {
long v = value.getAsLong();
public void encode(BigIntColumn column, Order order, ByteBuffer dst) {
assert !column.hasNullValue();

long v = column.getBigIntValue();
dst.put(mask((byte) ((v >> 56) ^ 0x80), order)); // Flip a sign bit to make it binary comparable
dst.put(mask((byte) (v >> 48), order));
dst.put(mask((byte) (v >> 40), order));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,32 @@

import com.scalar.db.api.Scan.Ordering.Order;
import com.scalar.db.common.error.CoreError;
import com.scalar.db.io.BlobValue;
import com.scalar.db.io.BlobColumn;
import java.nio.ByteBuffer;
import javax.annotation.concurrent.ThreadSafe;

@ThreadSafe
public class BlobBytesEncoder implements BytesEncoder<BlobValue> {
public class BlobBytesEncoder implements BytesEncoder<BlobColumn> {

private static final byte TERM = (byte) 0x00;
private static final byte MASKED_TERM = (byte) 0xff;

BlobBytesEncoder() {}

@Override
public int encodedLength(BlobValue value, Order order) {
assert value.getAsBytes().isPresent();
return value.getAsBytes().get().length + (order == Order.ASC ? 0 : 1);
public int encodedLength(BlobColumn column, Order order) {
assert column.getBlobValueAsBytes() != null;
return column.getBlobValueAsBytes().length + (order == Order.ASC ? 0 : 1);
}

@Override
public void encode(BlobValue value, Order order, ByteBuffer dst) {
assert value.getAsBytes().isPresent();
public void encode(BlobColumn column, Order order, ByteBuffer dst) {
assert column.getBlobValueAsBytes() != null;

byte[] value = column.getBlobValueAsBytes();

if (order == Order.DESC) {
for (byte b : value.getAsBytes().get()) {
for (byte b : value) {
if (b == TERM) {
throw new IllegalArgumentException(
CoreError.DYNAMO_ENCODER_0X00_BYTES_NOT_ACCEPTED_IN_BLOB_VALUES_IN_DESC_ORDER
Expand All @@ -36,7 +38,7 @@ public void encode(BlobValue value, Order order, ByteBuffer dst) {
}
}

for (byte b : value.getAsBytes().get()) {
for (byte b : value) {
dst.put(mask(b, order));
}
if (order == Order.DESC) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,27 @@
import static com.scalar.db.storage.dynamo.bytes.BytesUtils.mask;

import com.scalar.db.api.Scan.Ordering.Order;
import com.scalar.db.io.BooleanValue;
import com.scalar.db.io.BooleanColumn;
import java.nio.ByteBuffer;
import javax.annotation.concurrent.ThreadSafe;

@ThreadSafe
public class BooleanBytesEncoder implements BytesEncoder<BooleanValue> {
public class BooleanBytesEncoder implements BytesEncoder<BooleanColumn> {
private static final byte FALSE = 0x00;
private static final byte TRUE = 0x01;

BooleanBytesEncoder() {}

@Override
public int encodedLength(BooleanValue value, Order order) {
public int encodedLength(BooleanColumn column, Order order) {
return 1;
}

@Override
public void encode(BooleanValue value, Order order, ByteBuffer dst) {
boolean b = value.getAsBoolean();
public void encode(BooleanColumn column, Order order, ByteBuffer dst) {
assert !column.hasNullValue();

boolean b = column.getBooleanValue();
dst.put(mask(b ? TRUE : FALSE, order));
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
package com.scalar.db.storage.dynamo.bytes;

import com.scalar.db.api.Scan.Ordering.Order;
import com.scalar.db.io.Value;
import com.scalar.db.io.Column;
import java.nio.ByteBuffer;

/**
* A bytes-encoder that encodes a value to bytes while preserving the sort order.
* A bytes-encoder that encodes a column to bytes while preserving the sort order.
*
* @param <T> the value type
*/
public interface BytesEncoder<T extends Value<?>> {
public interface BytesEncoder<T extends Column<?>> {

/**
* Calculates the encoded bytes length.
*
* @param value a value
* @param column a column
* @param order an order
* @return the encoded bytes length
*/
int encodedLength(T value, Order order);
int encodedLength(T column, Order order);

/**
* Encodes the value to bytes
* Encodes the column to bytes
*
* @param value a value
* @param column a column
* @param order an order
* @param dst a ByteBuffer to write the encoded bytes
*/
void encode(T value, Order order, ByteBuffer dst);
void encode(T column, Order order, ByteBuffer dst);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@
import static com.scalar.db.storage.dynamo.bytes.BytesUtils.mask;

import com.scalar.db.api.Scan.Ordering.Order;
import com.scalar.db.io.DoubleValue;
import com.scalar.db.io.DoubleColumn;
import java.nio.ByteBuffer;
import javax.annotation.concurrent.ThreadSafe;

@ThreadSafe
public class DoubleBytesEncoder implements BytesEncoder<DoubleValue> {
public class DoubleBytesEncoder implements BytesEncoder<DoubleColumn> {

DoubleBytesEncoder() {}

@Override
public int encodedLength(DoubleValue value, Order order) {
public int encodedLength(DoubleColumn column, Order order) {
return 8;
}

@Override
public void encode(DoubleValue value, Order order, ByteBuffer dst) {
public void encode(DoubleColumn column, Order order, ByteBuffer dst) {
assert !column.hasNullValue();
/*
* The IEE754 floating point format already preserves sort ordering for positive floating point
* numbers when the raw bytes are compared in most significant byte order.
Expand All @@ -30,7 +31,7 @@ public void encode(DoubleValue value, Order order, ByteBuffer dst) {
*/

// store the floating point bits into a 64-bit long
long l = Double.doubleToLongBits(value.getAsDouble());
long l = Double.doubleToLongBits(column.getDoubleValue());

// invert the sign bit and XOR's all other bits with the sign bit itself
l ^= ((l >> (Long.SIZE - 1)) | Long.MIN_VALUE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@
import static com.scalar.db.storage.dynamo.bytes.BytesUtils.mask;

import com.scalar.db.api.Scan.Ordering.Order;
import com.scalar.db.io.FloatValue;
import com.scalar.db.io.FloatColumn;
import java.nio.ByteBuffer;
import javax.annotation.concurrent.ThreadSafe;

@ThreadSafe
public class FloatBytesEncoder implements BytesEncoder<FloatValue> {
public class FloatBytesEncoder implements BytesEncoder<FloatColumn> {

FloatBytesEncoder() {}

@Override
public int encodedLength(FloatValue value, Order order) {
public int encodedLength(FloatColumn column, Order order) {
return 4;
}

@Override
public void encode(FloatValue value, Order order, ByteBuffer dst) {
public void encode(FloatColumn column, Order order, ByteBuffer dst) {
assert !column.hasNullValue();
/*
* The IEE754 floating point format already preserves sort ordering for positive floating point
* numbers when the raw bytes are compared in most significant byte order.
Expand All @@ -30,7 +31,7 @@ public void encode(FloatValue value, Order order, ByteBuffer dst) {
*/

// store the floating point bits into a 32-bit int
int i = Float.floatToIntBits(value.getAsFloat());
int i = Float.floatToIntBits(column.getFloatValue());

// invert the sign bit and XOR's all other bits with the sign bit itself
i ^= ((i >> (Integer.SIZE - 1)) | Integer.MIN_VALUE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,25 @@
import static com.scalar.db.storage.dynamo.bytes.BytesUtils.mask;

import com.scalar.db.api.Scan.Ordering.Order;
import com.scalar.db.io.IntValue;
import com.scalar.db.io.IntColumn;
import java.nio.ByteBuffer;
import javax.annotation.concurrent.ThreadSafe;

@ThreadSafe
public class IntBytesEncoder implements BytesEncoder<IntValue> {
public class IntBytesEncoder implements BytesEncoder<IntColumn> {

IntBytesEncoder() {}

@Override
public int encodedLength(IntValue value, Order order) {
public int encodedLength(IntColumn column, Order order) {
return 4;
}

@Override
public void encode(IntValue value, Order order, ByteBuffer dst) {
int v = value.getAsInt();
public void encode(IntColumn column, Order order, ByteBuffer dst) {
assert !column.hasNullValue();

int v = column.getIntValue();
dst.put(mask((byte) ((v >> 24) ^ 0x80), order)); // Flip a sign bit to make it binary comparable
dst.put(mask((byte) (v >> 16), order));
dst.put(mask((byte) (v >> 8), order));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,77 +1,77 @@
package com.scalar.db.storage.dynamo.bytes;

import com.scalar.db.api.Scan.Ordering.Order;
import com.scalar.db.io.BigIntValue;
import com.scalar.db.io.BlobValue;
import com.scalar.db.io.BooleanValue;
import com.scalar.db.io.DoubleValue;
import com.scalar.db.io.FloatValue;
import com.scalar.db.io.IntValue;
import com.scalar.db.io.BigIntColumn;
import com.scalar.db.io.BlobColumn;
import com.scalar.db.io.BooleanColumn;
import com.scalar.db.io.Column;
import com.scalar.db.io.ColumnVisitor;
import com.scalar.db.io.DoubleColumn;
import com.scalar.db.io.FloatColumn;
import com.scalar.db.io.IntColumn;
import com.scalar.db.io.Key;
import com.scalar.db.io.TextValue;
import com.scalar.db.io.Value;
import com.scalar.db.io.ValueVisitor;
import com.scalar.db.io.TextColumn;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Map;
import javax.annotation.concurrent.NotThreadSafe;

@NotThreadSafe
public class KeyBytesEncodedLengthCalculator implements ValueVisitor {
public class KeyBytesEncodedLengthCalculator implements ColumnVisitor {

private int length;
private Map<String, Order> keyOrders;

@SuppressFBWarnings("EI_EXPOSE_REP2")
public int calculate(Key key, Map<String, Order> keyOrders) {
this.keyOrders = keyOrders;
for (Value<?> value : key) {
value.accept(this);
for (Column<?> column : key.getColumns()) {
column.accept(this);
}
return length;
}

@Override
public void visit(BooleanValue value) {
public void visit(BooleanColumn value) {
length +=
BytesEncoders.BOOLEAN.encodedLength(
value, keyOrders.getOrDefault(value.getName(), Order.ASC));
}

@Override
public void visit(IntValue value) {
public void visit(IntColumn value) {
length +=
BytesEncoders.INT.encodedLength(value, keyOrders.getOrDefault(value.getName(), Order.ASC));
}

@Override
public void visit(BigIntValue value) {
public void visit(BigIntColumn value) {
length +=
BytesEncoders.BIGINT.encodedLength(
value, keyOrders.getOrDefault(value.getName(), Order.ASC));
}

@Override
public void visit(FloatValue value) {
public void visit(FloatColumn value) {
length +=
BytesEncoders.FLOAT.encodedLength(
value, keyOrders.getOrDefault(value.getName(), Order.ASC));
}

@Override
public void visit(DoubleValue value) {
public void visit(DoubleColumn value) {
length +=
BytesEncoders.DOUBLE.encodedLength(
value, keyOrders.getOrDefault(value.getName(), Order.ASC));
}

@Override
public void visit(TextValue value) {
public void visit(TextColumn value) {
length +=
BytesEncoders.TEXT.encodedLength(value, keyOrders.getOrDefault(value.getName(), Order.ASC));
}

@Override
public void visit(BlobValue value) {
public void visit(BlobColumn value) {
length +=
BytesEncoders.BLOB.encodedLength(value, keyOrders.getOrDefault(value.getName(), Order.ASC));
}
Expand Down
Loading

0 comments on commit c988a99

Please sign in to comment.