Clarify ClusteringPrefix hierarchy

Patch by Branimir Lambov; reviewed by Sylvain Lebresne for CASSANDRA-11213


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

Branch: refs/heads/trunk
Commit: 2cc26eba7a742eb23e95b027bc611c924c233e1e
Parents: 94ca769
Author: Branimir Lambov <[email protected]>
Authored: Wed Apr 6 11:47:23 2016 +0300
Committer: Sylvain Lebresne <[email protected]>
Committed: Thu Apr 28 14:32:36 2016 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../ClusteringColumnRestrictions.java           |   2 +-
 .../restrictions/StatementRestrictions.java     |   2 +-
 .../cql3/statements/ModificationStatement.java  |  10 +-
 .../cql3/statements/SelectStatement.java        |  16 +-
 .../db/AbstractReadCommandBuilder.java          |  16 +-
 src/java/org/apache/cassandra/db/CBuilder.java  |  30 +-
 .../apache/cassandra/db/ClusteringBound.java    | 151 ++++++++++
 .../cassandra/db/ClusteringBoundOrBoundary.java | 163 +++++++++++
 .../apache/cassandra/db/ClusteringBoundary.java |  45 +++
 .../apache/cassandra/db/ClusteringPrefix.java   |  30 +-
 .../org/apache/cassandra/db/LegacyLayout.java   |  42 +--
 .../org/apache/cassandra/db/MultiCBuilder.java  |  37 ++-
 .../cassandra/db/MutableDeletionInfo.java       |   4 +-
 .../org/apache/cassandra/db/RangeTombstone.java | 142 ----------
 .../apache/cassandra/db/RangeTombstoneList.java |  56 ++--
 .../org/apache/cassandra/db/ReadCommand.java    |  10 +-
 .../org/apache/cassandra/db/Serializers.java    |   8 +-
 src/java/org/apache/cassandra/db/Slice.java     | 278 ++-----------------
 src/java/org/apache/cassandra/db/Slices.java    |  10 +-
 .../cassandra/db/UnfilteredDeserializer.java    |   8 +-
 .../columniterator/AbstractSSTableIterator.java |   6 +-
 .../db/columniterator/SSTableIterator.java      |   8 +-
 .../columniterator/SSTableReversedIterator.java |   6 +-
 .../db/partitions/AbstractBTreePartition.java   |   4 +-
 .../db/rows/AbstractRangeTombstoneMarker.java   |  12 +-
 .../db/rows/RangeTombstoneBoundMarker.java      |  22 +-
 .../db/rows/RangeTombstoneBoundaryMarker.java   |  20 +-
 .../cassandra/db/rows/RangeTombstoneMarker.java |   9 +-
 .../db/rows/RowAndDeletionMergeIterator.java    |   4 +-
 .../UnfilteredRowIteratorWithLowerBound.java    |  15 +-
 .../cassandra/db/rows/UnfilteredSerializer.java |  14 +-
 .../index/internal/CassandraIndexSearcher.java  |  10 +-
 .../apache/cassandra/service/DataResolver.java  |   6 +-
 .../cassandra/thrift/CassandraServer.java       |  10 +-
 .../apache/cassandra/tools/JsonTransformer.java |   8 +-
 .../cql3/TombstonesWithIndexedSSTableTest.java  |   1 -
 .../ClusteringColumnRestrictionsTest.java       |  64 ++---
 .../org/apache/cassandra/db/KeyspaceTest.java   |  12 +-
 .../cassandra/db/RangeTombstoneListTest.java    |  16 +-
 .../apache/cassandra/db/RangeTombstoneTest.java |   4 +-
 test/unit/org/apache/cassandra/db/RowTest.java  |  10 +-
 .../db/SinglePartitionSliceCommandTest.java     |   2 +-
 .../apache/cassandra/db/filter/SliceTest.java   |   4 +-
 .../partition/PartitionImplementationTest.java  |   3 +-
 .../rows/RowAndDeletionMergeIteratorTest.java   |  39 ++-
 .../rows/UnfilteredRowIteratorsMergeTest.java   |  18 +-
 47 files changed, 680 insertions(+), 708 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index f78ea90..78518b6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.6
+ * Clarify ClusteringPrefix hierarchy (CASSANDRA-11213)
  * Always perform collision check before joining ring (CASSANDRA-10134)
  * SSTableWriter output discrepancy (CASSANDRA-11646)
  * Fix potential timeout in NativeTransportService.testConcurrentDestroys 
(CASSANDRA-10756)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java
 
b/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java
index ab16ebc..837ee13 100644
--- 
a/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java
+++ 
b/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java
@@ -113,7 +113,7 @@ final class ClusteringColumnRestrictions extends 
RestrictionSetWrapper
         return builder.build();
     }
 
-    public NavigableSet<Slice.Bound> boundsAsClustering(Bound bound, 
QueryOptions options) throws InvalidRequestException
+    public NavigableSet<ClusteringBound> boundsAsClustering(Bound bound, 
QueryOptions options) throws InvalidRequestException
     {
         MultiCBuilder builder = MultiCBuilder.create(comparator, hasIN() || 
hasMultiColumnSlice());
         int keyPosition = 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java 
b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
index c4d7622..43a912d 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
@@ -721,7 +721,7 @@ public final class StatementRestrictions
      * @param options the query options
      * @return the bounds (start or end) of the clustering columns
      */
-    public NavigableSet<Slice.Bound> getClusteringColumnsBounds(Bound b, 
QueryOptions options)
+    public NavigableSet<ClusteringBound> getClusteringColumnsBounds(Bound b, 
QueryOptions options)
     {
         return clusteringColumnsRestrictions.boundsAsClustering(b, options);
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java 
b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
index 7243daa..6224457 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
@@ -674,8 +674,8 @@ public abstract class ModificationStatement implements 
CQLStatement
 
     private Slices createSlice(QueryOptions options)
     {
-        SortedSet<Slice.Bound> startBounds = 
restrictions.getClusteringColumnsBounds(Bound.START, options);
-        SortedSet<Slice.Bound> endBounds = 
restrictions.getClusteringColumnsBounds(Bound.END, options);
+        SortedSet<ClusteringBound> startBounds = 
restrictions.getClusteringColumnsBounds(Bound.START, options);
+        SortedSet<ClusteringBound> endBounds = 
restrictions.getClusteringColumnsBounds(Bound.END, options);
 
         return toSlices(startBounds, endBounds);
     }
@@ -714,14 +714,14 @@ public abstract class ModificationStatement implements 
CQLStatement
         return new UpdateParameters(cfm, updatedColumns(), options, 
getTimestamp(now, options), getTimeToLive(options), lists);
     }
 
-    private Slices toSlices(SortedSet<Slice.Bound> startBounds, 
SortedSet<Slice.Bound> endBounds)
+    private Slices toSlices(SortedSet<ClusteringBound> startBounds, 
SortedSet<ClusteringBound> endBounds)
     {
         assert startBounds.size() == endBounds.size();
 
         Slices.Builder builder = new Slices.Builder(cfm.comparator);
 
-        Iterator<Slice.Bound> starts = startBounds.iterator();
-        Iterator<Slice.Bound> ends = endBounds.iterator();
+        Iterator<ClusteringBound> starts = startBounds.iterator();
+        Iterator<ClusteringBound> ends = endBounds.iterator();
 
         while (starts.hasNext())
         {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java 
b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
index e46cb06..3f72bd8 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@ -553,27 +553,27 @@ public class SelectStatement implements CQLStatement
     private Slices makeSlices(QueryOptions options)
     throws InvalidRequestException
     {
-        SortedSet<Slice.Bound> startBounds = 
restrictions.getClusteringColumnsBounds(Bound.START, options);
-        SortedSet<Slice.Bound> endBounds = 
restrictions.getClusteringColumnsBounds(Bound.END, options);
+        SortedSet<ClusteringBound> startBounds = 
restrictions.getClusteringColumnsBounds(Bound.START, options);
+        SortedSet<ClusteringBound> endBounds = 
restrictions.getClusteringColumnsBounds(Bound.END, options);
         assert startBounds.size() == endBounds.size();
 
         // The case where startBounds == 1 is common enough that it's worth 
optimizing
         if (startBounds.size() == 1)
         {
-            Slice.Bound start = startBounds.first();
-            Slice.Bound end = endBounds.first();
+            ClusteringBound start = startBounds.first();
+            ClusteringBound end = endBounds.first();
             return cfm.comparator.compare(start, end) > 0
                  ? Slices.NONE
                  : Slices.with(cfm.comparator, Slice.make(start, end));
         }
 
         Slices.Builder builder = new Slices.Builder(cfm.comparator, 
startBounds.size());
-        Iterator<Slice.Bound> startIter = startBounds.iterator();
-        Iterator<Slice.Bound> endIter = endBounds.iterator();
+        Iterator<ClusteringBound> startIter = startBounds.iterator();
+        Iterator<ClusteringBound> endIter = endBounds.iterator();
         while (startIter.hasNext() && endIter.hasNext())
         {
-            Slice.Bound start = startIter.next();
-            Slice.Bound end = endIter.next();
+            ClusteringBound start = startIter.next();
+            ClusteringBound end = endIter.next();
 
             // Ignore slices that are nonsensical
             if (cfm.comparator.compare(start, end) > 0)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/AbstractReadCommandBuilder.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/AbstractReadCommandBuilder.java 
b/src/java/org/apache/cassandra/db/AbstractReadCommandBuilder.java
index dab22c7..849e684 100644
--- a/src/java/org/apache/cassandra/db/AbstractReadCommandBuilder.java
+++ b/src/java/org/apache/cassandra/db/AbstractReadCommandBuilder.java
@@ -43,8 +43,8 @@ public abstract class AbstractReadCommandBuilder
     protected Set<ColumnIdentifier> columns;
     protected final RowFilter filter = RowFilter.create();
 
-    private Slice.Bound lowerClusteringBound;
-    private Slice.Bound upperClusteringBound;
+    private ClusteringBound lowerClusteringBound;
+    private ClusteringBound upperClusteringBound;
 
     private NavigableSet<Clustering> clusterings;
 
@@ -64,28 +64,28 @@ public abstract class AbstractReadCommandBuilder
     public AbstractReadCommandBuilder fromIncl(Object... values)
     {
         assert lowerClusteringBound == null && clusterings == null;
-        this.lowerClusteringBound = 
Slice.Bound.create(cfs.metadata.comparator, true, true, values);
+        this.lowerClusteringBound = 
ClusteringBound.create(cfs.metadata.comparator, true, true, values);
         return this;
     }
 
     public AbstractReadCommandBuilder fromExcl(Object... values)
     {
         assert lowerClusteringBound == null && clusterings == null;
-        this.lowerClusteringBound = 
Slice.Bound.create(cfs.metadata.comparator, true, false, values);
+        this.lowerClusteringBound = 
ClusteringBound.create(cfs.metadata.comparator, true, false, values);
         return this;
     }
 
     public AbstractReadCommandBuilder toIncl(Object... values)
     {
         assert upperClusteringBound == null && clusterings == null;
-        this.upperClusteringBound = 
Slice.Bound.create(cfs.metadata.comparator, false, true, values);
+        this.upperClusteringBound = 
ClusteringBound.create(cfs.metadata.comparator, false, true, values);
         return this;
     }
 
     public AbstractReadCommandBuilder toExcl(Object... values)
     {
         assert upperClusteringBound == null && clusterings == null;
-        this.upperClusteringBound = 
Slice.Bound.create(cfs.metadata.comparator, false, false, values);
+        this.upperClusteringBound = 
ClusteringBound.create(cfs.metadata.comparator, false, false, values);
         return this;
     }
 
@@ -195,8 +195,8 @@ public abstract class AbstractReadCommandBuilder
         }
         else
         {
-            Slice slice = Slice.make(lowerClusteringBound == null ? 
Slice.Bound.BOTTOM : lowerClusteringBound,
-                                     upperClusteringBound == null ? 
Slice.Bound.TOP : upperClusteringBound);
+            Slice slice = Slice.make(lowerClusteringBound == null ? 
ClusteringBound.BOTTOM : lowerClusteringBound,
+                                     upperClusteringBound == null ? 
ClusteringBound.TOP : upperClusteringBound);
             return new 
ClusteringIndexSliceFilter(Slices.with(cfs.metadata.comparator, slice), 
reversed);
         }
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/CBuilder.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/CBuilder.java 
b/src/java/org/apache/cassandra/db/CBuilder.java
index 73b575f..be56394 100644
--- a/src/java/org/apache/cassandra/db/CBuilder.java
+++ b/src/java/org/apache/cassandra/db/CBuilder.java
@@ -24,7 +24,7 @@ import java.util.List;
 import org.apache.cassandra.db.marshal.AbstractType;
 
 /**
- * Allows to build ClusteringPrefixes, either Clustering or Slice.Bound.
+ * Allows to build ClusteringPrefixes, either Clustering or ClusteringBound.
  */
 public abstract class CBuilder
 {
@@ -60,7 +60,7 @@ public abstract class CBuilder
             return Clustering.STATIC_CLUSTERING;
         }
 
-        public Slice.Bound buildBound(boolean isStart, boolean isInclusive)
+        public ClusteringBound buildBound(boolean isStart, boolean isInclusive)
         {
             throw new UnsupportedOperationException();
         }
@@ -80,12 +80,12 @@ public abstract class CBuilder
             throw new UnsupportedOperationException();
         }
 
-        public Slice.Bound buildBoundWith(ByteBuffer value, boolean isStart, 
boolean isInclusive)
+        public ClusteringBound buildBoundWith(ByteBuffer value, boolean 
isStart, boolean isInclusive)
         {
             throw new UnsupportedOperationException();
         }
 
-        public Slice.Bound buildBoundWith(List<ByteBuffer> newValues, boolean 
isStart, boolean isInclusive)
+        public ClusteringBound buildBoundWith(List<ByteBuffer> newValues, 
boolean isStart, boolean isInclusive)
         {
             throw new UnsupportedOperationException();
         }
@@ -102,12 +102,12 @@ public abstract class CBuilder
     public abstract CBuilder add(ByteBuffer value);
     public abstract CBuilder add(Object value);
     public abstract Clustering build();
-    public abstract Slice.Bound buildBound(boolean isStart, boolean 
isInclusive);
+    public abstract ClusteringBound buildBound(boolean isStart, boolean 
isInclusive);
     public abstract Slice buildSlice();
     public abstract Clustering buildWith(ByteBuffer value);
     public abstract Clustering buildWith(List<ByteBuffer> newValues);
-    public abstract Slice.Bound buildBoundWith(ByteBuffer value, boolean 
isStart, boolean isInclusive);
-    public abstract Slice.Bound buildBoundWith(List<ByteBuffer> newValues, 
boolean isStart, boolean isInclusive);
+    public abstract ClusteringBound buildBoundWith(ByteBuffer value, boolean 
isStart, boolean isInclusive);
+    public abstract ClusteringBound buildBoundWith(List<ByteBuffer> newValues, 
boolean isStart, boolean isInclusive);
 
     private static class ArrayBackedBuilder extends CBuilder
     {
@@ -165,17 +165,17 @@ public abstract class CBuilder
             return size == 0 ? Clustering.EMPTY : Clustering.make(values);
         }
 
-        public Slice.Bound buildBound(boolean isStart, boolean isInclusive)
+        public ClusteringBound buildBound(boolean isStart, boolean isInclusive)
         {
             // We don't allow to add more element to a builder that has been 
built so
             // that we don't have to copy values (even though we have to do it 
in most cases).
             built = true;
 
             if (size == 0)
-                return isStart ? Slice.Bound.BOTTOM : Slice.Bound.TOP;
+                return isStart ? ClusteringBound.BOTTOM : ClusteringBound.TOP;
 
-            return Slice.Bound.create(Slice.Bound.boundKind(isStart, 
isInclusive),
-                                      size == values.length ? values : 
Arrays.copyOfRange(values, 0, size));
+            return ClusteringBound.create(ClusteringBound.boundKind(isStart, 
isInclusive),
+                                size == values.length ? values : 
Arrays.copyOfRange(values, 0, size));
         }
 
         public Slice buildSlice()
@@ -210,21 +210,21 @@ public abstract class CBuilder
             return Clustering.make(buffers);
         }
 
-        public Slice.Bound buildBoundWith(ByteBuffer value, boolean isStart, 
boolean isInclusive)
+        public ClusteringBound buildBoundWith(ByteBuffer value, boolean 
isStart, boolean isInclusive)
         {
             ByteBuffer[] newValues = Arrays.copyOf(values, size+1);
             newValues[size] = value;
-            return Slice.Bound.create(Slice.Bound.boundKind(isStart, 
isInclusive), newValues);
+            return ClusteringBound.create(ClusteringBound.boundKind(isStart, 
isInclusive), newValues);
         }
 
-        public Slice.Bound buildBoundWith(List<ByteBuffer> newValues, boolean 
isStart, boolean isInclusive)
+        public ClusteringBound buildBoundWith(List<ByteBuffer> newValues, 
boolean isStart, boolean isInclusive)
         {
             ByteBuffer[] buffers = Arrays.copyOf(values, size + 
newValues.size());
             int newSize = size;
             for (ByteBuffer value : newValues)
                 buffers[newSize++] = value;
 
-            return Slice.Bound.create(Slice.Bound.boundKind(isStart, 
isInclusive), buffers);
+            return ClusteringBound.create(ClusteringBound.boundKind(isStart, 
isInclusive), buffers);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/ClusteringBound.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ClusteringBound.java 
b/src/java/org/apache/cassandra/db/ClusteringBound.java
new file mode 100644
index 0000000..6366a37
--- /dev/null
+++ b/src/java/org/apache/cassandra/db/ClusteringBound.java
@@ -0,0 +1,151 @@
+package org.apache.cassandra.db;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.apache.cassandra.utils.memory.AbstractAllocator;
+
+/**
+ * The start or end of a range of clusterings, either inclusive or exclusive.
+ */
+public class ClusteringBound extends ClusteringBoundOrBoundary
+{
+    /** The smallest start bound, i.e. the one that starts before any row. */
+    public static final ClusteringBound BOTTOM = new 
ClusteringBound(Kind.INCL_START_BOUND, EMPTY_VALUES_ARRAY);
+    /** The biggest end bound, i.e. the one that ends after any row. */
+    public static final ClusteringBound TOP = new 
ClusteringBound(Kind.INCL_END_BOUND, EMPTY_VALUES_ARRAY);
+
+    protected ClusteringBound(Kind kind, ByteBuffer[] values)
+    {
+        super(kind, values);
+    }
+
+    public static ClusteringBound create(Kind kind, ByteBuffer[] values)
+    {
+        assert !kind.isBoundary();
+        return new ClusteringBound(kind, values);
+    }
+
+    public static Kind boundKind(boolean isStart, boolean isInclusive)
+    {
+        return isStart
+             ? (isInclusive ? Kind.INCL_START_BOUND : Kind.EXCL_START_BOUND)
+             : (isInclusive ? Kind.INCL_END_BOUND : Kind.EXCL_END_BOUND);
+    }
+
+    public static ClusteringBound inclusiveStartOf(ByteBuffer... values)
+    {
+        return create(Kind.INCL_START_BOUND, values);
+    }
+
+    public static ClusteringBound inclusiveEndOf(ByteBuffer... values)
+    {
+        return create(Kind.INCL_END_BOUND, values);
+    }
+
+    public static ClusteringBound exclusiveStartOf(ByteBuffer... values)
+    {
+        return create(Kind.EXCL_START_BOUND, values);
+    }
+
+    public static ClusteringBound exclusiveEndOf(ByteBuffer... values)
+    {
+        return create(Kind.EXCL_END_BOUND, values);
+    }
+
+    public static ClusteringBound inclusiveStartOf(ClusteringPrefix prefix)
+    {
+        ByteBuffer[] values = new ByteBuffer[prefix.size()];
+        for (int i = 0; i < prefix.size(); i++)
+            values[i] = prefix.get(i);
+        return inclusiveStartOf(values);
+    }
+
+    public static ClusteringBound exclusiveStartOf(ClusteringPrefix prefix)
+    {
+        ByteBuffer[] values = new ByteBuffer[prefix.size()];
+        for (int i = 0; i < prefix.size(); i++)
+            values[i] = prefix.get(i);
+        return exclusiveStartOf(values);
+    }
+
+    public static ClusteringBound inclusiveEndOf(ClusteringPrefix prefix)
+    {
+        ByteBuffer[] values = new ByteBuffer[prefix.size()];
+        for (int i = 0; i < prefix.size(); i++)
+            values[i] = prefix.get(i);
+        return inclusiveEndOf(values);
+    }
+
+    public static ClusteringBound create(ClusteringComparator comparator, 
boolean isStart, boolean isInclusive, Object... values)
+    {
+        CBuilder builder = CBuilder.create(comparator);
+        for (Object val : values)
+        {
+            if (val instanceof ByteBuffer)
+                builder.add((ByteBuffer) val);
+            else
+                builder.add(val);
+        }
+        return builder.buildBound(isStart, isInclusive);
+    }
+
+    @Override
+    public ClusteringBound invert()
+    {
+        return create(kind().invert(), values);
+    }
+
+    public ClusteringBound copy(AbstractAllocator allocator)
+    {
+        return (ClusteringBound) super.copy(allocator);
+    }
+
+    public boolean isStart()
+    {
+        return kind().isStart();
+    }
+
+    public boolean isEnd()
+    {
+        return !isStart();
+    }
+
+    public boolean isInclusive()
+    {
+        return kind == Kind.INCL_START_BOUND || kind == Kind.INCL_END_BOUND;
+    }
+
+    public boolean isExclusive()
+    {
+        return kind == Kind.EXCL_START_BOUND || kind == Kind.EXCL_END_BOUND;
+    }
+
+    // For use by intersects, it's called with the sstable bound opposite to 
the slice bound
+    // (so if the slice bound is a start, it's call with the max sstable bound)
+    int compareTo(ClusteringComparator comparator, List<ByteBuffer> 
sstableBound)
+    {
+        for (int i = 0; i < sstableBound.size(); i++)
+        {
+            // Say the slice bound is a start. It means we're in the case 
where the max
+            // sstable bound is say (1:5) while the slice start is (1). So the 
start
+            // does start before the sstable end bound (and intersect it). 
It's the exact
+            // inverse with a end slice bound.
+            if (i >= size())
+                return isStart() ? -1 : 1;
+
+            int cmp = comparator.compareComponent(i, get(i), 
sstableBound.get(i));
+            if (cmp != 0)
+                return cmp;
+        }
+
+        // Say the slice bound is a start. I means we're in the case where the 
max
+        // sstable bound is say (1), while the slice start is (1:5). This 
again means
+        // that the slice start before the end bound.
+        if (size() > sstableBound.size())
+            return isStart() ? -1 : 1;
+
+        // The slice bound is equal to the sstable bound. Results depends on 
whether the slice is inclusive or not
+        return isInclusive() ? 0 : (isStart() ? 1 : -1);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/ClusteringBoundOrBoundary.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ClusteringBoundOrBoundary.java 
b/src/java/org/apache/cassandra/db/ClusteringBoundOrBoundary.java
new file mode 100644
index 0000000..0c965e9
--- /dev/null
+++ b/src/java/org/apache/cassandra/db/ClusteringBoundOrBoundary.java
@@ -0,0 +1,163 @@
+package org.apache.cassandra.db;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.io.util.DataInputPlus;
+import org.apache.cassandra.io.util.DataOutputPlus;
+import org.apache.cassandra.utils.memory.AbstractAllocator;
+
+/**
+ * This class defines a threshold between ranges of clusterings. It can either 
be a start or end bound of a range, or
+ * the boundary between two different defined ranges.
+ * <p>
+ * The latter is used for range tombstones for 2 main reasons:
+ *   1) When merging multiple iterators having range tombstones (that are 
represented by their start and end markers),
+ *      we need to know when a range is close on an iterator, if it is 
reopened right away. Otherwise, we cannot
+ *      easily produce the markers on the merged iterators within risking to 
fail the sorting guarantees of an
+ *      iterator. See this comment for more details: https://goo.gl/yyB5mR.
+ *   2) This saves some storage space.
+ */
+public abstract class ClusteringBoundOrBoundary extends 
AbstractBufferClusteringPrefix
+{
+    public static final ClusteringBoundOrBoundary.Serializer serializer = new 
Serializer();
+
+    protected ClusteringBoundOrBoundary(Kind kind, ByteBuffer[] values)
+    {
+        super(kind, values);
+        assert values.length > 0 || !kind.isBoundary();
+    }
+
+    public static ClusteringBoundOrBoundary create(Kind kind, ByteBuffer[] 
values)
+    {
+        return kind.isBoundary()
+                ? new ClusteringBoundary(kind, values)
+                : new ClusteringBound(kind, values);
+    }
+
+    public boolean isBoundary()
+    {
+        return kind.isBoundary();
+    }
+
+    public boolean isOpen(boolean reversed)
+    {
+        return kind.isOpen(reversed);
+    }
+
+    public boolean isClose(boolean reversed)
+    {
+        return kind.isClose(reversed);
+    }
+
+    public static ClusteringBound inclusiveOpen(boolean reversed, ByteBuffer[] 
boundValues)
+    {
+        return new ClusteringBound(reversed ? Kind.INCL_END_BOUND : 
Kind.INCL_START_BOUND, boundValues);
+    }
+
+    public static ClusteringBound exclusiveOpen(boolean reversed, ByteBuffer[] 
boundValues)
+    {
+        return new ClusteringBound(reversed ? Kind.EXCL_END_BOUND : 
Kind.EXCL_START_BOUND, boundValues);
+    }
+
+    public static ClusteringBound inclusiveClose(boolean reversed, 
ByteBuffer[] boundValues)
+    {
+        return new ClusteringBound(reversed ? Kind.INCL_START_BOUND : 
Kind.INCL_END_BOUND, boundValues);
+    }
+
+    public static ClusteringBound exclusiveClose(boolean reversed, 
ByteBuffer[] boundValues)
+    {
+        return new ClusteringBound(reversed ? Kind.EXCL_START_BOUND : 
Kind.EXCL_END_BOUND, boundValues);
+    }
+
+    public static ClusteringBoundary inclusiveCloseExclusiveOpen(boolean 
reversed, ByteBuffer[] boundValues)
+    {
+        return new ClusteringBoundary(reversed ? 
Kind.EXCL_END_INCL_START_BOUNDARY : Kind.INCL_END_EXCL_START_BOUNDARY, 
boundValues);
+    }
+
+    public static ClusteringBoundary exclusiveCloseInclusiveOpen(boolean 
reversed, ByteBuffer[] boundValues)
+    {
+        return new ClusteringBoundary(reversed ? 
Kind.INCL_END_EXCL_START_BOUNDARY : Kind.EXCL_END_INCL_START_BOUNDARY, 
boundValues);
+    }
+
+    public ClusteringBoundOrBoundary copy(AbstractAllocator allocator)
+    {
+        ByteBuffer[] newValues = new ByteBuffer[size()];
+        for (int i = 0; i < size(); i++)
+            newValues[i] = allocator.clone(get(i));
+        return create(kind(), newValues);
+    }
+
+    public String toString(CFMetaData metadata)
+    {
+        return toString(metadata.comparator);
+    }
+
+    public String toString(ClusteringComparator comparator)
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append(kind()).append('(');
+        for (int i = 0; i < size(); i++)
+        {
+            if (i > 0)
+                sb.append(", ");
+            sb.append(comparator.subtype(i).getString(get(i)));
+        }
+        return sb.append(')').toString();
+    }
+
+    /**
+     * Returns the inverse of the current bound.
+     * <p>
+     * This invert both start into end (and vice-versa) and inclusive into 
exclusive (and vice-versa).
+     *
+     * @return the invert of this bound. For instance, if this bound is an 
exlusive start, this return
+     * an inclusive end with the same values.
+     */
+    public abstract ClusteringBoundOrBoundary invert();
+
+    public static class Serializer
+    {
+        public void serialize(ClusteringBoundOrBoundary bound, DataOutputPlus 
out, int version, List<AbstractType<?>> types) throws IOException
+        {
+            out.writeByte(bound.kind().ordinal());
+            out.writeShort(bound.size());
+            ClusteringPrefix.serializer.serializeValuesWithoutSize(bound, out, 
version, types);
+        }
+
+        public long serializedSize(ClusteringBoundOrBoundary bound, int 
version, List<AbstractType<?>> types)
+        {
+            return 1 // kind ordinal
+                 + TypeSizes.sizeof((short)bound.size())
+                 + 
ClusteringPrefix.serializer.valuesWithoutSizeSerializedSize(bound, version, 
types);
+        }
+
+        public ClusteringBoundOrBoundary deserialize(DataInputPlus in, int 
version, List<AbstractType<?>> types) throws IOException
+        {
+            Kind kind = Kind.values()[in.readByte()];
+            return deserializeValues(in, kind, version, types);
+        }
+
+        public void skipValues(DataInputPlus in, Kind kind, int version, 
List<AbstractType<?>> types) throws IOException
+        {
+            int size = in.readUnsignedShort();
+            if (size == 0)
+                return;
+
+            ClusteringPrefix.serializer.skipValuesWithoutSize(in, size, 
version, types);
+        }
+
+        public ClusteringBoundOrBoundary deserializeValues(DataInputPlus in, 
Kind kind, int version, List<AbstractType<?>> types) throws IOException
+        {
+            int size = in.readUnsignedShort();
+            if (size == 0)
+                return kind.isStart() ? ClusteringBound.BOTTOM : 
ClusteringBound.TOP;
+
+            ByteBuffer[] values = 
ClusteringPrefix.serializer.deserializeValuesWithoutSize(in, size, version, 
types);
+            return create(kind, values);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/ClusteringBoundary.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ClusteringBoundary.java 
b/src/java/org/apache/cassandra/db/ClusteringBoundary.java
new file mode 100644
index 0000000..503eaad
--- /dev/null
+++ b/src/java/org/apache/cassandra/db/ClusteringBoundary.java
@@ -0,0 +1,45 @@
+package org.apache.cassandra.db;
+
+import java.nio.ByteBuffer;
+
+import org.apache.cassandra.utils.memory.AbstractAllocator;
+
+/**
+ * The threshold between two different ranges, i.e. a shortcut for the 
combination of two ClusteringBounds -- one
+ * specifying the end of one of the ranges, and its (implicit) complement 
specifying the beginning of the other.
+ */
+public class ClusteringBoundary extends ClusteringBoundOrBoundary
+{
+    protected ClusteringBoundary(Kind kind, ByteBuffer[] values)
+    {
+        super(kind, values);
+    }
+
+    public static ClusteringBoundary create(Kind kind, ByteBuffer[] values)
+    {
+        assert kind.isBoundary();
+        return new ClusteringBoundary(kind, values);
+    }
+
+    @Override
+    public ClusteringBoundary invert()
+    {
+        return create(kind().invert(), values);
+    }
+
+    @Override
+    public ClusteringBoundary copy(AbstractAllocator allocator)
+    {
+        return (ClusteringBoundary) super.copy(allocator);
+    }
+
+    public ClusteringBound openBound(boolean reversed)
+    {
+        return ClusteringBound.create(kind.openBoundOfBoundary(reversed), 
values);
+    }
+
+    public ClusteringBound closeBound(boolean reversed)
+    {
+        return ClusteringBound.create(kind.closeBoundOfBoundary(reversed), 
values);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/ClusteringPrefix.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ClusteringPrefix.java 
b/src/java/org/apache/cassandra/db/ClusteringPrefix.java
index df0befc..d6aa484 100644
--- a/src/java/org/apache/cassandra/db/ClusteringPrefix.java
+++ b/src/java/org/apache/cassandra/db/ClusteringPrefix.java
@@ -37,10 +37,10 @@ import org.apache.cassandra.utils.ByteBufferUtil;
  * a "kind" that allows us to implement slices with inclusive and exclusive 
bounds.
  * <p>
  * In practice, {@code ClusteringPrefix} is just the common parts to its 3 
main subtype: {@link Clustering} and
- * {@link Slice.Bound}/{@link RangeTombstone.Bound}, where:
+ * {@link ClusteringBound}/{@link ClusteringBoundary}, where:
  *   1) {@code Clustering} represents the clustering values for a row, i.e. 
the values for it's clustering columns.
- *   2) {@code Slice.Bound} represents a bound (start or end) of a slice (of 
rows).
- *   3) {@code RangeTombstoneBoundMarker.Bound} represents a range tombstone 
marker "bound".
+ *   2) {@code ClusteringBound} represents a bound (start or end) of a slice 
(of rows) or a range tombstone.
+ *   3) {@code ClusteringBoundary} represents the threshold between two 
adjacent range tombstones.
  * See those classes for more details.
  */
 public interface ClusteringPrefix extends IMeasurableMemory, Clusterable
@@ -51,7 +51,7 @@ public interface ClusteringPrefix extends IMeasurableMemory, 
Clusterable
      * The kind of clustering prefix this actually is.
      *
      * The kind {@code STATIC_CLUSTERING} is only implemented by {@link 
Clustering#STATIC_CLUSTERING} and {@code CLUSTERING} is
-     * implemented by the {@link Clustering} class. The rest is used by {@link 
Slice.Bound} and {@link RangeTombstone.Bound}.
+     * implemented by the {@link Clustering} class. The rest is used by {@link 
ClusteringBound} and {@link ClusteringBoundary}.
      */
     public enum Kind
     {
@@ -122,8 +122,9 @@ public interface ClusteringPrefix extends 
IMeasurableMemory, Clusterable
                 case EXCL_START_BOUND:
                 case EXCL_END_BOUND:
                     return true;
+                default:
+                    return false;
             }
-            return false;
         }
 
         public boolean isBoundary()
@@ -133,8 +134,9 @@ public interface ClusteringPrefix extends 
IMeasurableMemory, Clusterable
                 case INCL_END_EXCL_START_BOUNDARY:
                 case EXCL_END_INCL_START_BOUNDARY:
                     return true;
+                default:
+                    return false;
             }
-            return false;
         }
 
         public boolean isStart()
@@ -259,7 +261,7 @@ public interface ClusteringPrefix extends 
IMeasurableMemory, Clusterable
             }
             else
             {
-                
RangeTombstone.Bound.serializer.serialize((RangeTombstone.Bound)clustering, 
out, version, types);
+                
ClusteringBoundOrBoundary.serializer.serialize((ClusteringBoundOrBoundary)clustering,
 out, version, types);
             }
         }
 
@@ -271,7 +273,7 @@ public interface ClusteringPrefix extends 
IMeasurableMemory, Clusterable
             if (kind == Kind.CLUSTERING)
                 Clustering.serializer.skip(in, version, types);
             else
-                RangeTombstone.Bound.serializer.skipValues(in, kind, version, 
types);
+                ClusteringBoundOrBoundary.serializer.skipValues(in, kind, 
version, types);
         }
 
         public ClusteringPrefix deserialize(DataInputPlus in, int version, 
List<AbstractType<?>> types) throws IOException
@@ -282,7 +284,7 @@ public interface ClusteringPrefix extends 
IMeasurableMemory, Clusterable
             if (kind == Kind.CLUSTERING)
                 return Clustering.serializer.deserialize(in, version, types);
             else
-                return RangeTombstone.Bound.serializer.deserializeValues(in, 
kind, version, types);
+                return 
ClusteringBoundOrBoundary.serializer.deserializeValues(in, kind, version, 
types);
         }
 
         public long serializedSize(ClusteringPrefix clustering, int version, 
List<AbstractType<?>> types)
@@ -292,7 +294,7 @@ public interface ClusteringPrefix extends 
IMeasurableMemory, Clusterable
             if (clustering.kind() == Kind.CLUSTERING)
                 return 1 + 
Clustering.serializer.serializedSize((Clustering)clustering, version, types);
             else
-                return 
RangeTombstone.Bound.serializer.serializedSize((RangeTombstone.Bound)clustering,
 version, types);
+                return 
ClusteringBoundOrBoundary.serializer.serializedSize((ClusteringBoundOrBoundary)clustering,
 version, types);
         }
 
         void serializeValuesWithoutSize(ClusteringPrefix clustering, 
DataOutputPlus out, int version, List<AbstractType<?>> types) throws IOException
@@ -462,9 +464,9 @@ public interface ClusteringPrefix extends 
IMeasurableMemory, Clusterable
                 this.nextValues = new ByteBuffer[nextSize];
         }
 
-        public int compareNextTo(Slice.Bound bound) throws IOException
+        public int compareNextTo(ClusteringBoundOrBoundary bound) throws 
IOException
         {
-            if (bound == Slice.Bound.TOP)
+            if (bound == ClusteringBound.TOP)
                 return -1;
 
             for (int i = 0; i < bound.size(); i++)
@@ -516,11 +518,11 @@ public interface ClusteringPrefix extends 
IMeasurableMemory, Clusterable
                 continue;
         }
 
-        public RangeTombstone.Bound deserializeNextBound() throws IOException
+        public ClusteringBoundOrBoundary deserializeNextBound() throws 
IOException
         {
             assert !nextIsRow;
             deserializeAll();
-            RangeTombstone.Bound bound = new RangeTombstone.Bound(nextKind, 
nextValues);
+            ClusteringBoundOrBoundary bound = 
ClusteringBoundOrBoundary.create(nextKind, nextValues);
             nextValues = null;
             return bound;
         }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/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 92ecbf5..1c80128 100644
--- a/src/java/org/apache/cassandra/db/LegacyLayout.java
+++ b/src/java/org/apache/cassandra/db/LegacyLayout.java
@@ -193,26 +193,26 @@ public abstract class LegacyLayout
         List<CompositeType.CompositeComponent> prefix = components.size() <= 
metadata.comparator.size()
                                                       ? components
                                                       : components.subList(0, 
metadata.comparator.size());
-        Slice.Bound.Kind boundKind;
+        ClusteringPrefix.Kind boundKind;
         if (isStart)
         {
             if (components.get(components.size() - 1).eoc > 0)
-                boundKind = Slice.Bound.Kind.EXCL_START_BOUND;
+                boundKind = ClusteringPrefix.Kind.EXCL_START_BOUND;
             else
-                boundKind = Slice.Bound.Kind.INCL_START_BOUND;
+                boundKind = ClusteringPrefix.Kind.INCL_START_BOUND;
         }
         else
         {
             if (components.get(components.size() - 1).eoc < 0)
-                boundKind = Slice.Bound.Kind.EXCL_END_BOUND;
+                boundKind = ClusteringPrefix.Kind.EXCL_END_BOUND;
             else
-                boundKind = Slice.Bound.Kind.INCL_END_BOUND;
+                boundKind = ClusteringPrefix.Kind.INCL_END_BOUND;
         }
 
         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);
+        ClusteringBound sb = ClusteringBound.create(boundKind, prefixValues);
 
         ColumnDefinition collectionName = components.size() == 
metadata.comparator.size() + 1
                                         ? 
metadata.getColumnDefinition(components.get(metadata.comparator.size()).value)
@@ -220,9 +220,9 @@ public abstract class LegacyLayout
         return new LegacyBound(sb, metadata.isCompound() && 
CompositeType.isStaticName(bound), collectionName);
     }
 
-    public static ByteBuffer encodeBound(CFMetaData metadata, Slice.Bound 
bound, boolean isStart)
+    public static ByteBuffer encodeBound(CFMetaData metadata, ClusteringBound 
bound, boolean isStart)
     {
-        if (bound == Slice.Bound.BOTTOM || bound == Slice.Bound.TOP || 
metadata.comparator.size() == 0)
+        if (bound == ClusteringBound.BOTTOM || bound == ClusteringBound.TOP || 
metadata.comparator.size() == 0)
             return ByteBufferUtil.EMPTY_BYTE_BUFFER;
 
         ClusteringPrefix clustering = bound.clustering();
@@ -722,8 +722,8 @@ public abstract class LegacyLayout
         if (!row.deletion().isLive())
         {
             Clustering clustering = row.clustering();
-            Slice.Bound startBound = Slice.Bound.inclusiveStartOf(clustering);
-            Slice.Bound endBound = Slice.Bound.inclusiveEndOf(clustering);
+            ClusteringBound startBound = 
ClusteringBound.inclusiveStartOf(clustering);
+            ClusteringBound endBound = 
ClusteringBound.inclusiveEndOf(clustering);
 
             LegacyBound start = new LegacyLayout.LegacyBound(startBound, 
false, null);
             LegacyBound end = new LegacyLayout.LegacyBound(endBound, false, 
null);
@@ -742,8 +742,8 @@ public abstract class LegacyLayout
             {
                 Clustering clustering = row.clustering();
 
-                Slice.Bound startBound = 
Slice.Bound.inclusiveStartOf(clustering);
-                Slice.Bound endBound = Slice.Bound.inclusiveEndOf(clustering);
+                ClusteringBound startBound = 
ClusteringBound.inclusiveStartOf(clustering);
+                ClusteringBound endBound = 
ClusteringBound.inclusiveEndOf(clustering);
 
                 LegacyLayout.LegacyBound start = new 
LegacyLayout.LegacyBound(startBound, col.isStatic(), col);
                 LegacyLayout.LegacyBound end = new 
LegacyLayout.LegacyBound(endBound, col.isStatic(), col);
@@ -918,9 +918,9 @@ public abstract class LegacyLayout
             // we can have collection deletion and we want those to sort 
properly just before the column they
             // delete, not before the whole row.
             // We also want to special case static so they sort before any 
non-static. Note in particular that
-            // this special casing is important in the case of one of the Atom 
being Slice.Bound.BOTTOM: we want
+            // this special casing is important in the case of one of the Atom 
being Bound.BOTTOM: we want
             // it to sort after the static as we deal with static first in 
toUnfilteredAtomIterator and having
-            // Slice.Bound.BOTTOM first would mess that up (note that static 
deletion is handled through a specific
+            // Bound.BOTTOM first would mess that up (note that static 
deletion is handled through a specific
             // static tombstone, see LegacyDeletionInfo.add()).
             if (o1.isStatic() != o2.isStatic())
                 return o1.isStatic() ? -1 : 1;
@@ -1328,14 +1328,14 @@ public abstract class LegacyLayout
 
     public static class LegacyBound
     {
-        public static final LegacyBound BOTTOM = new 
LegacyBound(Slice.Bound.BOTTOM, false, null);
-        public static final LegacyBound TOP = new LegacyBound(Slice.Bound.TOP, 
false, null);
+        public static final LegacyBound BOTTOM = new 
LegacyBound(ClusteringBound.BOTTOM, false, null);
+        public static final LegacyBound TOP = new 
LegacyBound(ClusteringBound.TOP, false, null);
 
-        public final Slice.Bound bound;
+        public final ClusteringBound bound;
         public final boolean isStatic;
         public final ColumnDefinition collectionName;
 
-        public LegacyBound(Slice.Bound bound, boolean isStatic, 
ColumnDefinition collectionName)
+        public LegacyBound(ClusteringBound bound, boolean isStatic, 
ColumnDefinition collectionName)
         {
             this.bound = bound;
             this.isStatic = isStatic;
@@ -1640,7 +1640,7 @@ public abstract class LegacyLayout
             deletionInfo.add(topLevel);
         }
 
-        private static Slice.Bound staticBound(CFMetaData metadata, boolean 
isStart)
+        private static ClusteringBound staticBound(CFMetaData metadata, 
boolean isStart)
         {
             // In pre-3.0 nodes, static row started by a clustering with all 
empty values so we
             // preserve that here. Note that in practice, it doesn't really 
matter since the rest
@@ -1649,8 +1649,8 @@ public abstract class LegacyLayout
             for (int i = 0; i < values.length; i++)
                 values[i] = ByteBufferUtil.EMPTY_BYTE_BUFFER;
             return isStart
-                 ? Slice.Bound.inclusiveStartOf(values)
-                 : Slice.Bound.inclusiveEndOf(values);
+                 ? ClusteringBound.inclusiveStartOf(values)
+                 : ClusteringBound.inclusiveEndOf(values);
         }
 
         public void add(CFMetaData metadata, LegacyRangeTombstone tombstone)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/MultiCBuilder.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/MultiCBuilder.java 
b/src/java/org/apache/cassandra/db/MultiCBuilder.java
index f03e674..ae8c26c 100644
--- a/src/java/org/apache/cassandra/db/MultiCBuilder.java
+++ b/src/java/org/apache/cassandra/db/MultiCBuilder.java
@@ -24,12 +24,11 @@ import java.util.List;
 import java.util.NavigableSet;
 
 import org.apache.cassandra.config.ColumnDefinition;
-import org.apache.cassandra.db.Slice.Bound;
 import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.btree.BTreeSet;
 
 /**
- * Builder that allow to build multiple Clustering/Slice.Bound at the same 
time.
+ * Builder that allow to build multiple Clustering/ClusteringBound at the same 
time.
  */
 public abstract class MultiCBuilder
 {
@@ -167,27 +166,27 @@ public abstract class MultiCBuilder
     public abstract NavigableSet<Clustering> build();
 
     /**
-     * Builds the <code>Slice.Bound</code>s for slice restrictions.
+     * Builds the <code>ClusteringBound</code>s for slice restrictions.
      *
      * @param isStart specify if the bound is a start one
      * @param isInclusive specify if the bound is inclusive or not
      * @param isOtherBoundInclusive specify if the other bound is inclusive or 
not
      * @param columnDefs the columns of the slice restriction
-     * @return the <code>Slice.Bound</code>s
+     * @return the <code>ClusteringBound</code>s
      */
-    public abstract NavigableSet<Slice.Bound> buildBoundForSlice(boolean 
isStart,
+    public abstract NavigableSet<ClusteringBound> buildBoundForSlice(boolean 
isStart,
                                                                  boolean 
isInclusive,
                                                                  boolean 
isOtherBoundInclusive,
                                                                  
List<ColumnDefinition> columnDefs);
 
     /**
-     * Builds the <code>Slice.Bound</code>s
+     * Builds the <code>ClusteringBound</code>s
      *
      * @param isStart specify if the bound is a start one
      * @param isInclusive specify if the bound is inclusive or not
-     * @return the <code>Slice.Bound</code>s
+     * @return the <code>ClusteringBound</code>s
      */
-    public abstract NavigableSet<Slice.Bound> buildBound(boolean isStart, 
boolean isInclusive);
+    public abstract NavigableSet<ClusteringBound> buildBound(boolean isStart, 
boolean isInclusive);
 
     /**
      * Checks if some elements can still be added to the clusterings.
@@ -264,15 +263,15 @@ public abstract class MultiCBuilder
         }
 
         @Override
-        public NavigableSet<Bound> buildBoundForSlice(boolean isStart,
-                                                      boolean isInclusive,
-                                                      boolean 
isOtherBoundInclusive,
-                                                      List<ColumnDefinition> 
columnDefs)
+        public NavigableSet<ClusteringBound> buildBoundForSlice(boolean 
isStart,
+                                                                boolean 
isInclusive,
+                                                                boolean 
isOtherBoundInclusive,
+                                                                
List<ColumnDefinition> columnDefs)
         {
             return buildBound(isStart, columnDefs.get(0).isReversedType() ? 
isOtherBoundInclusive : isInclusive);
         }
 
-        public NavigableSet<Slice.Bound> buildBound(boolean isStart, boolean 
isInclusive)
+        public NavigableSet<ClusteringBound> buildBound(boolean isStart, 
boolean isInclusive)
         {
             built = true;
 
@@ -280,13 +279,13 @@ public abstract class MultiCBuilder
                 return BTreeSet.empty(comparator);
 
             if (size == 0)
-                return BTreeSet.of(comparator, isStart ? Slice.Bound.BOTTOM : 
Slice.Bound.TOP);
+                return BTreeSet.of(comparator, isStart ? 
ClusteringBound.BOTTOM : ClusteringBound.TOP);
 
             ByteBuffer[] newValues = size == elements.length
                                    ? elements
                                    : Arrays.copyOf(elements, size);
 
-            return BTreeSet.of(comparator, 
Slice.Bound.create(Slice.Bound.boundKind(isStart, isInclusive), newValues));
+            return BTreeSet.of(comparator, 
ClusteringBound.create(ClusteringBound.boundKind(isStart, isInclusive), 
newValues));
         }
     }
 
@@ -419,7 +418,7 @@ public abstract class MultiCBuilder
             return set.build();
         }
 
-        public NavigableSet<Slice.Bound> buildBoundForSlice(boolean isStart,
+        public NavigableSet<ClusteringBound> buildBoundForSlice(boolean 
isStart,
                                                             boolean 
isInclusive,
                                                             boolean 
isOtherBoundInclusive,
                                                             
List<ColumnDefinition> columnDefs)
@@ -435,7 +434,7 @@ public abstract class MultiCBuilder
                 return BTreeSet.of(comparator, builder.buildBound(isStart, 
isInclusive));
 
             // Use a TreeSet to sort and eliminate duplicates
-            BTreeSet.Builder<Slice.Bound> set = BTreeSet.builder(comparator);
+            BTreeSet.Builder<ClusteringBound> set = 
BTreeSet.builder(comparator);
 
             // The first column of the slice might not be the first clustering 
column (e.g. clustering_0 = ? AND (clustering_1, clustering_2) >= (?, ?)
             int offset = columnDefs.get(0).position();
@@ -470,7 +469,7 @@ public abstract class MultiCBuilder
             return set.build();
         }
 
-        public NavigableSet<Slice.Bound> buildBound(boolean isStart, boolean 
isInclusive)
+        public NavigableSet<ClusteringBound> buildBound(boolean isStart, 
boolean isInclusive)
         {
             built = true;
 
@@ -483,7 +482,7 @@ public abstract class MultiCBuilder
                 return BTreeSet.of(comparator, builder.buildBound(isStart, 
isInclusive));
 
             // Use a TreeSet to sort and eliminate duplicates
-            BTreeSet.Builder<Slice.Bound> set = BTreeSet.builder(comparator);
+            BTreeSet.Builder<ClusteringBound> set = 
BTreeSet.builder(comparator);
 
             for (int i = 0, m = elementsList.size(); i < m; i++)
             {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/MutableDeletionInfo.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/MutableDeletionInfo.java 
b/src/java/org/apache/cassandra/db/MutableDeletionInfo.java
index d01b1d1..1ba77bb 100644
--- a/src/java/org/apache/cassandra/db/MutableDeletionInfo.java
+++ b/src/java/org/apache/cassandra/db/MutableDeletionInfo.java
@@ -290,8 +290,8 @@ public class MutableDeletionInfo implements DeletionInfo
                 DeletionTime openDeletion = 
openMarker.openDeletionTime(reversed);
                 assert marker.closeDeletionTime(reversed).equals(openDeletion);
 
-                Slice.Bound open = openMarker.openBound(reversed);
-                Slice.Bound close = marker.closeBound(reversed);
+                ClusteringBound open = openMarker.openBound(reversed);
+                ClusteringBound close = marker.closeBound(reversed);
 
                 Slice slice = reversed ? Slice.make(close, open) : 
Slice.make(open, close);
                 deletion.add(new RangeTombstone(slice, openDeletion), 
comparator);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/RangeTombstone.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/RangeTombstone.java 
b/src/java/org/apache/cassandra/db/RangeTombstone.java
index 29feb46..8e01b8e 100644
--- a/src/java/org/apache/cassandra/db/RangeTombstone.java
+++ b/src/java/org/apache/cassandra/db/RangeTombstone.java
@@ -17,16 +17,9 @@
  */
 package org.apache.cassandra.db;
 
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.List;
 import java.util.Objects;
 
-import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.db.rows.RangeTombstoneMarker;
-import org.apache.cassandra.io.util.DataInputPlus;
-import org.apache.cassandra.io.util.DataOutputPlus;
-import org.apache.cassandra.utils.memory.AbstractAllocator;
 
 
 /**
@@ -89,139 +82,4 @@ public class RangeTombstone
     {
         return Objects.hash(deletedSlice(), deletionTime());
     }
-
-    /**
-     * The bound of a range tombstone.
-     * <p>
-     * This is the same than for a slice but it includes "boundaries" between 
ranges. A boundary simply condensed
-     * a close and an opening "bound" into a single object. There is 2 main 
reasons for these "shortcut" boundaries:
-     *   1) When merging multiple iterators having range tombstones (that are 
represented by their start and end markers),
-     *      we need to know when a range is close on an iterator, if it is 
reopened right away. Otherwise, we cannot
-     *      easily produce the markers on the merged iterators within risking 
to fail the sorting guarantees of an
-     *      iterator. See this comment for more details: https://goo.gl/yyB5mR.
-     *   2) This saves some storage space.
-     */
-    public static class Bound extends Slice.Bound
-    {
-        public static final Serializer serializer = new Serializer();
-
-        /** The smallest start bound, i.e. the one that starts before any row. 
*/
-        public static final Bound BOTTOM = new Bound(Kind.INCL_START_BOUND, 
EMPTY_VALUES_ARRAY);
-        /** The biggest end bound, i.e. the one that ends after any row. */
-        public static final Bound TOP = new Bound(Kind.INCL_END_BOUND, 
EMPTY_VALUES_ARRAY);
-
-        public Bound(Kind kind, ByteBuffer[] values)
-        {
-            super(kind, values);
-            assert values.length > 0 || !kind.isBoundary();
-        }
-
-        public boolean isBoundary()
-        {
-            return kind.isBoundary();
-        }
-
-        public boolean isOpen(boolean reversed)
-        {
-            return kind.isOpen(reversed);
-        }
-
-        public boolean isClose(boolean reversed)
-        {
-            return kind.isClose(reversed);
-        }
-
-        public static RangeTombstone.Bound inclusiveOpen(boolean reversed, 
ByteBuffer[] boundValues)
-        {
-            return new Bound(reversed ? Kind.INCL_END_BOUND : 
Kind.INCL_START_BOUND, boundValues);
-        }
-
-        public static RangeTombstone.Bound exclusiveOpen(boolean reversed, 
ByteBuffer[] boundValues)
-        {
-            return new Bound(reversed ? Kind.EXCL_END_BOUND : 
Kind.EXCL_START_BOUND, boundValues);
-        }
-
-        public static RangeTombstone.Bound inclusiveClose(boolean reversed, 
ByteBuffer[] boundValues)
-        {
-            return new Bound(reversed ? Kind.INCL_START_BOUND : 
Kind.INCL_END_BOUND, boundValues);
-        }
-
-        public static RangeTombstone.Bound exclusiveClose(boolean reversed, 
ByteBuffer[] boundValues)
-        {
-            return new Bound(reversed ? Kind.EXCL_START_BOUND : 
Kind.EXCL_END_BOUND, boundValues);
-        }
-
-        public static RangeTombstone.Bound inclusiveCloseExclusiveOpen(boolean 
reversed, ByteBuffer[] boundValues)
-        {
-            return new Bound(reversed ? Kind.EXCL_END_INCL_START_BOUNDARY : 
Kind.INCL_END_EXCL_START_BOUNDARY, boundValues);
-        }
-
-        public static RangeTombstone.Bound exclusiveCloseInclusiveOpen(boolean 
reversed, ByteBuffer[] boundValues)
-        {
-            return new Bound(reversed ? Kind.INCL_END_EXCL_START_BOUNDARY : 
Kind.EXCL_END_INCL_START_BOUNDARY, boundValues);
-        }
-
-        public static RangeTombstone.Bound fromSliceBound(Slice.Bound 
sliceBound)
-        {
-            return new RangeTombstone.Bound(sliceBound.kind(), 
sliceBound.getRawValues());
-        }
-
-        public RangeTombstone.Bound copy(AbstractAllocator allocator)
-        {
-            ByteBuffer[] newValues = new ByteBuffer[size()];
-            for (int i = 0; i < size(); i++)
-                newValues[i] = allocator.clone(get(i));
-            return new Bound(kind(), newValues);
-        }
-
-        @Override
-        public Bound withNewKind(Kind kind)
-        {
-            return new Bound(kind, values);
-        }
-
-        public static class Serializer
-        {
-            public void serialize(RangeTombstone.Bound bound, DataOutputPlus 
out, int version, List<AbstractType<?>> types) throws IOException
-            {
-                out.writeByte(bound.kind().ordinal());
-                out.writeShort(bound.size());
-                ClusteringPrefix.serializer.serializeValuesWithoutSize(bound, 
out, version, types);
-            }
-
-            public long serializedSize(RangeTombstone.Bound bound, int 
version, List<AbstractType<?>> types)
-            {
-                return 1 // kind ordinal
-                     + TypeSizes.sizeof((short)bound.size())
-                     + 
ClusteringPrefix.serializer.valuesWithoutSizeSerializedSize(bound, version, 
types);
-            }
-
-            public RangeTombstone.Bound deserialize(DataInputPlus in, int 
version, List<AbstractType<?>> types) throws IOException
-            {
-                Kind kind = Kind.values()[in.readByte()];
-                return deserializeValues(in, kind, version, types);
-            }
-
-            public void skipValues(DataInputPlus in, Kind kind, int version,
-                                                          
List<AbstractType<?>> types) throws IOException
-            {
-                int size = in.readUnsignedShort();
-                if (size == 0)
-                    return;
-
-                ClusteringPrefix.serializer.skipValuesWithoutSize(in, size, 
version, types);
-            }
-
-            public RangeTombstone.Bound deserializeValues(DataInputPlus in, 
Kind kind, int version,
-                    List<AbstractType<?>> types) throws IOException
-            {
-                int size = in.readUnsignedShort();
-                if (size == 0)
-                    return kind.isStart() ? BOTTOM : TOP;
-
-                ByteBuffer[] values = 
ClusteringPrefix.serializer.deserializeValuesWithoutSize(in, size, version, 
types);
-                return new RangeTombstone.Bound(kind, values);
-            }
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/RangeTombstoneList.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/RangeTombstoneList.java 
b/src/java/org/apache/cassandra/db/RangeTombstoneList.java
index baeb227..c60b774 100644
--- a/src/java/org/apache/cassandra/db/RangeTombstoneList.java
+++ b/src/java/org/apache/cassandra/db/RangeTombstoneList.java
@@ -54,15 +54,15 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
 
     // Note: we don't want to use a List for the markedAts and delTimes to 
avoid boxing. We could
     // use a List for starts and ends, but having arrays everywhere is almost 
simpler.
-    private Slice.Bound[] starts;
-    private Slice.Bound[] ends;
+    private ClusteringBound[] starts;
+    private ClusteringBound[] ends;
     private long[] markedAts;
     private int[] delTimes;
 
     private long boundaryHeapSize;
     private int size;
 
-    private RangeTombstoneList(ClusteringComparator comparator, Slice.Bound[] 
starts, Slice.Bound[] ends, long[] markedAts, int[] delTimes, long 
boundaryHeapSize, int size)
+    private RangeTombstoneList(ClusteringComparator comparator, 
ClusteringBound[] starts, ClusteringBound[] ends, long[] markedAts, int[] 
delTimes, long boundaryHeapSize, int size)
     {
         assert starts.length == ends.length && starts.length == 
markedAts.length && starts.length == delTimes.length;
         this.comparator = comparator;
@@ -76,7 +76,7 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
 
     public RangeTombstoneList(ClusteringComparator comparator, int capacity)
     {
-        this(comparator, new Slice.Bound[capacity], new Slice.Bound[capacity], 
new long[capacity], new int[capacity], 0, 0);
+        this(comparator, new ClusteringBound[capacity], new 
ClusteringBound[capacity], new long[capacity], new int[capacity], 0, 0);
     }
 
     public boolean isEmpty()
@@ -107,8 +107,8 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
     public RangeTombstoneList copy(AbstractAllocator allocator)
     {
         RangeTombstoneList copy =  new RangeTombstoneList(comparator,
-                                                          new 
Slice.Bound[size],
-                                                          new 
Slice.Bound[size],
+                                                          new 
ClusteringBound[size],
+                                                          new 
ClusteringBound[size],
                                                           
Arrays.copyOf(markedAts, size),
                                                           
Arrays.copyOf(delTimes, size),
                                                           boundaryHeapSize, 
size);
@@ -123,12 +123,12 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
         return copy;
     }
 
-    private static Slice.Bound clone(Slice.Bound bound, AbstractAllocator 
allocator)
+    private static ClusteringBound clone(ClusteringBound bound, 
AbstractAllocator allocator)
     {
         ByteBuffer[] values = new ByteBuffer[bound.size()];
         for (int i = 0; i < values.length; i++)
             values[i] = allocator.clone(bound.get(i));
-        return new Slice.Bound(bound.kind(), values);
+        return new ClusteringBound(bound.kind(), values);
     }
 
     public void add(RangeTombstone tombstone)
@@ -145,7 +145,7 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
      * This method will be faster if the new tombstone sort after all the 
currently existing ones (this is a common use case),
      * but it doesn't assume it.
      */
-    public void add(Slice.Bound start, Slice.Bound end, long markedAt, int 
delTime)
+    public void add(ClusteringBound start, ClusteringBound end, long markedAt, 
int delTime)
     {
         if (isEmpty())
         {
@@ -324,17 +324,17 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
         return new RangeTombstone(Slice.make(starts[idx], ends[idx]), new 
DeletionTime(markedAts[idx], delTimes[idx]));
     }
 
-    private RangeTombstone rangeTombstoneWithNewStart(int idx, Slice.Bound 
newStart)
+    private RangeTombstone rangeTombstoneWithNewStart(int idx, ClusteringBound 
newStart)
     {
         return new RangeTombstone(Slice.make(newStart, ends[idx]), new 
DeletionTime(markedAts[idx], delTimes[idx]));
     }
 
-    private RangeTombstone rangeTombstoneWithNewEnd(int idx, Slice.Bound 
newEnd)
+    private RangeTombstone rangeTombstoneWithNewEnd(int idx, ClusteringBound 
newEnd)
     {
         return new RangeTombstone(Slice.make(starts[idx], newEnd), new 
DeletionTime(markedAts[idx], delTimes[idx]));
     }
 
-    private RangeTombstone rangeTombstoneWithNewBounds(int idx, Slice.Bound 
newStart, Slice.Bound newEnd)
+    private RangeTombstone rangeTombstoneWithNewBounds(int idx, 
ClusteringBound newStart, ClusteringBound newEnd)
     {
         return new RangeTombstone(Slice.make(newStart, newEnd), new 
DeletionTime(markedAts[idx], delTimes[idx]));
     }
@@ -380,13 +380,13 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
 
     private Iterator<RangeTombstone> forwardIterator(final Slice slice)
     {
-        int startIdx = slice.start() == Slice.Bound.BOTTOM ? 0 : 
searchInternal(slice.start(), 0, size);
+        int startIdx = slice.start() == ClusteringBound.BOTTOM ? 0 : 
searchInternal(slice.start(), 0, size);
         final int start = startIdx < 0 ? -startIdx-1 : startIdx;
 
         if (start >= size)
             return Collections.emptyIterator();
 
-        int finishIdx = slice.end() == Slice.Bound.TOP ? size - 1 : 
searchInternal(slice.end(), start, size);
+        int finishIdx = slice.end() == ClusteringBound.TOP ? size - 1 : 
searchInternal(slice.end(), start, size);
         // if stopIdx is the first range after 'slice.end()' we care only 
until the previous range
         final int finish = finishIdx < 0 ? -finishIdx-2 : finishIdx;
 
@@ -397,8 +397,8 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
         {
             // We want to make sure the range are stricly included within the 
queried slice as this
             // make it easier to combine things when iterating over successive 
slices.
-            Slice.Bound s = comparator.compare(starts[start], slice.start()) < 
0 ? slice.start() : starts[start];
-            Slice.Bound e = comparator.compare(slice.end(), ends[start]) < 0 ? 
slice.end() : ends[start];
+            ClusteringBound s = comparator.compare(starts[start], 
slice.start()) < 0 ? slice.start() : starts[start];
+            ClusteringBound e = comparator.compare(slice.end(), ends[start]) < 
0 ? slice.end() : ends[start];
             return 
Iterators.<RangeTombstone>singletonIterator(rangeTombstoneWithNewBounds(start, 
s, e));
         }
 
@@ -425,14 +425,14 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
 
     private Iterator<RangeTombstone> reverseIterator(final Slice slice)
     {
-        int startIdx = slice.end() == Slice.Bound.TOP ? size - 1 : 
searchInternal(slice.end(), 0, size);
+        int startIdx = slice.end() == ClusteringBound.TOP ? size - 1 : 
searchInternal(slice.end(), 0, size);
         // if startIdx is the first range after 'slice.end()' we care only 
until the previous range
         final int start = startIdx < 0 ? -startIdx-2 : startIdx;
 
         if (start < 0)
             return Collections.emptyIterator();
 
-        int finishIdx = slice.start() == Slice.Bound.BOTTOM ? 0 : 
searchInternal(slice.start(), 0, start + 1);  // include same as finish
+        int finishIdx = slice.start() == ClusteringBound.BOTTOM ? 0 : 
searchInternal(slice.start(), 0, start + 1);  // include same as finish
         // if stopIdx is the first range after 'slice.end()' we care only 
until the previous range
         final int finish = finishIdx < 0 ? -finishIdx-1 : finishIdx;
 
@@ -443,8 +443,8 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
         {
             // We want to make sure the range are stricly included within the 
queried slice as this
             // make it easier to combine things when iterator over successive 
slices.
-            Slice.Bound s = comparator.compare(starts[start], slice.start()) < 
0 ? slice.start() : starts[start];
-            Slice.Bound e = comparator.compare(slice.end(), ends[start]) < 0 ? 
slice.end() : ends[start];
+            ClusteringBound s = comparator.compare(starts[start], 
slice.start()) < 0 ? slice.start() : starts[start];
+            ClusteringBound e = comparator.compare(slice.end(), ends[start]) < 
0 ? slice.end() : ends[start];
             return 
Iterators.<RangeTombstone>singletonIterator(rangeTombstoneWithNewBounds(start, 
s, e));
         }
 
@@ -527,7 +527,7 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
      *   - e_i <= s_i+1
      * Basically, range are non overlapping and in order.
      */
-    private void insertFrom(int i, Slice.Bound start, Slice.Bound end, long 
markedAt, int delTime)
+    private void insertFrom(int i, ClusteringBound start, ClusteringBound end, 
long markedAt, int delTime)
     {
         while (i < size)
         {
@@ -546,7 +546,7 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
                 // First deal with what might come before the newly added one.
                 if (comparator.compare(starts[i], start) < 0)
                 {
-                    Slice.Bound newEnd = start.invert();
+                    ClusteringBound newEnd = start.invert();
                     if (!Slice.isEmpty(comparator, starts[i], newEnd))
                     {
                         addInternal(i, starts[i], start.invert(), 
markedAts[i], delTimes[i]);
@@ -594,7 +594,7 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
                     // one to reflect the not overwritten parts. We're then 
done.
                     addInternal(i, start, end, markedAt, delTime);
                     i++;
-                    Slice.Bound newStart = end.invert();
+                    ClusteringBound newStart = end.invert();
                     if (!Slice.isEmpty(comparator, newStart, ends[i]))
                     {
                         setInternal(i, newStart, ends[i], markedAts[i], 
delTimes[i]);
@@ -616,7 +616,7 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
                         addInternal(i, start, end, markedAt, delTime);
                         return;
                     }
-                    Slice.Bound newEnd = starts[i].invert();
+                    ClusteringBound newEnd = starts[i].invert();
                     if (!Slice.isEmpty(comparator, start, newEnd))
                     {
                         addInternal(i, start, newEnd, markedAt, delTime);
@@ -648,7 +648,7 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
     /*
      * Adds the new tombstone at index i, growing and/or moving elements to 
make room for it.
      */
-    private void addInternal(int i, Slice.Bound start, Slice.Bound end, long 
markedAt, int delTime)
+    private void addInternal(int i, ClusteringBound start, ClusteringBound 
end, long markedAt, int delTime)
     {
         assert i >= 0;
 
@@ -687,12 +687,12 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
         delTimes = grow(delTimes, size, newLength, i);
     }
 
-    private static Slice.Bound[] grow(Slice.Bound[] a, int size, int 
newLength, int i)
+    private static ClusteringBound[] grow(ClusteringBound[] a, int size, int 
newLength, int i)
     {
         if (i < 0 || i >= size)
             return Arrays.copyOf(a, newLength);
 
-        Slice.Bound[] newA = new Slice.Bound[newLength];
+        ClusteringBound[] newA = new ClusteringBound[newLength];
         System.arraycopy(a, 0, newA, 0, i);
         System.arraycopy(a, i, newA, i+1, size - i);
         return newA;
@@ -737,7 +737,7 @@ public class RangeTombstoneList implements 
Iterable<RangeTombstone>, IMeasurable
         starts[i] = null;
     }
 
-    private void setInternal(int i, Slice.Bound start, Slice.Bound end, long 
markedAt, int delTime)
+    private void setInternal(int i, ClusteringBound start, ClusteringBound 
end, long markedAt, int delTime)
     {
         if (starts[i] != null)
             boundaryHeapSize -= starts[i].unsharedHeapSize() + 
ends[i].unsharedHeapSize();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/ReadCommand.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ReadCommand.java 
b/src/java/org/apache/cassandra/db/ReadCommand.java
index 387e062..c842814 100644
--- a/src/java/org/apache/cassandra/db/ReadCommand.java
+++ b/src/java/org/apache/cassandra/db/ReadCommand.java
@@ -1074,7 +1074,7 @@ public abstract class ReadCommand extends MonitorableImpl 
implements ReadQuery
             // slice filter's stop.
             DataRange.Paging pagingRange = (DataRange.Paging) 
rangeCommand.dataRange();
             Clustering lastReturned = pagingRange.getLastReturned();
-            Slice.Bound newStart = Slice.Bound.exclusiveStartOf(lastReturned);
+            ClusteringBound newStart = 
ClusteringBound.exclusiveStartOf(lastReturned);
             Slice lastSlice = 
filter.requestedSlices().get(filter.requestedSlices().size() - 1);
             
ByteBufferUtil.writeWithShortLength(LegacyLayout.encodeBound(metadata, 
newStart, true), out);
             
ByteBufferUtil.writeWithShortLength(LegacyLayout.encodeClustering(metadata, 
lastSlice.end().clustering()), out);
@@ -1542,7 +1542,7 @@ public abstract class ReadCommand extends MonitorableImpl 
implements ReadQuery
         static long serializedStaticSliceSize(CFMetaData metadata)
         {
             // unlike serializeStaticSlice(), but we don't care about reversal 
for size calculations
-            ByteBuffer sliceStart = LegacyLayout.encodeBound(metadata, 
Slice.Bound.BOTTOM, false);
+            ByteBuffer sliceStart = LegacyLayout.encodeBound(metadata, 
ClusteringBound.BOTTOM, false);
             long size = 
ByteBufferUtil.serializedSizeWithShortLength(sliceStart);
 
             size += TypeSizes.sizeof((short) (metadata.comparator.size() * 3 + 
2));
@@ -1570,7 +1570,7 @@ public abstract class ReadCommand extends MonitorableImpl 
implements ReadQuery
             // slice finish after we've written the static slice start
             if (!isReversed)
             {
-                ByteBuffer sliceStart = LegacyLayout.encodeBound(metadata, 
Slice.Bound.BOTTOM, false);
+                ByteBuffer sliceStart = LegacyLayout.encodeBound(metadata, 
ClusteringBound.BOTTOM, false);
                 ByteBufferUtil.writeWithShortLength(sliceStart, out);
             }
 
@@ -1586,7 +1586,7 @@ public abstract class ReadCommand extends MonitorableImpl 
implements ReadQuery
 
             if (isReversed)
             {
-                ByteBuffer sliceStart = LegacyLayout.encodeBound(metadata, 
Slice.Bound.BOTTOM, false);
+                ByteBuffer sliceStart = LegacyLayout.encodeBound(metadata, 
ClusteringBound.BOTTOM, false);
                 ByteBufferUtil.writeWithShortLength(sliceStart, out);
             }
         }
@@ -1708,7 +1708,7 @@ public abstract class ReadCommand extends MonitorableImpl 
implements ReadQuery
             {
                 Slices.Builder slicesBuilder = new 
Slices.Builder(metadata.comparator);
                 for (Clustering clustering : requestedRows)
-                    
slicesBuilder.add(Slice.Bound.inclusiveStartOf(clustering), 
Slice.Bound.inclusiveEndOf(clustering));
+                    
slicesBuilder.add(ClusteringBound.inclusiveStartOf(clustering), 
ClusteringBound.inclusiveEndOf(clustering));
                 slices = slicesBuilder.build();
             }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cc26eba/src/java/org/apache/cassandra/db/Serializers.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Serializers.java 
b/src/java/org/apache/cassandra/db/Serializers.java
index a0503e0..d6aac64 100644
--- a/src/java/org/apache/cassandra/db/Serializers.java
+++ b/src/java/org/apache/cassandra/db/Serializers.java
@@ -132,11 +132,11 @@ public class Serializers
                 {
                     // It's a range tombstone bound. It is a start since 
that's the only part we've ever included
                     // in the index entries.
-                    Slice.Bound.Kind boundKind = eoc > 0
-                                                 ? 
Slice.Bound.Kind.EXCL_START_BOUND
-                                                 : 
Slice.Bound.Kind.INCL_START_BOUND;
+                    ClusteringPrefix.Kind boundKind = eoc > 0
+                                                 ? 
ClusteringPrefix.Kind.EXCL_START_BOUND
+                                                 : 
ClusteringPrefix.Kind.INCL_START_BOUND;
 
-                    return Slice.Bound.create(boundKind, 
components.toArray(new ByteBuffer[components.size()]));
+                    return ClusteringBound.create(boundKind, 
components.toArray(new ByteBuffer[components.size()]));
                 }
             }
 

Reply via email to