Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id C55F5200B8B for ; Tue, 20 Sep 2016 04:32:16 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id C4243160AE1; Tue, 20 Sep 2016 02:32:16 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id E997F160ADF for ; Tue, 20 Sep 2016 04:32:15 +0200 (CEST) Received: (qmail 33083 invoked by uid 500); 20 Sep 2016 02:32:09 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 30547 invoked by uid 99); 20 Sep 2016 02:32:07 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 20 Sep 2016 02:32:07 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 93932E9437; Tue, 20 Sep 2016 02:32:07 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: zznate@apache.org To: commits@cassandra.apache.org Date: Tue, 20 Sep 2016 02:32:39 -0000 Message-Id: <7979637e98594a399c882cad48b020d3@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [33/50] [abbrv] cassandra git commit: Handle composite prefixes with final EOC=0 as in 2.x and refactor LegacyLayout.decodeBound archived-at: Tue, 20 Sep 2016 02:32:17 -0000 Handle composite prefixes with final EOC=0 as in 2.x and refactor LegacyLayout.decodeBound patch by Stefania Alborghetti and Sylvain Lebresne; reviewed by Tyler Hobbs and Sylvain Lebresne for CASSANDRA-12423 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/d600f51e Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/d600f51e Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/d600f51e Branch: refs/heads/cassandra-3.9 Commit: d600f51ee1a3eb7b30ce3c409129567b70c22012 Parents: 932f3eb Author: Stefania Alborghetti Authored: Tue Aug 30 16:08:09 2016 +0800 Committer: Stefania Alborghetti Committed: Mon Sep 12 16:56:30 2016 +0800 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../org/apache/cassandra/db/LegacyLayout.java | 64 +++++++++++--------- .../cassandra/db/marshal/CompositeType.java | 26 -------- 3 files changed, 37 insertions(+), 54 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/d600f51e/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 459d591..f0ec3e3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0.9 + * Handle composite prefixes with final EOC=0 as in 2.x and refactor LegacyLayout.decodeBound (CASSANDRA-12423) * Fix paging for 2.x to 3.x upgrades (CASSANDRA-11195) * select_distinct_with_deletions_test failing on non-vnode environments (CASSANDRA-11126) * Stack Overflow returned to queries while upgrading (CASSANDRA-12527) http://git-wip-us.apache.org/repos/asf/cassandra/blob/d600f51e/src/java/org/apache/cassandra/db/LegacyLayout.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/LegacyLayout.java b/src/java/org/apache/cassandra/db/LegacyLayout.java index 65f9d3f..c8e7536 100644 --- a/src/java/org/apache/cassandra/db/LegacyLayout.java +++ b/src/java/org/apache/cassandra/db/LegacyLayout.java @@ -186,41 +186,49 @@ public abstract class LegacyLayout if (!bound.hasRemaining()) return isStart ? LegacyBound.BOTTOM : LegacyBound.TOP; - List components = metadata.isCompound() - ? CompositeType.deconstruct(bound) - : Collections.singletonList(new CompositeType.CompositeComponent(bound, (byte) 0)); - - // Either it's a prefix of the clustering, or it's the bound of a collection range tombstone (and thus has - // the collection column name) - assert components.size() <= metadata.comparator.size() || (!metadata.isCompactTable() && components.size() == metadata.comparator.size() + 1); - - List prefix = components.size() <= metadata.comparator.size() - ? components - : components.subList(0, metadata.comparator.size()); - Slice.Bound.Kind boundKind; + if (!metadata.isCompound()) + { + // The non compound case is a lot easier, in that there is no EOC nor collection to worry about, so dealing + // with that first. + return new LegacyBound(isStart ? Slice.Bound.inclusiveStartOf(bound) : Slice.Bound.inclusiveEndOf(bound), false, null); + } + + int clusteringSize = metadata.comparator.size(); + + List components = CompositeType.splitName(bound); + byte eoc = CompositeType.lastEOC(bound); + + // There can be more components than the clustering size only in the case this is the bound of a collection + // range tombstone. In which case, there is exactly one more component, and that component is the name of the + // collection being selected/deleted. + assert components.size() <= clusteringSize || (!metadata.isCompactTable() && components.size() == clusteringSize + 1); + + ColumnDefinition collectionName = null; + if (components.size() > clusteringSize) + collectionName = metadata.getColumnDefinition(components.remove(clusteringSize)); + + boolean isInclusive; if (isStart) { - if (components.get(components.size() - 1).eoc > 0) - boundKind = Slice.Bound.Kind.EXCL_START_BOUND; - else - boundKind = Slice.Bound.Kind.INCL_START_BOUND; + isInclusive = eoc <= 0; } else { - if (components.get(components.size() - 1).eoc < 0) - boundKind = Slice.Bound.Kind.EXCL_END_BOUND; - else - boundKind = Slice.Bound.Kind.INCL_END_BOUND; - } + isInclusive = eoc >= 0; - ByteBuffer[] prefixValues = new ByteBuffer[prefix.size()]; - for (int i = 0; i < prefix.size(); i++) - prefixValues[i] = prefix.get(i).value; - Slice.Bound sb = Slice.Bound.create(boundKind, prefixValues); + // for an end bound, if we only have a prefix of all the components and the final EOC is zero, + // then it should only match up to the prefix but no further, that is, it is an inclusive bound + // of the exact prefix but an exclusive bound of anything beyond it, so adding an empty + // composite value ensures this behavior, see CASSANDRA-12423 for more details + if (eoc == 0 && components.size() < clusteringSize) + { + components.add(ByteBufferUtil.EMPTY_BYTE_BUFFER); + isInclusive = false; + } + } - ColumnDefinition collectionName = components.size() == metadata.comparator.size() + 1 - ? metadata.getColumnDefinition(components.get(metadata.comparator.size()).value) - : null; + Slice.Bound.Kind boundKind = Slice.Bound.boundKind(isStart, isInclusive); + Slice.Bound sb = Slice.Bound.create(boundKind, components.toArray(new ByteBuffer[components.size()])); return new LegacyBound(sb, metadata.isCompound() && CompositeType.isStaticName(bound), collectionName); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/d600f51e/src/java/org/apache/cassandra/db/marshal/CompositeType.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/marshal/CompositeType.java b/src/java/org/apache/cassandra/db/marshal/CompositeType.java index d005fd7..52d6d39 100644 --- a/src/java/org/apache/cassandra/db/marshal/CompositeType.java +++ b/src/java/org/apache/cassandra/db/marshal/CompositeType.java @@ -227,32 +227,6 @@ public class CompositeType extends AbstractCompositeType return null; } - public static class CompositeComponent - { - public ByteBuffer value; - public byte eoc; - - public CompositeComponent(ByteBuffer value, byte eoc) - { - this.value = value; - this.eoc = eoc; - } - } - - public static List deconstruct(ByteBuffer bytes) - { - List list = new ArrayList<>(); - ByteBuffer bb = bytes.duplicate(); - readStatic(bb); - while (bb.remaining() > 0) - { - ByteBuffer value = ByteBufferUtil.readBytesWithShortLength(bb); - byte eoc = bb.get(); - list.add(new CompositeComponent(value, eoc)); - } - return list; - } - // Extract CQL3 column name from the full column name. public ByteBuffer extractLastComponent(ByteBuffer bb) {