This is an automated email from the ASF dual-hosted git repository.
bdeggleston pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new 8be1cbe Use unsigned short in ValueAccessor.sliceWithShortLength
8be1cbe is described below
commit 8be1cbe9ab14155773bfab765a3567df9ff9833f
Author: Blake Eggleston <[email protected]>
AuthorDate: Tue Sep 29 14:20:05 2020 -0700
Use unsigned short in ValueAccessor.sliceWithShortLength
Patch by Blake Eggleston; Reviewed by Caleb Rackliffe and David Capwell for
CASSANDRA-16147
---
.circleci/config.yml | 98 +++++++++++-----------
CHANGES.txt | 1 +
.../cassandra/db/marshal/ByteArrayAccessor.java | 53 ++++++++++++
.../cassandra/db/marshal/ByteBufferAccessor.java | 53 ++++++++++++
.../apache/cassandra/db/marshal/CompositeType.java | 2 +-
.../apache/cassandra/db/marshal/ValueAccessor.java | 14 +---
.../org/apache/cassandra/utils/ByteArrayUtil.java | 4 +
.../org/apache/cassandra/utils/ByteBufferUtil.java | 8 +-
.../cassandra/db/marshal/CompositeTypeTest.java | 22 +++++
.../cassandra/db/marshal/ValueAccessorTest.java | 54 ++++++++++++
10 files changed, 247 insertions(+), 62 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 8ba8949..45c8820 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -3,10 +3,10 @@ jobs:
j8_jvm_upgrade_dtests:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 1
+ parallelism: 2
steps:
- attach_workspace:
at: /home/cassandra
@@ -94,10 +94,10 @@ jobs:
j8_cqlsh-dtests-py2-with-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -171,10 +171,10 @@ jobs:
j11_unit_tests:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -263,10 +263,10 @@ jobs:
j8_cqlsh-dtests-py38-no-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -340,10 +340,10 @@ jobs:
j11_cqlsh-dtests-py3-with-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -418,10 +418,10 @@ jobs:
j11_cqlsh-dtests-py3-no-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -496,10 +496,10 @@ jobs:
j11_cqlsh-dtests-py38-with-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -574,10 +574,10 @@ jobs:
j8_cqlsh-dtests-py3-with-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -651,10 +651,10 @@ jobs:
j8_cqlsh-dtests-py2-no-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -728,10 +728,10 @@ jobs:
j11_cqlsh-dtests-py2-with-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -806,10 +806,10 @@ jobs:
j11_dtests-with-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -887,10 +887,10 @@ jobs:
j8_dtests-no-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -945,10 +945,10 @@ jobs:
j8_upgradetests-no-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -1044,7 +1044,7 @@ jobs:
utests_stress:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
parallelism: 1
@@ -1089,10 +1089,10 @@ jobs:
j8_unit_tests:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -1180,10 +1180,10 @@ jobs:
j11_jvm_dtests:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 1
+ parallelism: 2
steps:
- attach_workspace:
at: /home/cassandra
@@ -1353,10 +1353,10 @@ jobs:
j11_cqlsh-dtests-py2-no-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -1431,10 +1431,10 @@ jobs:
j8_dtests-with-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -1489,10 +1489,10 @@ jobs:
j11_cqlsh-dtests-py38-no-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -1567,10 +1567,10 @@ jobs:
j8_jvm_dtests:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 1
+ parallelism: 5
steps:
- attach_workspace:
at: /home/cassandra
@@ -1738,10 +1738,10 @@ jobs:
j8_cqlsh-dtests-py3-no-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -1815,10 +1815,10 @@ jobs:
j8_cqlsh-dtests-py38-with-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -1892,7 +1892,7 @@ jobs:
utests_long:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
parallelism: 1
@@ -1937,7 +1937,7 @@ jobs:
utests_fqltool:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
parallelism: 1
@@ -1982,10 +1982,10 @@ jobs:
j11_dtests-no-vnodes:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
@@ -2063,10 +2063,10 @@ jobs:
utests_compression:
docker:
- image: nastra/cassandra-testing-ubuntu1910-java11-w-dependencies:20200603
- resource_class: medium
+ resource_class: xlarge
working_directory: ~/
shell: /bin/bash -eo pipefail -l
- parallelism: 4
+ parallelism: 100
steps:
- attach_workspace:
at: /home/cassandra
diff --git a/CHANGES.txt b/CHANGES.txt
index d1fa00e..d66bcad 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
4.0-beta3
+ * Use unsigned short in ValueAccessor.sliceWithShortLength (CASSANDRA-16147)
* Abort repairs when getting a truncation request (CASSANDRA-15854)
* Remove bad assert when getting active compactions for an sstable
(CASSANDRA-15457)
* Avoid failing compactions with very large partitions (CASSANDRA-15164)
diff --git a/src/java/org/apache/cassandra/db/marshal/ByteArrayAccessor.java
b/src/java/org/apache/cassandra/db/marshal/ByteArrayAccessor.java
index 92f18a2..7d13844 100644
--- a/src/java/org/apache/cassandra/db/marshal/ByteArrayAccessor.java
+++ b/src/java/org/apache/cassandra/db/marshal/ByteArrayAccessor.java
@@ -43,49 +43,58 @@ public class ByteArrayAccessor implements
ValueAccessor<byte[]>
private ByteArrayAccessor() {}
+ @Override
public int size(byte[] value)
{
return value.length;
}
+ @Override
public byte[][] createArray(int length)
{
return new byte[length][];
}
+ @Override
public void write(byte[] value, DataOutputPlus out) throws IOException
{
out.write(value);
}
+ @Override
public void write(byte[] value, ByteBuffer out)
{
out.put(value);
}
+ @Override
public <V2> int copyTo(byte[] src, int srcOffset, V2 dst,
ValueAccessor<V2> dstAccessor, int dstOffset, int size)
{
dstAccessor.copyByteArrayTo(src, srcOffset, dst, dstOffset, size);
return size;
}
+ @Override
public int copyByteArrayTo(byte[] src, int srcOffset, byte[] dst, int
dstOffset, int size)
{
FastByteOperations.copy(src, srcOffset, dst, dstOffset, size);
return size;
}
+ @Override
public int copyByteBufferTo(ByteBuffer src, int srcOffset, byte[] dst, int
dstOffset, int size)
{
FastByteOperations.copy(src, src.position() + srcOffset, dst,
dstOffset, size);
return size;
}
+ @Override
public void digest(byte[] value, int offset, int size, Digest digest)
{
digest.update(value, offset, size);
}
+ @Override
public byte[] read(DataInputPlus in, int length) throws IOException
{
byte[] b = new byte[length];
@@ -93,26 +102,31 @@ public class ByteArrayAccessor implements
ValueAccessor<byte[]>
return b;
}
+ @Override
public byte[] slice(byte[] input, int offset, int length)
{
return Arrays.copyOfRange(input, offset, offset + length);
}
+ @Override
public <V2> int compare(byte[] left, V2 right, ValueAccessor<V2> accessorR)
{
return accessorR.compareByteArrayTo(left, right);
}
+ @Override
public int compareByteArrayTo(byte[] left, byte[] right)
{
return ByteArrayUtil.compareUnsigned(left, right);
}
+ @Override
public int compareByteBufferTo(ByteBuffer left, byte[] right)
{
return ByteBufferUtil.compare(left, right);
}
+ @Override
public ByteBuffer toBuffer(byte[] value)
{
if (value == null)
@@ -120,11 +134,13 @@ public class ByteArrayAccessor implements
ValueAccessor<byte[]>
return ByteBuffer.wrap(value);
}
+ @Override
public byte[] toArray(byte[] value)
{
return value;
}
+ @Override
public byte[] toArray(byte[] value, int offset, int length)
{
if (value == null)
@@ -134,159 +150,196 @@ public class ByteArrayAccessor implements
ValueAccessor<byte[]>
return slice(value, offset, length);
}
+ @Override
public String toString(byte[] value, Charset charset) throws
CharacterCodingException
{
return new String(value, charset);
}
+ @Override
public String toHex(byte[] value)
{
return Hex.bytesToHex(value);
}
+ @Override
public byte toByte(byte[] value)
{
return value[0];
}
+ @Override
public byte getByte(byte[] value, int offset)
{
return value[offset];
}
+ @Override
public short toShort(byte[] value)
{
return getShort(value, 0);
}
+ @Override
public short getShort(byte[] value, int offset)
{
return ByteArrayUtil.getShort(value, offset);
}
+ @Override
+ public int getUnsignedShort(byte[] value, int offset)
+ {
+ return ByteArrayUtil.getUnsignedShort(value, offset);
+ }
+
+ @Override
public int toInt(byte[] value)
{
return getInt(value, 0);
}
+ @Override
public int getInt(byte[] value, int offset)
{
return ByteArrayUtil.getInt(value, offset);
}
+ @Override
public long toLong(byte[] value)
{
return getLong(value, 0);
}
+ @Override
public long getLong(byte[] value, int offset)
{
return ByteArrayUtil.getLong(value, offset);
}
+ @Override
public float toFloat(byte[] value)
{
return ByteArrayUtil.getFloat(value, 0);
}
+ @Override
public double toDouble(byte[] value)
{
return ByteArrayUtil.getDouble(value, 0);
}
+ @Override
public UUID toUUID(byte[] value)
{
return new UUID(getLong(value, 0), getLong(value, 8));
}
+ @Override
public int putShort(byte[] dst, int offset, short value)
{
ByteArrayUtil.putShort(dst, offset, value);
return TypeSizes.SHORT_SIZE;
}
+ @Override
public int putInt(byte[] dst, int offset, int value)
{
ByteArrayUtil.putInt(dst, offset, value);
return TypeSizes.INT_SIZE;
}
+ @Override
public int putLong(byte[] dst, int offset, long value)
{
ByteArrayUtil.putLong(dst, offset, value);
return TypeSizes.LONG_SIZE;
}
+ @Override
public byte[] empty()
{
return EMPTY;
}
+ @Override
public byte[] valueOf(byte[] bytes)
{
return bytes;
}
+ @Override
public byte[] valueOf(ByteBuffer bytes)
{
return ByteBufferUtil.getArray(bytes);
}
+ @Override
public byte[] valueOf(String s, Charset charset)
{
return ByteArrayUtil.bytes(s, charset);
}
+ @Override
public byte[] valueOf(UUID v)
{
return UUIDGen.decompose(v);
}
+ @Override
public byte[] valueOf(boolean v)
{
return v ? new byte[] {1} : new byte[] {0};
}
+ @Override
public byte[] valueOf(byte v)
{
return ByteArrayUtil.bytes(v);
}
+ @Override
public byte[] valueOf(short v)
{
return ByteArrayUtil.bytes(v);
}
+ @Override
public byte[] valueOf(int v)
{
return ByteArrayUtil.bytes(v);
}
+ @Override
public byte[] valueOf(long v)
{
return ByteArrayUtil.bytes(v);
}
+ @Override
public byte[] valueOf(float v)
{
return ByteArrayUtil.bytes(v);
}
+ @Override
public byte[] valueOf(double v)
{
return ByteArrayUtil.bytes(v);
}
+ @Override
public <V2> byte[] convert(V2 src, ValueAccessor<V2> accessor)
{
return accessor.toArray(src);
}
+ @Override
public byte[] allocate(int size)
{
return new byte[size];
}
+ @Override
public ObjectFactory<byte[]> factory()
{
return factory;
diff --git a/src/java/org/apache/cassandra/db/marshal/ByteBufferAccessor.java
b/src/java/org/apache/cassandra/db/marshal/ByteBufferAccessor.java
index df27d8b..b7dfce6 100644
--- a/src/java/org/apache/cassandra/db/marshal/ByteBufferAccessor.java
+++ b/src/java/org/apache/cassandra/db/marshal/ByteBufferAccessor.java
@@ -42,54 +42,64 @@ public class ByteBufferAccessor implements
ValueAccessor<ByteBuffer>
private ByteBufferAccessor() {}
+ @Override
public int size(ByteBuffer value)
{
return value.remaining();
}
+ @Override
public ByteBuffer[] createArray(int length)
{
return new ByteBuffer[length];
}
+ @Override
public void write(ByteBuffer value, DataOutputPlus out) throws IOException
{
out.write(value);
}
+ @Override
public void write(ByteBuffer value, ByteBuffer out)
{
out.put(value.duplicate());
}
+ @Override
public <V2> int copyTo(ByteBuffer src, int srcOffset, V2 dst,
ValueAccessor<V2> dstAccessor, int dstOffset, int size)
{
dstAccessor.copyByteBufferTo(src, srcOffset, dst, dstOffset, size);
return size;
}
+ @Override
public int copyByteArrayTo(byte[] src, int srcOffset, ByteBuffer dst, int
dstOffset, int size)
{
FastByteOperations.copy(src, srcOffset, dst, dst.position() +
dstOffset, size);
return size;
}
+ @Override
public int copyByteBufferTo(ByteBuffer src, int srcOffset, ByteBuffer dst,
int dstOffset, int size)
{
FastByteOperations.copy(src, src.position() + srcOffset, dst,
dst.position() + dstOffset, size);
return size;
}
+ @Override
public void digest(ByteBuffer value, int offset, int size, Digest digest)
{
digest.update(value, value.position() + offset, size);
}
+ @Override
public ByteBuffer read(DataInputPlus in, int length) throws IOException
{
return ByteBufferUtil.read(in, length);
}
+ @Override
public ByteBuffer slice(ByteBuffer input, int offset, int length)
{
ByteBuffer copy = input.duplicate();
@@ -98,26 +108,31 @@ public class ByteBufferAccessor implements
ValueAccessor<ByteBuffer>
return copy;
}
+ @Override
public <V2> int compare(ByteBuffer left, V2 right, ValueAccessor<V2>
accessorR)
{
return accessorR.compareByteBufferTo(left, right);
}
+ @Override
public int compareByteArrayTo(byte[] left, ByteBuffer right)
{
return ByteBufferUtil.compare(left, right);
}
+ @Override
public int compareByteBufferTo(ByteBuffer left, ByteBuffer right)
{
return ByteBufferUtil.compareUnsigned(left, right);
}
+ @Override
public ByteBuffer toBuffer(ByteBuffer value)
{
return value;
}
+ @Override
public byte[] toArray(ByteBuffer value)
{
if (value == null)
@@ -125,6 +140,7 @@ public class ByteBufferAccessor implements
ValueAccessor<ByteBuffer>
return ByteBufferUtil.getArray(value);
}
+ @Override
public byte[] toArray(ByteBuffer value, int offset, int length)
{
if (value == null)
@@ -132,159 +148,196 @@ public class ByteBufferAccessor implements
ValueAccessor<ByteBuffer>
return ByteBufferUtil.getArray(value, value.position() + offset,
length);
}
+ @Override
public String toString(ByteBuffer value, Charset charset) throws
CharacterCodingException
{
return ByteBufferUtil.string(value, charset);
}
+ @Override
public ByteBuffer valueOf(UUID v)
{
return UUIDGen.toByteBuffer(v);
}
+ @Override
public String toHex(ByteBuffer value)
{
return ByteBufferUtil.bytesToHex(value);
}
+ @Override
public byte toByte(ByteBuffer value)
{
return ByteBufferUtil.toByte(value);
}
+ @Override
public byte getByte(ByteBuffer value, int offset)
{
return value.get(value.position() + offset);
}
+ @Override
public short toShort(ByteBuffer value)
{
return ByteBufferUtil.toShort(value);
}
+ @Override
public short getShort(ByteBuffer value, int offset)
{
return value.getShort(value.position() + offset);
}
+ @Override
+ public int getUnsignedShort(ByteBuffer value, int offset)
+ {
+ return ByteBufferUtil.getUnsignedShort(value, offset);
+ }
+
+ @Override
public int toInt(ByteBuffer value)
{
return ByteBufferUtil.toInt(value);
}
+ @Override
public int getInt(ByteBuffer value, int offset)
{
return value.getInt(value.position() + offset);
}
+ @Override
public long toLong(ByteBuffer value)
{
return ByteBufferUtil.toLong(value);
}
+ @Override
public long getLong(ByteBuffer value, int offset)
{
return value.getLong(value.position() + offset);
}
+ @Override
public float toFloat(ByteBuffer value)
{
return ByteBufferUtil.toFloat(value);
}
+ @Override
public double toDouble(ByteBuffer value)
{
return ByteBufferUtil.toDouble(value);
}
+ @Override
public UUID toUUID(ByteBuffer value)
{
return UUIDGen.getUUID(value);
}
+ @Override
public int putShort(ByteBuffer dst, int offset, short value)
{
dst.putShort(dst.position() + offset, value);
return TypeSizes.SHORT_SIZE;
}
+ @Override
public int putInt(ByteBuffer dst, int offset, int value)
{
dst.putInt(dst.position() + offset, value);
return TypeSizes.INT_SIZE;
}
+ @Override
public int putLong(ByteBuffer dst, int offset, long value)
{
dst.putLong(dst.position() + offset, value);
return TypeSizes.LONG_SIZE;
}
+ @Override
public ByteBuffer empty()
{
return ByteBufferUtil.EMPTY_BYTE_BUFFER;
}
+ @Override
public ByteBuffer valueOf(byte[] bytes)
{
return ByteBuffer.wrap(bytes);
}
+ @Override
public ByteBuffer valueOf(ByteBuffer bytes)
{
return bytes;
}
+ @Override
public ByteBuffer valueOf(String v, Charset charset)
{
return ByteBufferUtil.bytes(v, charset);
}
+ @Override
public ByteBuffer valueOf(boolean v)
{
return v ? ByteBuffer.wrap(new byte[] {1}) : ByteBuffer.wrap(new
byte[] {0});
}
+ @Override
public ByteBuffer valueOf(byte v)
{
return ByteBufferUtil.bytes(v);
}
+ @Override
public ByteBuffer valueOf(short v)
{
return ByteBufferUtil.bytes(v);
}
+ @Override
public ByteBuffer valueOf(int v)
{
return ByteBufferUtil.bytes(v);
}
+ @Override
public ByteBuffer valueOf(long v)
{
return ByteBufferUtil.bytes(v);
}
+ @Override
public ByteBuffer valueOf(float v)
{
return ByteBufferUtil.bytes(v);
}
+ @Override
public ByteBuffer valueOf(double v)
{
return ByteBufferUtil.bytes(v);
}
+ @Override
public <V2> ByteBuffer convert(V2 src, ValueAccessor<V2> accessor)
{
return accessor.toBuffer(src);
}
+ @Override
public ByteBuffer allocate(int size)
{
return ByteBuffer.allocate(size);
}
+ @Override
public ObjectFactory<ByteBuffer> factory()
{
return ByteBufferObjectFactory.instance;
diff --git a/src/java/org/apache/cassandra/db/marshal/CompositeType.java
b/src/java/org/apache/cassandra/db/marshal/CompositeType.java
index d7041b8..bf5e914a 100644
--- a/src/java/org/apache/cassandra/db/marshal/CompositeType.java
+++ b/src/java/org/apache/cassandra/db/marshal/CompositeType.java
@@ -247,7 +247,7 @@ public class CompositeType extends AbstractCompositeType
public static <V> boolean isStaticName(V value, ValueAccessor<V> accessor)
{
- return accessor.size(value) >= 2 && (accessor.getShortLength(value, 0)
& 0xFFFF) == STATIC_MARKER;
+ return accessor.size(value) >= 2 && (accessor.getUnsignedShort(value,
0) & 0xFFFF) == STATIC_MARKER;
}
@Override
diff --git a/src/java/org/apache/cassandra/db/marshal/ValueAccessor.java
b/src/java/org/apache/cassandra/db/marshal/ValueAccessor.java
index 8ab1569..10532ff 100644
--- a/src/java/org/apache/cassandra/db/marshal/ValueAccessor.java
+++ b/src/java/org/apache/cassandra/db/marshal/ValueAccessor.java
@@ -216,24 +216,16 @@ public interface ValueAccessor<V>
V slice(V input, int offset, int length);
/**
- * same as {@link ValueAccessor#slice(Object, int, int)}, except the
length is taked from the first
+ * same as {@link ValueAccessor#slice(Object, int, int)}, except the
length is taken from the first
* 2 bytes from the given offset (and not included in the return value)
*/
default V sliceWithShortLength(V input, int offset)
{
- int size = getShort(input, offset);
+ int size = getUnsignedShort(input, offset);
return slice(input, offset + 2, size);
}
/**
- * @return a short length prefix starting at {@param offset}
- */
- default int getShortLength(V v, int offset)
- {
- return getShort(v, offset);
- }
-
- /**
* lexicographically compare {@param left} to {@param right}
* @param <VR> backing type of
*/
@@ -311,6 +303,8 @@ public interface ValueAccessor<V>
short toShort(V value);
/** returns a short from offset {@param offset} */
short getShort(V value, int offset);
+ /** returns an unsigned short from offset {@param offset} */
+ int getUnsignedShort(V value, int offset);
/** returns an int from offset 0 */
int toInt(V value);
/** returns an int from offset {@param offset} */
diff --git a/src/java/org/apache/cassandra/utils/ByteArrayUtil.java
b/src/java/org/apache/cassandra/utils/ByteArrayUtil.java
index 559607c..75734ad 100644
--- a/src/java/org/apache/cassandra/utils/ByteArrayUtil.java
+++ b/src/java/org/apache/cassandra/utils/ByteArrayUtil.java
@@ -111,6 +111,10 @@ public class ByteArrayUtil
(b[off] << 8));
}
+ public static int getUnsignedShort(byte[] b, int off) {
+ return ((b[off] & 0xFF) << 8) | (b[off + 1] & 0xFF);
+ }
+
public static int getInt(byte[] b, int off) {
return ((b[off + 3] & 0xFF) ) +
((b[off + 2] & 0xFF) << 8) +
diff --git a/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
b/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
index fca989f..d0ab6b2 100644
--- a/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
+++ b/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
@@ -701,11 +701,15 @@ public class ByteBufferUtil
return false;
}
+ public static int getUnsignedShort(ByteBuffer bb, int position)
+ {
+ return ((bb.get(position) & 0xFF) << 8) | (bb.get(position + 1) &
0xFF);
+ }
+
// Doesn't change bb position
public static int getShortLength(ByteBuffer bb, int position)
{
- int length = (bb.get(position) & 0xFF) << 8;
- return length | (bb.get(position + 1) & 0xFF);
+ return getUnsignedShort(bb, position);
}
// changes bb position
diff --git a/test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java
b/test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java
index e79b90e..eb838d3 100644
--- a/test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java
+++ b/test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java
@@ -22,6 +22,8 @@ import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.util.*;
+import com.google.common.collect.Lists;
+import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.fail;
@@ -321,4 +323,24 @@ public class CompositeTypeTest
bb.rewind();
return bb;
}
+
+ private static <V> void testToFromString(ByteBuffer bytes,
ValueAccessor<V> accessor, CompositeType type)
+ {
+ V value = accessor.valueOf(bytes);
+ String s = type.getString(value, accessor);
+ ByteBuffer fromString = type.fromString(s);
+ Assert.assertEquals(bytes, fromString);
+ }
+
+
+ @Test
+ public void testLargeValues()
+ {
+ CompositeType type =
CompositeType.getInstance(Lists.newArrayList(BytesType.instance));
+ ByteBuffer expected = ByteBuffer.allocate(0xFFFE);
+ new Random(0).nextBytes(expected.array());
+ ByteBuffer serialized =
CompositeType.build(ByteBufferAccessor.instance, expected);
+ for (ValueAccessor<?> accessor : ValueAccessors.ACCESSORS)
+ testToFromString(serialized, accessor, type);
+ }
}
diff --git a/test/unit/org/apache/cassandra/db/marshal/ValueAccessorTest.java
b/test/unit/org/apache/cassandra/db/marshal/ValueAccessorTest.java
index 49851e9..566751b 100644
--- a/test/unit/org/apache/cassandra/db/marshal/ValueAccessorTest.java
+++ b/test/unit/org/apache/cassandra/db/marshal/ValueAccessorTest.java
@@ -18,6 +18,7 @@
package org.apache.cassandra.db.marshal;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Random;
@@ -26,10 +27,15 @@ import com.google.common.primitives.Shorts;
import org.junit.Assert;
import org.junit.Test;
+import org.apache.cassandra.io.util.DataOutputBuffer;
import org.apache.cassandra.utils.ByteArrayUtil;
import org.apache.cassandra.utils.ByteBufferUtil;
+import org.assertj.core.api.Assertions;
+import org.quicktheories.core.Gen;
+import org.quicktheories.generators.SourceDSL;
import static org.apache.cassandra.db.marshal.ValueAccessors.ACCESSORS;
+import static org.quicktheories.QuickTheory.qt;
public class ValueAccessorTest
{
@@ -129,4 +135,52 @@ public class ValueAccessorTest
testTypeConversion(i, accessor, random);
}
}
+
+ private static <V> void testReadWriteWithShortLength(ValueAccessor<V>
accessor, int size) throws IOException
+ {
+ Random random = new Random(size);
+ byte[] bytes = new byte[size];
+ random.nextBytes(bytes);
+ ByteBuffer buffer = ByteBuffer.wrap(bytes);
+
+ try (DataOutputBuffer out = new DataOutputBuffer(size + 2))
+ {
+ ByteBufferUtil.writeWithShortLength(buffer, out);
+ V flushed = accessor.valueOf(out.toByteArray());
+ V value = accessor.sliceWithShortLength(flushed, 0);
+ Assert.assertArrayEquals(bytes, accessor.toArray(value));
+ }
+ }
+
+ @Test
+ public void testReadWriteWithShortLength() throws IOException
+ {
+ int[] lengths = new int[]{0, 1, 2, 256, 0x8001, 0xFFFF};
+ for (int length : lengths)
+ {
+ for (ValueAccessor<?> accessor: ACCESSORS)
+ testReadWriteWithShortLength(accessor, length);
+ }
+ }
+
+ @Test
+ public void testUnsignedShort()
+ {
+ Gen<Integer> gen = SourceDSL.integers().between(0, Short.MAX_VALUE * 2
+ 1);
+
+ qt().forAll(gen).checkAssert(jint -> {
+ int size = jint;
+ for (ValueAccessor<Object> accessor: ACCESSORS)
+ {
+ Object value = accessor.allocate(5);
+ for (int offset : Arrays.asList(0, 3))
+ {
+ accessor.putShort(value, offset, (short) size); // testing
signed
+ Assertions.assertThat(accessor.getUnsignedShort(value,
offset))
+ .as("getUnsignedShort(putShort(unsigned_short))
!= unsigned_short for %s", accessor.getClass())
+ .isEqualTo(size);
+ }
+ }
+ });
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]