Return-Path: X-Original-To: apmail-cassandra-commits-archive@www.apache.org Delivered-To: apmail-cassandra-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 81A4C9911 for ; Wed, 22 Feb 2012 13:24:08 +0000 (UTC) Received: (qmail 66148 invoked by uid 500); 22 Feb 2012 13:24:08 -0000 Delivered-To: apmail-cassandra-commits-archive@cassandra.apache.org Received: (qmail 66123 invoked by uid 500); 22 Feb 2012 13:24:08 -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 66115 invoked by uid 99); 22 Feb 2012 13:24:08 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 22 Feb 2012 13:24:08 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.114] (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 22 Feb 2012 13:24:05 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id F150D8122B3; Wed, 22 Feb 2012 13:23:43 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: slebresne@apache.org To: commits@cassandra.apache.org X-Mailer: ASF-Git Admin Mailer Subject: [3/3] git commit: Fix short read protection Message-Id: <20120222132343.F150D8122B3@tyr.zones.apache.org> Date: Wed, 22 Feb 2012 13:23:43 +0000 (UTC) X-Virus-Checked: Checked by ClamAV on apache.org Fix short read protection patch by slebresne; reviewed by driftx for CASSANDRA-3934 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/8413d831 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/8413d831 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/8413d831 Branch: refs/heads/cassandra-1.1 Commit: 8413d831d12099e8f2764438f0f31ec8ea1830b0 Parents: 44ac7a0 Author: Sylvain Lebresne Authored: Wed Feb 22 14:21:53 2012 +0100 Committer: Sylvain Lebresne Committed: Wed Feb 22 14:21:53 2012 +0100 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cassandra/db/RetriedSliceFromReadCommand.java | 2 +- .../apache/cassandra/db/SliceFromReadCommand.java | 25 ++++++++++---- 3 files changed, 20 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/8413d831/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 5869d32..966f940 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -23,6 +23,7 @@ * remove the wait on hint future during write (CASSANDRA-3870) * (cqlsh) ignore missing CfDef opts (CASSANDRA-3933) * (cqlsh) look for cqlshlib relative to realpath (CASSANDRA-3767) + * Fix short read protection (CASSANDRA-3934) Merged from 0.8: * (Pig) fix CassandraStorage to use correct comparator in Super ColumnFamily case (CASSANDRA-3251) http://git-wip-us.apache.org/repos/asf/cassandra/blob/8413d831/src/java/org/apache/cassandra/db/RetriedSliceFromReadCommand.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/RetriedSliceFromReadCommand.java b/src/java/org/apache/cassandra/db/RetriedSliceFromReadCommand.java index 6890f9d..5e0ca13 100644 --- a/src/java/org/apache/cassandra/db/RetriedSliceFromReadCommand.java +++ b/src/java/org/apache/cassandra/db/RetriedSliceFromReadCommand.java @@ -53,7 +53,7 @@ public class RetriedSliceFromReadCommand extends SliceFromReadCommand } @Override - public int getRequestedCount() + public int getOriginalRequestedCount() { return originalCount; } http://git-wip-us.apache.org/repos/asf/cassandra/blob/8413d831/src/java/org/apache/cassandra/db/SliceFromReadCommand.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/SliceFromReadCommand.java b/src/java/org/apache/cassandra/db/SliceFromReadCommand.java index 51c1602..58b5e22 100644 --- a/src/java/org/apache/cassandra/db/SliceFromReadCommand.java +++ b/src/java/org/apache/cassandra/db/SliceFromReadCommand.java @@ -76,10 +76,16 @@ public class SliceFromReadCommand extends ReadCommand int liveColumnsInRow = row != null ? row.cf.getLiveColumnCount() : 0; assert maxLiveColumns <= count; - if ((maxLiveColumns == count) && (liveColumnsInRow < count)) + // We generate a retry if at least one node reply with count live columns but after merge we have less + // than the total number of column we are interested in (which may be < count on a retry) + if ((maxLiveColumns == count) && (liveColumnsInRow < getOriginalRequestedCount())) { - int retryCount = count + count - liveColumnsInRow; - return new RetriedSliceFromReadCommand(table, key, queryPath, start, finish, reversed, count, retryCount); + // We asked t (= count) live columns and got l (=liveColumnsInRow) ones. + // From that, we can estimate that on this row, for x requested + // columns, only l/t end up live after reconciliation. So for next + // round we want to ask x column so that x * (l/t) == t, i.e. x = t^2/l. + int retryCount = ((count * count) / liveColumnsInRow) + 1; + return new RetriedSliceFromReadCommand(table, key, queryPath, start, finish, reversed, getOriginalRequestedCount(), retryCount); } return null; @@ -93,11 +99,11 @@ public class SliceFromReadCommand extends ReadCommand int liveColumnsInRow = row.cf.getLiveColumnCount(); - if (liveColumnsInRow > getRequestedCount()) + if (liveColumnsInRow > getOriginalRequestedCount()) { - int columnsToTrim = liveColumnsInRow - getRequestedCount(); + int columnsToTrim = liveColumnsInRow - getOriginalRequestedCount(); - logger.debug("trimming {} live columns to the originally requested {}", row.cf.getLiveColumnCount(), getRequestedCount()); + logger.debug("trimming {} live columns to the originally requested {}", row.cf.getLiveColumnCount(), getOriginalRequestedCount()); Collection columns; if (reversed) @@ -122,7 +128,12 @@ public class SliceFromReadCommand extends ReadCommand } } - protected int getRequestedCount() + /** + * The original number of columns requested by the user. + * This can be different from count when the slice command is a retry (see + * RetriedSliceFromReadCommand) + */ + protected int getOriginalRequestedCount() { return count; }