10579: fix NativeCell behaviour when clustering components > 32K in size
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/986a1a76 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/986a1a76 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/986a1a76 Branch: refs/heads/trunk Commit: 986a1a769437bf1e47248e257772a074c27bac92 Parents: 83fb3cc Author: Benedict Elliott Smith <bened...@apache.org> Authored: Mon Oct 26 16:50:39 2015 +0000 Committer: Benedict Elliott Smith <bened...@apache.org> Committed: Mon Nov 2 16:40:35 2015 +0000 ---------------------------------------------------------------------- .../cassandra/utils/btree/NodeBuilder.java | 9 +++--- .../cassandra/utils/memory/MemoryUtil.java | 2 +- .../org/apache/cassandra/db/NativeCellTest.java | 31 +++++++++++++++++++- 3 files changed, 36 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/986a1a76/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java b/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java index 9d57182..0e304e5 100644 --- a/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java +++ b/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java @@ -185,9 +185,8 @@ final class NodeBuilder } else { - // if not found, we need to apply updateFunction still - key = updateFunction.apply(key); - addNewKey(key); // handles splitting parent if necessary via ensureRoom + // if not found, we need to apply updateFunction still, which is handled in addNewKey + addNewKey(key); } // done, so return null @@ -315,7 +314,9 @@ final class NodeBuilder copyFromKeyPosition++; } - // puts the provided key in the builder, with no impact on treatment of data from copyf + // applies the updateFunction + // puts the resulting key into the builder + // splits the parent if necessary via ensureRoom void addNewKey(Object key) { ensureRoom(buildKeyPosition + 1); http://git-wip-us.apache.org/repos/asf/cassandra/blob/986a1a76/src/java/org/apache/cassandra/utils/memory/MemoryUtil.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/utils/memory/MemoryUtil.java b/src/java/org/apache/cassandra/utils/memory/MemoryUtil.java index 57edc52..f96957d 100644 --- a/src/java/org/apache/cassandra/utils/memory/MemoryUtil.java +++ b/src/java/org/apache/cassandra/utils/memory/MemoryUtil.java @@ -98,7 +98,7 @@ public abstract class MemoryUtil public static int getShort(long address) { - return UNALIGNED ? unsafe.getShort(address) : getShortByByte(address); + return UNALIGNED ? unsafe.getShort(address) & 0xffff : getShortByByte(address); } public static int getInt(long address) http://git-wip-us.apache.org/repos/asf/cassandra/blob/986a1a76/test/unit/org/apache/cassandra/db/NativeCellTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/db/NativeCellTest.java b/test/unit/org/apache/cassandra/db/NativeCellTest.java index 6a2bf73..70b7b87 100644 --- a/test/unit/org/apache/cassandra/db/NativeCellTest.java +++ b/test/unit/org/apache/cassandra/db/NativeCellTest.java @@ -85,9 +85,38 @@ public class NativeCellTest new Name(simpleSparse(new ColumnIdentifier("a", true)), new SimpleSparseCellNameType(UTF8Type.instance)), new Name(compositeDense(bytes("a"), bytes("b")), new CompoundDenseCellNameType(Arrays.<AbstractType<?>>asList(UTF8Type.instance, UTF8Type.instance))), new Name(compositeSparse(bytess("b", "c"), new ColumnIdentifier("a", true), false), new CompoundSparseCellNameType(Arrays.<AbstractType<?>>asList(UTF8Type.instance, UTF8Type.instance))), - new Name(compositeSparse(bytess("b", "c"), new ColumnIdentifier("a", true), true), new CompoundSparseCellNameType(Arrays.<AbstractType<?>>asList(UTF8Type.instance, UTF8Type.instance))) + new Name(compositeSparse(bytess("b", "c"), new ColumnIdentifier("a", true), true), new CompoundSparseCellNameType(Arrays.<AbstractType<?>>asList(UTF8Type.instance, UTF8Type.instance))), + new Name(simpleDense(huge('a', 40000)), new SimpleDenseCellNameType(UTF8Type.instance)), + new Name(simpleSparse(new ColumnIdentifier(hugestr('a', 40000), true)), new SimpleSparseCellNameType(UTF8Type.instance)), + new Name(compositeDense(huge('a', 20000), huge('b', 20000)), new CompoundDenseCellNameType(Arrays.<AbstractType<?>>asList(UTF8Type.instance, UTF8Type.instance))), + new Name(compositeSparse(huges(40000, 'b', 'c'), new ColumnIdentifier(hugestr('a', 10000), true), false), new CompoundSparseCellNameType(Arrays.<AbstractType<?>>asList(UTF8Type.instance, UTF8Type.instance))), + new Name(compositeSparse(huges(40000, 'b', 'c'), new ColumnIdentifier(hugestr('a', 10000), true), true), new CompoundSparseCellNameType(Arrays.<AbstractType<?>>asList(UTF8Type.instance, UTF8Type.instance))) }; + private static ByteBuffer huge(char ch, int count) + { + return bytes(hugestr(ch, count)); + } + + private static ByteBuffer[] huges(int count, char ... chs) + { + ByteBuffer[] r = new ByteBuffer[chs.length]; + for (int i = 0 ; i < chs.length ; i++) + r[i] = huge(chs[i], count / chs.length); + return r; + } + + private static String hugestr(char ch, int count) + { + ThreadLocalRandom random = ThreadLocalRandom.current(); + byte[] bytes = new byte[count]; + random.nextBytes(bytes); + bytes[0] = (byte) ch; + for (int i = 0 ; i < bytes.length ; i++) + bytes[i] &= 0x7f; + return new String(bytes); + } + private static final CFMetaData metadata = new CFMetaData("", "", ColumnFamilyType.Standard, null); static {