You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by bl...@apache.org on 2015/08/05 13:57:04 UTC

[3/3] cassandra git commit: Fix serialization of AbstractBounds

Fix serialization of AbstractBounds

patch by Sylvain Lebresne; reviewed by Benjamin Lerer for CASSANDRA-9775


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/bd7d1198
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/bd7d1198
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/bd7d1198

Branch: refs/heads/cassandra-3.0
Commit: bd7d1198ac1e02785e912c7cfbb504ddaab6bb93
Parents: 028df72
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Wed Aug 5 12:21:24 2015 +0200
Committer: blerer <be...@datastax.com>
Committed: Wed Aug 5 12:21:24 2015 +0200

----------------------------------------------------------------------
 src/java/org/apache/cassandra/db/DataRange.java | 14 ++++-
 .../apache/cassandra/dht/AbstractBounds.java    | 58 +++++++++++++++++---
 2 files changed, 61 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/bd7d1198/src/java/org/apache/cassandra/db/DataRange.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/DataRange.java b/src/java/org/apache/cassandra/db/DataRange.java
index 023f572..79b2448 100644
--- a/src/java/org/apache/cassandra/db/DataRange.java
+++ b/src/java/org/apache/cassandra/db/DataRange.java
@@ -42,7 +42,7 @@ public class DataRange
 {
     public static final Serializer serializer = new Serializer();
 
-    private final AbstractBounds<PartitionPosition> keyRange;
+    protected final AbstractBounds<PartitionPosition> keyRange;
     protected final ClusteringIndexFilter clusteringIndexFilter;
 
     /**
@@ -201,7 +201,7 @@ public class DataRange
      * @param range the range of partition keys to query.
      * @param comparator the comparator for the table queried.
      * @param lastReturned the clustering for the last result returned by the previous page, i.e. the result we want to start our new page
-     * from. This last returned must <b>must</b> correspond to left bound of {@code range} (in other words, {@code range.left} must be the
+     * from. This last returned <b>must</b> correspond to left bound of {@code range} (in other words, {@code range.left} must be the
      * partition key for that {@code lastReturned} result).
      * @param inclusive whether or not we want to include the {@code lastReturned} in the newly returned page of results.
      *
@@ -354,6 +354,16 @@ public class DataRange
         {
             return false;
         }
+
+        @Override
+        public String toString(CFMetaData metadata)
+        {
+            return String.format("range=%s pfilter=%s lastReturned=%s (%s)",
+                                 keyRange.getString(metadata.getKeyValidator()),
+                                 clusteringIndexFilter.toString(metadata),
+                                 lastReturned.toString(metadata),
+                                 inclusive ? "included" : "excluded");
+        }
     }
 
     public static class Serializer

http://git-wip-us.apache.org/repos/asf/cassandra/blob/bd7d1198/src/java/org/apache/cassandra/dht/AbstractBounds.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/dht/AbstractBounds.java b/src/java/org/apache/cassandra/dht/AbstractBounds.java
index d9a0c62..9e74eb8 100644
--- a/src/java/org/apache/cassandra/dht/AbstractBounds.java
+++ b/src/java/org/apache/cassandra/dht/AbstractBounds.java
@@ -27,6 +27,7 @@ import org.apache.cassandra.db.PartitionPosition;
 import org.apache.cassandra.db.TypeSizes;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.io.util.DataOutputPlus;
+import org.apache.cassandra.net.MessagingService;
 import org.apache.cassandra.utils.Pair;
 
 public abstract class AbstractBounds<T extends RingPosition<T>> implements Serializable
@@ -119,8 +120,13 @@ public abstract class AbstractBounds<T extends RingPosition<T>> implements Seria
 
     public static class AbstractBoundsSerializer<T extends RingPosition<T>> implements IPartitionerDependentSerializer<AbstractBounds<T>>
     {
+        private static final int IS_TOKEN_FLAG        = 0x01;
+        private static final int START_INCLUSIVE_FLAG = 0x02;
+        private static final int END_INCLUSIVE_FLAG   = 0x04;
+
         IPartitionerDependentSerializer<T> serializer;
 
+        // Use for pre-3.0 protocol
         private static int kindInt(AbstractBounds<?> ab)
         {
             int kind = ab instanceof Range ? Type.RANGE.ordinal() : Type.BOUNDS.ordinal();
@@ -129,6 +135,19 @@ public abstract class AbstractBounds<T extends RingPosition<T>> implements Seria
             return kind;
         }
 
+        // For from 3.0 onwards
+        private static int kindFlags(AbstractBounds<?> ab)
+        {
+            int flags = 0;
+            if (ab.left instanceof Token)
+                flags |= IS_TOKEN_FLAG;
+            if (ab.isStartInclusive())
+                flags |= START_INCLUSIVE_FLAG;
+            if (ab.isEndInclusive())
+                flags |= END_INCLUSIVE_FLAG;
+            return flags;
+        }
+
         public AbstractBoundsSerializer(IPartitionerDependentSerializer<T> serializer)
         {
             this.serializer = serializer;
@@ -140,30 +159,51 @@ public abstract class AbstractBounds<T extends RingPosition<T>> implements Seria
              * The first int tells us if it's a range or bounds (depending on the value) _and_ if it's tokens or keys (depending on the
              * sign). We use negative kind for keys so as to preserve the serialization of token from older version.
              */
-            out.writeInt(kindInt(range));
+            if (version < MessagingService.VERSION_30)
+                out.writeInt(kindInt(range));
+            else
+                out.writeByte(kindFlags(range));
             serializer.serialize(range.left, out, version);
             serializer.serialize(range.right, out, version);
         }
 
         public AbstractBounds<T> deserialize(DataInput in, IPartitioner p, int version) throws IOException
         {
-            int kind = in.readInt();
-            boolean isToken = kind >= 0;
-            if (!isToken)
-                kind = -(kind+1);
+            boolean isToken, startInclusive, endInclusive;
+            if (version < MessagingService.VERSION_30)
+            {
+                int kind = in.readInt();
+                isToken = kind >= 0;
+                if (!isToken)
+                    kind = -(kind+1);
+
+                // Pre-3.0, everything that wasa not a Range was (wrongly) serialized as a Bound;
+                startInclusive = kind != Type.RANGE.ordinal();
+                endInclusive = true;
+            }
+            else
+            {
+                int flags = in.readUnsignedByte();
+                isToken = (flags & IS_TOKEN_FLAG) != 0;
+                startInclusive = (flags & START_INCLUSIVE_FLAG) != 0;
+                endInclusive = (flags & END_INCLUSIVE_FLAG) != 0;
+            }
 
             T left = serializer.deserialize(in, p, version);
             T right = serializer.deserialize(in, p, version);
             assert isToken == left instanceof Token;
 
-            if (kind == Type.RANGE.ordinal())
-                return new Range<T>(left, right);
-            return new Bounds<T>(left, right);
+            if (startInclusive)
+                return endInclusive ? new Bounds<T>(left, right) : new IncludingExcludingBounds<T>(left, right);
+            else
+                return endInclusive ? new Range<T>(left, right) : new ExcludingBounds<T>(left, right);
         }
 
         public long serializedSize(AbstractBounds<T> ab, int version)
         {
-            int size = TypeSizes.sizeof(kindInt(ab));
+            int size = version < MessagingService.VERSION_30
+                     ? TypeSizes.sizeof(kindInt(ab))
+                     : 1;
             size += serializer.serializedSize(ab.left, version);
             size += serializer.serializedSize(ab.right, version);
             return size;