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 <bdeggles...@gmail.com>
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: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to