From 2cc26eba7a742eb23e95b027bc611c924c233e1e Mon Sep 17 00:00:00 2001 From: Branimir Lambov Date: Wed, 6 Apr 2016 11:47:23 +0300 Subject: [PATCH] Clarify ClusteringPrefix hierarchy Patch by Branimir Lambov; reviewed by Sylvain Lebresne for CASSANDRA-11213 --- CHANGES.txt | 1 + .../ClusteringColumnRestrictions.java | 2 +- .../restrictions/StatementRestrictions.java | 2 +- .../statements/ModificationStatement.java | 10 +- .../cql3/statements/SelectStatement.java | 16 +- .../db/AbstractReadCommandBuilder.java | 16 +- .../org/apache/cassandra/db/CBuilder.java | 30 +- .../apache/cassandra/db/ClusteringBound.java | 151 ++++++++++ .../db/ClusteringBoundOrBoundary.java | 163 ++++++++++ .../cassandra/db/ClusteringBoundary.java | 45 +++ .../apache/cassandra/db/ClusteringPrefix.java | 30 +- .../org/apache/cassandra/db/LegacyLayout.java | 42 +-- .../apache/cassandra/db/MultiCBuilder.java | 37 ++- .../cassandra/db/MutableDeletionInfo.java | 4 +- .../apache/cassandra/db/RangeTombstone.java | 142 --------- .../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 +- .../AbstractSSTableIterator.java | 6 +- .../db/columniterator/SSTableIterator.java | 8 +- .../SSTableReversedIterator.java | 6 +- .../db/partitions/AbstractBTreePartition.java | 4 +- .../db/rows/AbstractRangeTombstoneMarker.java | 12 +- .../db/rows/RangeTombstoneBoundMarker.java | 22 +- .../db/rows/RangeTombstoneBoundaryMarker.java | 20 +- .../db/rows/RangeTombstoneMarker.java | 9 +- .../db/rows/RowAndDeletionMergeIterator.java | 4 +- .../UnfilteredRowIteratorWithLowerBound.java | 15 +- .../db/rows/UnfilteredSerializer.java | 14 +- .../internal/CassandraIndexSearcher.java | 10 +- .../cassandra/service/DataResolver.java | 6 +- .../cassandra/thrift/CassandraServer.java | 10 +- .../cassandra/tools/JsonTransformer.java | 8 +- .../TombstonesWithIndexedSSTableTest.java | 1 - .../ClusteringColumnRestrictionsTest.java | 64 ++-- .../org/apache/cassandra/db/KeyspaceTest.java | 12 +- .../cassandra/db/RangeTombstoneListTest.java | 16 +- .../cassandra/db/RangeTombstoneTest.java | 4 +- .../unit/org/apache/cassandra/db/RowTest.java | 10 +- .../db/SinglePartitionSliceCommandTest.java | 2 +- .../apache/cassandra/db/filter/SliceTest.java | 4 +- .../PartitionImplementationTest.java | 3 +- .../rows/RowAndDeletionMergeIteratorTest.java | 39 ++- .../rows/UnfilteredRowIteratorsMergeTest.java | 18 +- 47 files changed, 680 insertions(+), 708 deletions(-) create mode 100644 src/java/org/apache/cassandra/db/ClusteringBound.java create mode 100644 src/java/org/apache/cassandra/db/ClusteringBoundOrBoundary.java create mode 100644 src/java/org/apache/cassandra/db/ClusteringBoundary.java diff --git a/CHANGES.txt b/CHANGES.txt index f78ea90b9c..78518b68d9 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) diff --git a/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java index ab16ebca92..837ee13aa0 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 boundsAsClustering(Bound bound, QueryOptions options) throws InvalidRequestException + public NavigableSet boundsAsClustering(Bound bound, QueryOptions options) throws InvalidRequestException { MultiCBuilder builder = MultiCBuilder.create(comparator, hasIN() || hasMultiColumnSlice()); int keyPosition = 0; diff --git a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java index c4d7622123..43a912df74 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 getClusteringColumnsBounds(Bound b, QueryOptions options) + public NavigableSet getClusteringColumnsBounds(Bound b, QueryOptions options) { return clusteringColumnsRestrictions.boundsAsClustering(b, options); } diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java index 7243daac2c..6224457478 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 startBounds = restrictions.getClusteringColumnsBounds(Bound.START, options); - SortedSet endBounds = restrictions.getClusteringColumnsBounds(Bound.END, options); + SortedSet startBounds = restrictions.getClusteringColumnsBounds(Bound.START, options); + SortedSet 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 startBounds, SortedSet endBounds) + private Slices toSlices(SortedSet startBounds, SortedSet endBounds) { assert startBounds.size() == endBounds.size(); Slices.Builder builder = new Slices.Builder(cfm.comparator); - Iterator starts = startBounds.iterator(); - Iterator ends = endBounds.iterator(); + Iterator starts = startBounds.iterator(); + Iterator ends = endBounds.iterator(); while (starts.hasNext()) { diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index e46cb06060..3f72bd8007 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 startBounds = restrictions.getClusteringColumnsBounds(Bound.START, options); - SortedSet endBounds = restrictions.getClusteringColumnsBounds(Bound.END, options); + SortedSet startBounds = restrictions.getClusteringColumnsBounds(Bound.START, options); + SortedSet 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 startIter = startBounds.iterator(); - Iterator endIter = endBounds.iterator(); + Iterator startIter = startBounds.iterator(); + Iterator 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) diff --git a/src/java/org/apache/cassandra/db/AbstractReadCommandBuilder.java b/src/java/org/apache/cassandra/db/AbstractReadCommandBuilder.java index dab22c70e1..849e6845e3 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 columns; protected final RowFilter filter = RowFilter.create(); - private Slice.Bound lowerClusteringBound; - private Slice.Bound upperClusteringBound; + private ClusteringBound lowerClusteringBound; + private ClusteringBound upperClusteringBound; private NavigableSet 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); } } diff --git a/src/java/org/apache/cassandra/db/CBuilder.java b/src/java/org/apache/cassandra/db/CBuilder.java index 73b575f223..be56394f01 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 newValues, boolean isStart, boolean isInclusive) + public ClusteringBound buildBoundWith(List 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 newValues); - public abstract Slice.Bound buildBoundWith(ByteBuffer value, boolean isStart, boolean isInclusive); - public abstract Slice.Bound buildBoundWith(List newValues, boolean isStart, boolean isInclusive); + public abstract ClusteringBound buildBoundWith(ByteBuffer value, boolean isStart, boolean isInclusive); + public abstract ClusteringBound buildBoundWith(List 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 newValues, boolean isStart, boolean isInclusive) + public ClusteringBound buildBoundWith(List 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); } } } 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 0000000000..6366a379c7 --- /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 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 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 0000000000..0c965e97ae --- /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. + *

+ * 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. + *

+ * 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> 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> types) + { + return 1 // kind ordinal + + TypeSizes.sizeof((short)bound.size()) + + ClusteringPrefix.serializer.valuesWithoutSizeSerializedSize(bound, version, types); + } + + public ClusteringBoundOrBoundary deserialize(DataInputPlus in, int version, List> 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> 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> 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); + } + } +} 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 0000000000..503eaada0f --- /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 diff --git a/src/java/org/apache/cassandra/db/ClusteringPrefix.java b/src/java/org/apache/cassandra/db/ClusteringPrefix.java index df0befcfca..d6aa48427a 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. *

* 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> 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> 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> 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; } diff --git a/src/java/org/apache/cassandra/db/LegacyLayout.java b/src/java/org/apache/cassandra/db/LegacyLayout.java index 92ecbf5bcd..1c8012814d 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 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) diff --git a/src/java/org/apache/cassandra/db/MultiCBuilder.java b/src/java/org/apache/cassandra/db/MultiCBuilder.java index f03e6745fa..ae8c26c418 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 build(); /** - * Builds the Slice.Bounds for slice restrictions. + * Builds the ClusteringBounds 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 Slice.Bounds + * @return the ClusteringBounds */ - public abstract NavigableSet buildBoundForSlice(boolean isStart, + public abstract NavigableSet buildBoundForSlice(boolean isStart, boolean isInclusive, boolean isOtherBoundInclusive, List columnDefs); /** - * Builds the Slice.Bounds + * Builds the ClusteringBounds * * @param isStart specify if the bound is a start one * @param isInclusive specify if the bound is inclusive or not - * @return the Slice.Bounds + * @return the ClusteringBounds */ - public abstract NavigableSet buildBound(boolean isStart, boolean isInclusive); + public abstract NavigableSet 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 buildBoundForSlice(boolean isStart, - boolean isInclusive, - boolean isOtherBoundInclusive, - List columnDefs) + public NavigableSet buildBoundForSlice(boolean isStart, + boolean isInclusive, + boolean isOtherBoundInclusive, + List columnDefs) { return buildBound(isStart, columnDefs.get(0).isReversedType() ? isOtherBoundInclusive : isInclusive); } - public NavigableSet buildBound(boolean isStart, boolean isInclusive) + public NavigableSet 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 buildBoundForSlice(boolean isStart, + public NavigableSet buildBoundForSlice(boolean isStart, boolean isInclusive, boolean isOtherBoundInclusive, List 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 set = BTreeSet.builder(comparator); + BTreeSet.Builder 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 buildBound(boolean isStart, boolean isInclusive) + public NavigableSet 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 set = BTreeSet.builder(comparator); + BTreeSet.Builder set = BTreeSet.builder(comparator); for (int i = 0, m = elementsList.size(); i < m; i++) { diff --git a/src/java/org/apache/cassandra/db/MutableDeletionInfo.java b/src/java/org/apache/cassandra/db/MutableDeletionInfo.java index d01b1d1f12..1ba77bb02b 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); diff --git a/src/java/org/apache/cassandra/db/RangeTombstone.java b/src/java/org/apache/cassandra/db/RangeTombstone.java index 29feb46818..8e01b8e276 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. - *

- * 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> 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> 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> 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> 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> 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); - } - } - } } diff --git a/src/java/org/apache/cassandra/db/RangeTombstoneList.java b/src/java/org/apache/cassandra/db/RangeTombstoneList.java index baeb227a41..c60b77413b 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, 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, 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, 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, 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, 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, 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, IMeasurable private Iterator 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, 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.singletonIterator(rangeTombstoneWithNewBounds(start, s, e)); } @@ -425,14 +425,14 @@ public class RangeTombstoneList implements Iterable, IMeasurable private Iterator 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, 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.singletonIterator(rangeTombstoneWithNewBounds(start, s, e)); } @@ -527,7 +527,7 @@ public class RangeTombstoneList implements Iterable, 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, 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, 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, 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, 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, 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, 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(); diff --git a/src/java/org/apache/cassandra/db/ReadCommand.java b/src/java/org/apache/cassandra/db/ReadCommand.java index 387e062371..c842814c5e 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(); } diff --git a/src/java/org/apache/cassandra/db/Serializers.java b/src/java/org/apache/cassandra/db/Serializers.java index a0503e09bf..d6aac64fef 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()])); } } diff --git a/src/java/org/apache/cassandra/db/Slice.java b/src/java/org/apache/cassandra/db/Slice.java index 8611470171..c3da222612 100644 --- a/src/java/org/apache/cassandra/db/Slice.java +++ b/src/java/org/apache/cassandra/db/Slice.java @@ -38,10 +38,10 @@ public class Slice public static final Serializer serializer = new Serializer(); /** The slice selecting all rows (of a given partition) */ - public static final Slice ALL = new Slice(Bound.BOTTOM, Bound.TOP) + public static final Slice ALL = new Slice(ClusteringBound.BOTTOM, ClusteringBound.TOP) { @Override - public boolean selects(ClusteringComparator comparator, Clustering clustering) + public boolean includes(ClusteringComparator comparator, ClusteringPrefix clustering) { return true; } @@ -59,19 +59,19 @@ public class Slice } }; - private final Bound start; - private final Bound end; + private final ClusteringBound start; + private final ClusteringBound end; - private Slice(Bound start, Bound end) + private Slice(ClusteringBound start, ClusteringBound end) { assert start.isStart() && end.isEnd(); this.start = start; this.end = end; } - public static Slice make(Bound start, Bound end) + public static Slice make(ClusteringBound start, ClusteringBound end) { - if (start == Bound.BOTTOM && end == Bound.TOP) + if (start == ClusteringBound.BOTTOM && end == ClusteringBound.TOP) return ALL; return new Slice(start, end); @@ -95,7 +95,7 @@ public class Slice // This doesn't give us what we want with the clustering prefix assert clustering != Clustering.STATIC_CLUSTERING; ByteBuffer[] values = extractValues(clustering); - return new Slice(Bound.inclusiveStartOf(values), Bound.inclusiveEndOf(values)); + return new Slice(ClusteringBound.inclusiveStartOf(values), ClusteringBound.inclusiveEndOf(values)); } public static Slice make(Clustering start, Clustering end) @@ -106,7 +106,7 @@ public class Slice ByteBuffer[] startValues = extractValues(start); ByteBuffer[] endValues = extractValues(end); - return new Slice(Bound.inclusiveStartOf(startValues), Bound.inclusiveEndOf(endValues)); + return new Slice(ClusteringBound.inclusiveStartOf(startValues), ClusteringBound.inclusiveEndOf(endValues)); } private static ByteBuffer[] extractValues(ClusteringPrefix clustering) @@ -117,22 +117,22 @@ public class Slice return values; } - public Bound start() + public ClusteringBound start() { return start; } - public Bound end() + public ClusteringBound end() { return end; } - public Bound open(boolean reversed) + public ClusteringBound open(boolean reversed) { return reversed ? end : start; } - public Bound close(boolean reversed) + public ClusteringBound close(boolean reversed) { return reversed ? start : end; } @@ -157,34 +157,21 @@ public class Slice * @return whether the slice formed by {@code start} and {@code end} is * empty or not. */ - public static boolean isEmpty(ClusteringComparator comparator, Slice.Bound start, Slice.Bound end) + public static boolean isEmpty(ClusteringComparator comparator, ClusteringBound start, ClusteringBound end) { assert start.isStart() && end.isEnd(); return comparator.compare(end, start) < 0; } /** - * Returns whether a given clustering is selected by this slice. - * - * @param comparator the comparator for the table this is a slice of. - * @param clustering the clustering to test inclusion of. - * - * @return whether {@code clustering} is selected by this slice. - */ - public boolean selects(ClusteringComparator comparator, Clustering clustering) - { - return comparator.compare(start, clustering) <= 0 && comparator.compare(clustering, end) <= 0; - } - - /** - * Returns whether a given bound is included in this slice. + * Returns whether a given clustering or bound is included in this slice. * * @param comparator the comparator for the table this is a slice of. * @param bound the bound to test inclusion of. * * @return whether {@code bound} is within the bounds of this slice. */ - public boolean includes(ClusteringComparator comparator, Bound bound) + public boolean includes(ClusteringComparator comparator, ClusteringPrefix bound) { return comparator.compare(start, bound) <= 0 && comparator.compare(bound, end) <= 0; } @@ -218,7 +205,7 @@ public class Slice return this; ByteBuffer[] values = extractValues(lastReturned); - return new Slice(start, inclusive ? Bound.inclusiveEndOf(values) : Bound.exclusiveEndOf(values)); + return new Slice(start, inclusive ? ClusteringBound.inclusiveEndOf(values) : ClusteringBound.exclusiveEndOf(values)); } else { @@ -231,7 +218,7 @@ public class Slice return this; ByteBuffer[] values = extractValues(lastReturned); - return new Slice(inclusive ? Bound.inclusiveStartOf(values) : Bound.exclusiveStartOf(values), end); + return new Slice(inclusive ? ClusteringBound.inclusiveStartOf(values) : ClusteringBound.exclusiveStartOf(values), end); } } @@ -320,238 +307,21 @@ public class Slice { public void serialize(Slice slice, DataOutputPlus out, int version, List> types) throws IOException { - Bound.serializer.serialize(slice.start, out, version, types); - Bound.serializer.serialize(slice.end, out, version, types); + ClusteringBound.serializer.serialize(slice.start, out, version, types); + ClusteringBound.serializer.serialize(slice.end, out, version, types); } public long serializedSize(Slice slice, int version, List> types) { - return Bound.serializer.serializedSize(slice.start, version, types) - + Bound.serializer.serializedSize(slice.end, version, types); + return ClusteringBound.serializer.serializedSize(slice.start, version, types) + + ClusteringBound.serializer.serializedSize(slice.end, version, types); } public Slice deserialize(DataInputPlus in, int version, List> types) throws IOException { - Bound start = Bound.serializer.deserialize(in, version, types); - Bound end = Bound.serializer.deserialize(in, version, types); + ClusteringBound start = (ClusteringBound) ClusteringBound.serializer.deserialize(in, version, types); + ClusteringBound end = (ClusteringBound) ClusteringBound.serializer.deserialize(in, version, types); return new Slice(start, end); } } - - /** - * The bound of a slice. - *

- * This can be either a start or an end bound, and this can be either inclusive or exclusive. - */ - public static class Bound extends AbstractBufferClusteringPrefix - { - public static final Serializer serializer = new Serializer(); - - /** - * The smallest and biggest bound. Note that as range tomstone bounds are (special case) of slice bounds, - * we want the BOTTOM and TOP to be the same object, but we alias them here because it's cleaner when dealing - * with slices to refer to Slice.Bound.BOTTOM and Slice.Bound.TOP. - */ - public static final Bound BOTTOM = RangeTombstone.Bound.BOTTOM; - public static final Bound TOP = RangeTombstone.Bound.TOP; - - protected Bound(Kind kind, ByteBuffer[] values) - { - super(kind, values); - } - - public static Bound create(Kind kind, ByteBuffer[] values) - { - assert !kind.isBoundary(); - return new Bound(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 Bound inclusiveStartOf(ByteBuffer... values) - { - return create(Kind.INCL_START_BOUND, values); - } - - public static Bound inclusiveEndOf(ByteBuffer... values) - { - return create(Kind.INCL_END_BOUND, values); - } - - public static Bound exclusiveStartOf(ByteBuffer... values) - { - return create(Kind.EXCL_START_BOUND, values); - } - - public static Bound exclusiveEndOf(ByteBuffer... values) - { - return create(Kind.EXCL_END_BOUND, values); - } - - public static Bound 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 Bound 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 Bound 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 Bound 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); - } - - public Bound withNewKind(Kind kind) - { - assert !kind.isBoundary(); - return new Bound(kind, values); - } - - 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; - } - - /** - * Returns the inverse of the current bound. - *

- * 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 Slice.Bound invert() - { - return withNewKind(kind().invert()); - } - - // 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) - private int compareTo(ClusteringComparator comparator, List 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); - } - - 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(); - } - - /** - * Serializer for slice bounds. - *

- * Contrarily to {@code Clustering}, a slice bound can be a true prefix of the full clustering, so we actually record - * its size. - */ - public static class Serializer - { - public void serialize(Slice.Bound bound, DataOutputPlus out, int version, List> types) throws IOException - { - out.writeByte(bound.kind().ordinal()); - out.writeShort(bound.size()); - ClusteringPrefix.serializer.serializeValuesWithoutSize(bound, out, version, types); - } - - public long serializedSize(Slice.Bound bound, int version, List> types) - { - return 1 // kind ordinal - + TypeSizes.sizeof((short)bound.size()) - + ClusteringPrefix.serializer.valuesWithoutSizeSerializedSize(bound, version, types); - } - - public Slice.Bound deserialize(DataInputPlus in, int version, List> types) throws IOException - { - Kind kind = Kind.values()[in.readByte()]; - return deserializeValues(in, kind, version, types); - } - - public Slice.Bound deserializeValues(DataInputPlus in, Kind kind, int version, List> 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 Slice.Bound.create(kind, values); - } - } - } } diff --git a/src/java/org/apache/cassandra/db/Slices.java b/src/java/org/apache/cassandra/db/Slices.java index 13533d627b..4fcda59342 100644 --- a/src/java/org/apache/cassandra/db/Slices.java +++ b/src/java/org/apache/cassandra/db/Slices.java @@ -59,7 +59,7 @@ public abstract class Slices implements Iterable */ public static Slices with(ClusteringComparator comparator, Slice slice) { - if (slice.start() == Slice.Bound.BOTTOM && slice.end() == Slice.Bound.TOP) + if (slice.start() == ClusteringBound.BOTTOM && slice.end() == ClusteringBound.TOP) return Slices.ALL; assert comparator.compare(slice.start(), slice.end()) <= 0; @@ -186,7 +186,7 @@ public abstract class Slices implements Iterable this.slices = new ArrayList<>(initialSize); } - public Builder add(Slice.Bound start, Slice.Bound end) + public Builder add(ClusteringBound start, ClusteringBound end) { return add(Slice.make(start, end)); } @@ -328,7 +328,7 @@ public abstract class Slices implements Iterable for (int i = 0; i < size; i++) slices[i] = Slice.serializer.deserialize(in, version, metadata.comparator.subtypes()); - if (size == 1 && slices[0].start() == Slice.Bound.BOTTOM && slices[0].end() == Slice.Bound.TOP) + if (size == 1 && slices[0].start() == ClusteringBound.BOTTOM && slices[0].end() == ClusteringBound.TOP) return ALL; return new ArrayBackedSlices(metadata.comparator, slices); @@ -646,8 +646,8 @@ public abstract class Slices implements Iterable public static ComponentOfSlice fromSlice(int component, Slice slice) { - Slice.Bound start = slice.start(); - Slice.Bound end = slice.end(); + ClusteringBound start = slice.start(); + ClusteringBound end = slice.end(); if (component >= start.size() && component >= end.size()) return null; diff --git a/src/java/org/apache/cassandra/db/UnfilteredDeserializer.java b/src/java/org/apache/cassandra/db/UnfilteredDeserializer.java index a9b2903a13..88be4e5778 100644 --- a/src/java/org/apache/cassandra/db/UnfilteredDeserializer.java +++ b/src/java/org/apache/cassandra/db/UnfilteredDeserializer.java @@ -81,7 +81,7 @@ public abstract class UnfilteredDeserializer * comparison. Whenever we know what to do with this atom (read it or skip it), * readNext or skipNext should be called. */ - public abstract int compareNextTo(Slice.Bound bound) throws IOException; + public abstract int compareNextTo(ClusteringBound bound) throws IOException; /** * Returns whether the next atom is a row or not. @@ -173,7 +173,7 @@ public abstract class UnfilteredDeserializer isReady = true; } - public int compareNextTo(Slice.Bound bound) throws IOException + public int compareNextTo(ClusteringBound bound) throws IOException { if (!isReady) prepareNext(); @@ -202,7 +202,7 @@ public abstract class UnfilteredDeserializer isReady = false; if (UnfilteredSerializer.kind(nextFlags) == Unfiltered.Kind.RANGE_TOMBSTONE_MARKER) { - RangeTombstone.Bound bound = clusteringDeserializer.deserializeNextBound(); + ClusteringBoundOrBoundary bound = clusteringDeserializer.deserializeNextBound(); return UnfilteredSerializer.serializer.deserializeMarkerBody(in, header, bound); } else @@ -326,7 +326,7 @@ public abstract class UnfilteredDeserializer return tombstone.isCollectionTombstone() || tombstone.isRowDeletion(metadata); } - public int compareNextTo(Slice.Bound bound) throws IOException + public int compareNextTo(ClusteringBound bound) throws IOException { if (!hasNext()) throw new IllegalStateException(); diff --git a/src/java/org/apache/cassandra/db/columniterator/AbstractSSTableIterator.java b/src/java/org/apache/cassandra/db/columniterator/AbstractSSTableIterator.java index 5ee46dae03..8e0f42ee6c 100644 --- a/src/java/org/apache/cassandra/db/columniterator/AbstractSSTableIterator.java +++ b/src/java/org/apache/cassandra/db/columniterator/AbstractSSTableIterator.java @@ -555,11 +555,11 @@ public abstract class AbstractSSTableIterator implements UnfilteredRowIterator // Finds the index of the first block containing the provided bound, starting at the provided index. // Will be -1 if the bound is before any block, and blocksCount() if it is after every block. - public int findBlockIndex(Slice.Bound bound, int fromIdx) throws IOException + public int findBlockIndex(ClusteringBound bound, int fromIdx) throws IOException { - if (bound == Slice.Bound.BOTTOM) + if (bound == ClusteringBound.BOTTOM) return -1; - if (bound == Slice.Bound.TOP) + if (bound == ClusteringBound.TOP) return blocksCount(); return indexFor(bound, fromIdx); diff --git a/src/java/org/apache/cassandra/db/columniterator/SSTableIterator.java b/src/java/org/apache/cassandra/db/columniterator/SSTableIterator.java index 6b8f83fab1..e4f670030b 100644 --- a/src/java/org/apache/cassandra/db/columniterator/SSTableIterator.java +++ b/src/java/org/apache/cassandra/db/columniterator/SSTableIterator.java @@ -59,9 +59,9 @@ public class SSTableIterator extends AbstractSSTableIterator private class ForwardReader extends Reader { // The start of the current slice. This will be null as soon as we know we've passed that bound. - protected Slice.Bound start; + protected ClusteringBound start; // The end of the current slice. Will never be null. - protected Slice.Bound end = Slice.Bound.TOP; + protected ClusteringBound end = ClusteringBound.TOP; protected Unfiltered next; // the next element to return: this is computed by hasNextInternal(). @@ -75,7 +75,7 @@ public class SSTableIterator extends AbstractSSTableIterator public void setForSlice(Slice slice) throws IOException { - start = slice.start() == Slice.Bound.BOTTOM ? null : slice.start(); + start = slice.start() == ClusteringBound.BOTTOM ? null : slice.start(); end = slice.end(); sliceDone = false; @@ -103,7 +103,7 @@ public class SSTableIterator extends AbstractSSTableIterator updateOpenMarker((RangeTombstoneMarker)deserializer.readNext()); } - Slice.Bound sliceStart = start; + ClusteringBound sliceStart = start; start = null; // We've reached the beginning of our queried slice. If we have an open marker diff --git a/src/java/org/apache/cassandra/db/columniterator/SSTableReversedIterator.java b/src/java/org/apache/cassandra/db/columniterator/SSTableReversedIterator.java index 7594cbd5fa..7f6b4620be 100644 --- a/src/java/org/apache/cassandra/db/columniterator/SSTableReversedIterator.java +++ b/src/java/org/apache/cassandra/db/columniterator/SSTableReversedIterator.java @@ -141,7 +141,7 @@ public class SSTableReversedIterator extends AbstractSSTableIterator // Reads the unfiltered from disk and load them into the reader buffer. It stops reading when either the partition // is fully read, or when stopReadingDisk() returns true. - protected void loadFromDisk(Slice.Bound start, Slice.Bound end, boolean includeFirst) throws IOException + protected void loadFromDisk(ClusteringBound start, ClusteringBound end, boolean includeFirst) throws IOException { buffer.reset(); @@ -163,7 +163,7 @@ public class SSTableReversedIterator extends AbstractSSTableIterator // If we have an open marker, it's either one from what we just skipped (if start != null), or it's from the previous index block. if (openMarker != null) { - RangeTombstone.Bound markerStart = start == null ? RangeTombstone.Bound.BOTTOM : RangeTombstone.Bound.fromSliceBound(start); + ClusteringBound markerStart = start == null ? ClusteringBound.BOTTOM : start; buffer.add(new RangeTombstoneBoundMarker(markerStart, openMarker)); } @@ -186,7 +186,7 @@ public class SSTableReversedIterator extends AbstractSSTableIterator if (openMarker != null) { // If we have no end and still an openMarker, this means we're indexed and the marker is closed in a following block. - RangeTombstone.Bound markerEnd = end == null ? RangeTombstone.Bound.TOP : RangeTombstone.Bound.fromSliceBound(end); + ClusteringBound markerEnd = end == null ? ClusteringBound.TOP : end; buffer.add(new RangeTombstoneBoundMarker(markerEnd, getAndClearOpenMarker())); } diff --git a/src/java/org/apache/cassandra/db/partitions/AbstractBTreePartition.java b/src/java/org/apache/cassandra/db/partitions/AbstractBTreePartition.java index c276c570ac..1c05f3c682 100644 --- a/src/java/org/apache/cassandra/db/partitions/AbstractBTreePartition.java +++ b/src/java/org/apache/cassandra/db/partitions/AbstractBTreePartition.java @@ -193,8 +193,8 @@ public abstract class AbstractBTreePartition implements Partition, Iterable private UnfilteredRowIterator sliceIterator(ColumnFilter selection, Slice slice, boolean reversed, Holder current, Row staticRow) { - Slice.Bound start = slice.start() == Slice.Bound.BOTTOM ? null : slice.start(); - Slice.Bound end = slice.end() == Slice.Bound.TOP ? null : slice.end(); + ClusteringBound start = slice.start() == ClusteringBound.BOTTOM ? null : slice.start(); + ClusteringBound end = slice.end() == ClusteringBound.TOP ? null : slice.end(); Iterator rowIter = BTree.slice(current.tree, metadata.comparator, start, true, end, true, desc(reversed)); Iterator deleteIter = current.deletionInfo.rangeIterator(slice, reversed); diff --git a/src/java/org/apache/cassandra/db/rows/AbstractRangeTombstoneMarker.java b/src/java/org/apache/cassandra/db/rows/AbstractRangeTombstoneMarker.java index b1ee7ec586..153243c68a 100644 --- a/src/java/org/apache/cassandra/db/rows/AbstractRangeTombstoneMarker.java +++ b/src/java/org/apache/cassandra/db/rows/AbstractRangeTombstoneMarker.java @@ -20,18 +20,18 @@ package org.apache.cassandra.db.rows; import java.nio.ByteBuffer; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.db.*; +import org.apache.cassandra.db.ClusteringBoundOrBoundary; -public abstract class AbstractRangeTombstoneMarker implements RangeTombstoneMarker +public abstract class AbstractRangeTombstoneMarker implements RangeTombstoneMarker { - protected final RangeTombstone.Bound bound; + protected final B bound; - protected AbstractRangeTombstoneMarker(RangeTombstone.Bound bound) + protected AbstractRangeTombstoneMarker(B bound) { this.bound = bound; } - public RangeTombstone.Bound clustering() + public B clustering() { return bound; } @@ -58,7 +58,7 @@ public abstract class AbstractRangeTombstoneMarker implements RangeTombstoneMark public void validateData(CFMetaData metadata) { - Slice.Bound bound = clustering(); + ClusteringBoundOrBoundary bound = clustering(); for (int i = 0; i < bound.size(); i++) { ByteBuffer value = bound.get(i); diff --git a/src/java/org/apache/cassandra/db/rows/RangeTombstoneBoundMarker.java b/src/java/org/apache/cassandra/db/rows/RangeTombstoneBoundMarker.java index b35033d3e9..45e594b93e 100644 --- a/src/java/org/apache/cassandra/db/rows/RangeTombstoneBoundMarker.java +++ b/src/java/org/apache/cassandra/db/rows/RangeTombstoneBoundMarker.java @@ -28,43 +28,37 @@ import org.apache.cassandra.utils.memory.AbstractAllocator; /** * A range tombstone marker that indicates the bound of a range tombstone (start or end). */ -public class RangeTombstoneBoundMarker extends AbstractRangeTombstoneMarker +public class RangeTombstoneBoundMarker extends AbstractRangeTombstoneMarker { private final DeletionTime deletion; - public RangeTombstoneBoundMarker(RangeTombstone.Bound bound, DeletionTime deletion) + public RangeTombstoneBoundMarker(ClusteringBound bound, DeletionTime deletion) { super(bound); - assert !bound.isBoundary(); this.deletion = deletion; } - public RangeTombstoneBoundMarker(Slice.Bound bound, DeletionTime deletion) - { - this(new RangeTombstone.Bound(bound.kind(), bound.getRawValues()), deletion); - } - public static RangeTombstoneBoundMarker inclusiveOpen(boolean reversed, ByteBuffer[] boundValues, DeletionTime deletion) { - RangeTombstone.Bound bound = RangeTombstone.Bound.inclusiveOpen(reversed, boundValues); + ClusteringBound bound = ClusteringBound.inclusiveOpen(reversed, boundValues); return new RangeTombstoneBoundMarker(bound, deletion); } public static RangeTombstoneBoundMarker exclusiveOpen(boolean reversed, ByteBuffer[] boundValues, DeletionTime deletion) { - RangeTombstone.Bound bound = RangeTombstone.Bound.exclusiveOpen(reversed, boundValues); + ClusteringBound bound = ClusteringBound.exclusiveOpen(reversed, boundValues); return new RangeTombstoneBoundMarker(bound, deletion); } public static RangeTombstoneBoundMarker inclusiveClose(boolean reversed, ByteBuffer[] boundValues, DeletionTime deletion) { - RangeTombstone.Bound bound = RangeTombstone.Bound.inclusiveClose(reversed, boundValues); + ClusteringBound bound = ClusteringBound.inclusiveClose(reversed, boundValues); return new RangeTombstoneBoundMarker(bound, deletion); } public static RangeTombstoneBoundMarker exclusiveClose(boolean reversed, ByteBuffer[] boundValues, DeletionTime deletion) { - RangeTombstone.Bound bound = RangeTombstone.Bound.exclusiveClose(reversed, boundValues); + ClusteringBound bound = ClusteringBound.exclusiveClose(reversed, boundValues); return new RangeTombstoneBoundMarker(bound, deletion); } @@ -109,12 +103,12 @@ public class RangeTombstoneBoundMarker extends AbstractRangeTombstoneMarker return bound.isInclusive(); } - public RangeTombstone.Bound openBound(boolean reversed) + public ClusteringBound openBound(boolean reversed) { return isOpen(reversed) ? clustering() : null; } - public RangeTombstone.Bound closeBound(boolean reversed) + public ClusteringBound closeBound(boolean reversed) { return isClose(reversed) ? clustering() : null; } diff --git a/src/java/org/apache/cassandra/db/rows/RangeTombstoneBoundaryMarker.java b/src/java/org/apache/cassandra/db/rows/RangeTombstoneBoundaryMarker.java index 06fbf87c74..fd41bea346 100644 --- a/src/java/org/apache/cassandra/db/rows/RangeTombstoneBoundaryMarker.java +++ b/src/java/org/apache/cassandra/db/rows/RangeTombstoneBoundaryMarker.java @@ -28,12 +28,12 @@ import org.apache.cassandra.utils.memory.AbstractAllocator; /** * A range tombstone marker that represents a boundary between 2 range tombstones (i.e. it closes one range and open another). */ -public class RangeTombstoneBoundaryMarker extends AbstractRangeTombstoneMarker +public class RangeTombstoneBoundaryMarker extends AbstractRangeTombstoneMarker { private final DeletionTime endDeletion; private final DeletionTime startDeletion; - public RangeTombstoneBoundaryMarker(RangeTombstone.Bound bound, DeletionTime endDeletion, DeletionTime startDeletion) + public RangeTombstoneBoundaryMarker(ClusteringBoundary bound, DeletionTime endDeletion, DeletionTime startDeletion) { super(bound); assert bound.isBoundary(); @@ -43,7 +43,7 @@ public class RangeTombstoneBoundaryMarker extends AbstractRangeTombstoneMarker public static RangeTombstoneBoundaryMarker exclusiveCloseInclusiveOpen(boolean reversed, ByteBuffer[] boundValues, DeletionTime closeDeletion, DeletionTime openDeletion) { - RangeTombstone.Bound bound = RangeTombstone.Bound.exclusiveCloseInclusiveOpen(reversed, boundValues); + ClusteringBoundary bound = ClusteringBoundary.exclusiveCloseInclusiveOpen(reversed, boundValues); DeletionTime endDeletion = reversed ? openDeletion : closeDeletion; DeletionTime startDeletion = reversed ? closeDeletion : openDeletion; return new RangeTombstoneBoundaryMarker(bound, endDeletion, startDeletion); @@ -51,7 +51,7 @@ public class RangeTombstoneBoundaryMarker extends AbstractRangeTombstoneMarker public static RangeTombstoneBoundaryMarker inclusiveCloseExclusiveOpen(boolean reversed, ByteBuffer[] boundValues, DeletionTime closeDeletion, DeletionTime openDeletion) { - RangeTombstone.Bound bound = RangeTombstone.Bound.inclusiveCloseExclusiveOpen(reversed, boundValues); + ClusteringBoundary bound = ClusteringBoundary.inclusiveCloseExclusiveOpen(reversed, boundValues); DeletionTime endDeletion = reversed ? openDeletion : closeDeletion; DeletionTime startDeletion = reversed ? closeDeletion : openDeletion; return new RangeTombstoneBoundaryMarker(bound, endDeletion, startDeletion); @@ -88,14 +88,14 @@ public class RangeTombstoneBoundaryMarker extends AbstractRangeTombstoneMarker return (bound.kind() == ClusteringPrefix.Kind.EXCL_END_INCL_START_BOUNDARY) ^ reversed; } - public RangeTombstone.Bound openBound(boolean reversed) + public ClusteringBound openBound(boolean reversed) { - return bound.withNewKind(bound.kind().openBoundOfBoundary(reversed)); + return bound.openBound(reversed); } - public RangeTombstone.Bound closeBound(boolean reversed) + public ClusteringBound closeBound(boolean reversed) { - return bound.withNewKind(bound.kind().closeBoundOfBoundary(reversed)); + return bound.closeBound(reversed); } public boolean closeIsInclusive(boolean reversed) @@ -120,9 +120,9 @@ public class RangeTombstoneBoundaryMarker extends AbstractRangeTombstoneMarker return new RangeTombstoneBoundaryMarker(clustering().copy(allocator), endDeletion, startDeletion); } - public static RangeTombstoneBoundaryMarker makeBoundary(boolean reversed, Slice.Bound close, Slice.Bound open, DeletionTime closeDeletion, DeletionTime openDeletion) + public static RangeTombstoneBoundaryMarker makeBoundary(boolean reversed, ClusteringBound close, ClusteringBound open, DeletionTime closeDeletion, DeletionTime openDeletion) { - assert RangeTombstone.Bound.Kind.compare(close.kind(), open.kind()) == 0 : "Both bound don't form a boundary"; + assert ClusteringPrefix.Kind.compare(close.kind(), open.kind()) == 0 : "Both bound don't form a boundary"; boolean isExclusiveClose = close.isExclusive() || (close.isInclusive() && open.isInclusive() && openDeletion.supersedes(closeDeletion)); return isExclusiveClose ? exclusiveCloseInclusiveOpen(reversed, close.getRawValues(), closeDeletion, openDeletion) diff --git a/src/java/org/apache/cassandra/db/rows/RangeTombstoneMarker.java b/src/java/org/apache/cassandra/db/rows/RangeTombstoneMarker.java index 053b5dcb3e..bc98899119 100644 --- a/src/java/org/apache/cassandra/db/rows/RangeTombstoneMarker.java +++ b/src/java/org/apache/cassandra/db/rows/RangeTombstoneMarker.java @@ -20,7 +20,6 @@ package org.apache.cassandra.db.rows; import java.nio.ByteBuffer; import java.util.*; -import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.db.*; import org.apache.cassandra.utils.memory.AbstractAllocator; @@ -33,7 +32,7 @@ import org.apache.cassandra.utils.memory.AbstractAllocator; public interface RangeTombstoneMarker extends Unfiltered { @Override - public RangeTombstone.Bound clustering(); + public ClusteringBoundOrBoundary clustering(); public boolean isBoundary(); @@ -45,8 +44,8 @@ public interface RangeTombstoneMarker extends Unfiltered public boolean openIsInclusive(boolean reversed); public boolean closeIsInclusive(boolean reversed); - public RangeTombstone.Bound openBound(boolean reversed); - public RangeTombstone.Bound closeBound(boolean reversed); + public ClusteringBound openBound(boolean reversed); + public ClusteringBound closeBound(boolean reversed); public RangeTombstoneMarker copy(AbstractAllocator allocator); @@ -68,7 +67,7 @@ public interface RangeTombstoneMarker extends Unfiltered private final DeletionTime partitionDeletion; private final boolean reversed; - private RangeTombstone.Bound bound; + private ClusteringBoundOrBoundary bound; private final RangeTombstoneMarker[] markers; // For each iterator, what is the currently open marker deletion time (or null if there is no open marker on that iterator) diff --git a/src/java/org/apache/cassandra/db/rows/RowAndDeletionMergeIterator.java b/src/java/org/apache/cassandra/db/rows/RowAndDeletionMergeIterator.java index 389fe4551c..5d7d8fe5c3 100644 --- a/src/java/org/apache/cassandra/db/rows/RowAndDeletionMergeIterator.java +++ b/src/java/org/apache/cassandra/db/rows/RowAndDeletionMergeIterator.java @@ -153,12 +153,12 @@ public class RowAndDeletionMergeIterator extends AbstractUnfilteredRowIterator return range; } - private Slice.Bound openBound(RangeTombstone range) + private ClusteringBound openBound(RangeTombstone range) { return range.deletedSlice().open(isReverseOrder()); } - private Slice.Bound closeBound(RangeTombstone range) + private ClusteringBound closeBound(RangeTombstone range) { return range.deletedSlice().close(isReverseOrder()); } diff --git a/src/java/org/apache/cassandra/db/rows/UnfilteredRowIteratorWithLowerBound.java b/src/java/org/apache/cassandra/db/rows/UnfilteredRowIteratorWithLowerBound.java index 5c04966a3e..fd74fc6505 100644 --- a/src/java/org/apache/cassandra/db/rows/UnfilteredRowIteratorWithLowerBound.java +++ b/src/java/org/apache/cassandra/db/rows/UnfilteredRowIteratorWithLowerBound.java @@ -31,7 +31,7 @@ public class UnfilteredRowIteratorWithLowerBound extends LazilyInitializedUnfilt private final boolean isForThrift; private final int nowInSec; private final boolean applyThriftTransformation; - private RangeTombstone.Bound lowerBound; + private ClusteringBound lowerBound; private boolean firstItemRetrieved; public UnfilteredRowIteratorWithLowerBound(DecoratedKey partitionKey, @@ -61,12 +61,11 @@ public class UnfilteredRowIteratorWithLowerBound extends LazilyInitializedUnfilt // The partition index lower bound is more accurate than the sstable metadata lower bound but it is only // present if the iterator has already been initialized, which we only do when there are tombstones since in // this case we cannot use the sstable metadata clustering values - - RangeTombstone.Bound ret = getPartitionIndexLowerBound(); + ClusteringBound ret = getPartitionIndexLowerBound(); return ret != null ? makeBound(ret) : makeBound(getMetadataLowerBound()); } - private Unfiltered makeBound(RangeTombstone.Bound bound) + private Unfiltered makeBound(ClusteringBound bound) { if (bound == null) return null; @@ -158,7 +157,7 @@ public class UnfilteredRowIteratorWithLowerBound extends LazilyInitializedUnfilt /** * @return the lower bound stored on the index entry for this partition, if available. */ - private RangeTombstone.Bound getPartitionIndexLowerBound() + private ClusteringBound getPartitionIndexLowerBound() { // NOTE: CASSANDRA-11206 removed the lookup against the key-cache as the IndexInfo objects are no longer // in memory for not heap backed IndexInfo objects (so, these are on disk). @@ -182,7 +181,7 @@ public class UnfilteredRowIteratorWithLowerBound extends LazilyInitializedUnfilt lowerBoundPrefix.getRawValues().length, sstable.metadata.comparator.size(), sstable.getFilename()); - return RangeTombstone.Bound.inclusiveOpen(filter.isReversed(), lowerBoundPrefix.getRawValues()); + return ClusteringBound.inclusiveOpen(filter.isReversed(), lowerBoundPrefix.getRawValues()); } catch (IOException e) { @@ -204,7 +203,7 @@ public class UnfilteredRowIteratorWithLowerBound extends LazilyInitializedUnfilt * @return a global lower bound made from the clustering values stored in the sstable metadata, note that * this currently does not correctly compare tombstone bounds, especially ranges. */ - private RangeTombstone.Bound getMetadataLowerBound() + private ClusteringBound getMetadataLowerBound() { if (!canUseMetadataLowerBound()) return null; @@ -216,6 +215,6 @@ public class UnfilteredRowIteratorWithLowerBound extends LazilyInitializedUnfilt vals.size(), sstable.metadata.comparator.size(), sstable.getFilename()); - return RangeTombstone.Bound.inclusiveOpen(filter.isReversed(), vals.toArray(new ByteBuffer[vals.size()])); + return ClusteringBound.inclusiveOpen(filter.isReversed(), vals.toArray(new ByteBuffer[vals.size()])); } } diff --git a/src/java/org/apache/cassandra/db/rows/UnfilteredSerializer.java b/src/java/org/apache/cassandra/db/rows/UnfilteredSerializer.java index 0fa0f3e6c3..27b0df11ea 100644 --- a/src/java/org/apache/cassandra/db/rows/UnfilteredSerializer.java +++ b/src/java/org/apache/cassandra/db/rows/UnfilteredSerializer.java @@ -53,7 +53,7 @@ import org.apache.cassandra.io.util.DataOutputPlus; * is the vint encoded value of n, i.e. 's 1-based index, * are the for this complex column * is where is the marker bound as serialized - * by {@code Slice.Bound.serializer} and is the marker deletion + * by {@code ClusteringBoundOrBoundary.serializer} and is the marker deletion * time. * * A cell start with a 1 byte . The 2nd and third flag bits indicate if @@ -203,7 +203,7 @@ public class UnfilteredSerializer throws IOException { out.writeByte((byte)IS_MARKER); - RangeTombstone.Bound.serializer.serialize(marker.clustering(), out, version, header.clusteringTypes()); + ClusteringBoundOrBoundary.serializer.serialize(marker.clustering(), out, version, header.clusteringTypes()); if (header.isForSSTable()) { @@ -305,7 +305,7 @@ public class UnfilteredSerializer { assert !header.isForSSTable(); return 1 // flags - + RangeTombstone.Bound.serializer.serializedSize(marker.clustering(), version, header.clusteringTypes()) + + ClusteringBoundOrBoundary.serializer.serializedSize(marker.clustering(), version, header.clusteringTypes()) + serializedMarkerBodySize(marker, header, previousUnfilteredSize, version); } @@ -352,7 +352,7 @@ public class UnfilteredSerializer if (kind(flags) == Unfiltered.Kind.RANGE_TOMBSTONE_MARKER) { - RangeTombstone.Bound bound = RangeTombstone.Bound.serializer.deserialize(in, helper.version, header.clusteringTypes()); + ClusteringBoundOrBoundary bound = ClusteringBoundOrBoundary.serializer.deserialize(in, helper.version, header.clusteringTypes()); return deserializeMarkerBody(in, header, bound); } else @@ -374,7 +374,7 @@ public class UnfilteredSerializer return deserializeRowBody(in, header, helper, flags, extendedFlags, builder); } - public RangeTombstoneMarker deserializeMarkerBody(DataInputPlus in, SerializationHeader header, RangeTombstone.Bound bound) + public RangeTombstoneMarker deserializeMarkerBody(DataInputPlus in, SerializationHeader header, ClusteringBoundOrBoundary bound) throws IOException { if (header.isForSSTable()) @@ -384,9 +384,9 @@ public class UnfilteredSerializer } if (bound.isBoundary()) - return new RangeTombstoneBoundaryMarker(bound, header.readDeletionTime(in), header.readDeletionTime(in)); + return new RangeTombstoneBoundaryMarker((ClusteringBoundary) bound, header.readDeletionTime(in), header.readDeletionTime(in)); else - return new RangeTombstoneBoundMarker(bound, header.readDeletionTime(in)); + return new RangeTombstoneBoundMarker((ClusteringBound) bound, header.readDeletionTime(in)); } public Row deserializeRowBody(DataInputPlus in, diff --git a/src/java/org/apache/cassandra/index/internal/CassandraIndexSearcher.java b/src/java/org/apache/cassandra/index/internal/CassandraIndexSearcher.java index 1e2857910d..47d20169b0 100644 --- a/src/java/org/apache/cassandra/index/internal/CassandraIndexSearcher.java +++ b/src/java/org/apache/cassandra/index/internal/CassandraIndexSearcher.java @@ -112,8 +112,8 @@ public abstract class CassandraIndexSearcher implements Index.Searcher DecoratedKey startKey = (DecoratedKey) range.left; DecoratedKey endKey = (DecoratedKey) range.right; - Slice.Bound start = Slice.Bound.BOTTOM; - Slice.Bound end = Slice.Bound.TOP; + ClusteringBound start = ClusteringBound.BOTTOM; + ClusteringBound end = ClusteringBound.TOP; /* * For index queries over a range, we can't do a whole lot better than querying everything for the key range, though for @@ -146,15 +146,15 @@ public abstract class CassandraIndexSearcher implements Index.Searcher else { // otherwise, just start the index slice from the key we do have - slice = Slice.make(makeIndexBound(((DecoratedKey)range.left).getKey(), Slice.Bound.BOTTOM), - Slice.Bound.TOP); + slice = Slice.make(makeIndexBound(((DecoratedKey)range.left).getKey(), ClusteringBound.BOTTOM), + ClusteringBound.TOP); } } return new ClusteringIndexSliceFilter(Slices.with(index.getIndexComparator(), slice), false); } } - private Slice.Bound makeIndexBound(ByteBuffer rowKey, Slice.Bound bound) + private ClusteringBound makeIndexBound(ByteBuffer rowKey, ClusteringBound bound) { return index.buildIndexClusteringPrefix(rowKey, bound, null) .buildBound(bound.isStart(), bound.isInclusive()); diff --git a/src/java/org/apache/cassandra/service/DataResolver.java b/src/java/org/apache/cassandra/service/DataResolver.java index 7fa6b72922..bbc037917c 100644 --- a/src/java/org/apache/cassandra/service/DataResolver.java +++ b/src/java/org/apache/cassandra/service/DataResolver.java @@ -167,7 +167,7 @@ public class DataResolver extends ResponseResolver private final Row.Builder[] currentRows = new Row.Builder[sources.length]; private final RowDiffListener diffListener; - private final Slice.Bound[] markerOpen = new Slice.Bound[sources.length]; + private final ClusteringBound[] markerOpen = new ClusteringBound[sources.length]; private final DeletionTime[] markerTime = new DeletionTime[sources.length]; public MergeListener(DecoratedKey partitionKey, PartitionColumns columns, boolean isReversed) @@ -268,8 +268,8 @@ public class DataResolver extends ResponseResolver // Note that boundaries are both close and open, so it's not one or the other if (merged.isClose(isReversed) && markerOpen[i] != null) { - Slice.Bound open = markerOpen[i]; - Slice.Bound close = merged.closeBound(isReversed); + ClusteringBound open = markerOpen[i]; + ClusteringBound close = merged.closeBound(isReversed); update(i).add(new RangeTombstone(Slice.make(isReversed ? close : open, isReversed ? open : close), markerTime[i])); } if (merged.isOpen(isReversed) && (marker == null || merged.openDeletionTime(isReversed).supersedes(marker.openDeletionTime(isReversed)))) diff --git a/src/java/org/apache/cassandra/thrift/CassandraServer.java b/src/java/org/apache/cassandra/thrift/CassandraServer.java index b958c67d76..357958cc98 100644 --- a/src/java/org/apache/cassandra/thrift/CassandraServer.java +++ b/src/java/org/apache/cassandra/thrift/CassandraServer.java @@ -1218,7 +1218,7 @@ public class CassandraServer implements Cassandra.Iface } } - private void addRange(CFMetaData cfm, LegacyLayout.LegacyDeletionInfo delInfo, Slice.Bound start, Slice.Bound end, long timestamp, int nowInSec) + private void addRange(CFMetaData cfm, LegacyLayout.LegacyDeletionInfo delInfo, ClusteringBound start, ClusteringBound end, long timestamp, int nowInSec) { delInfo.add(cfm, new RangeTombstone(Slice.make(start, end), new DeletionTime(timestamp, nowInSec))); } @@ -1233,7 +1233,7 @@ public class CassandraServer implements Cassandra.Iface try { if (del.super_column == null && cfm.isSuper()) - addRange(cfm, delInfo, Slice.Bound.inclusiveStartOf(c), Slice.Bound.inclusiveEndOf(c), del.timestamp, nowInSec); + addRange(cfm, delInfo, ClusteringBound.inclusiveStartOf(c), ClusteringBound.inclusiveEndOf(c), del.timestamp, nowInSec); else if (del.super_column != null) cells.add(toLegacyDeletion(cfm, del.super_column, c, del.timestamp, nowInSec)); else @@ -1267,7 +1267,7 @@ public class CassandraServer implements Cassandra.Iface else { if (del.super_column != null) - addRange(cfm, delInfo, Slice.Bound.inclusiveStartOf(del.super_column), Slice.Bound.inclusiveEndOf(del.super_column), del.timestamp, nowInSec); + addRange(cfm, delInfo, ClusteringBound.inclusiveStartOf(del.super_column), ClusteringBound.inclusiveEndOf(del.super_column), del.timestamp, nowInSec); else delInfo.add(new DeletionTime(del.timestamp, nowInSec)); } @@ -2437,8 +2437,8 @@ public class CassandraServer implements Cassandra.Iface for (int i = 0 ; i < request.getColumn_slices().size() ; i++) { fixOptionalSliceParameters(request.getColumn_slices().get(i)); - Slice.Bound start = LegacyLayout.decodeBound(metadata, request.getColumn_slices().get(i).start, true).bound; - Slice.Bound finish = LegacyLayout.decodeBound(metadata, request.getColumn_slices().get(i).finish, false).bound; + ClusteringBound start = LegacyLayout.decodeBound(metadata, request.getColumn_slices().get(i).start, true).bound; + ClusteringBound finish = LegacyLayout.decodeBound(metadata, request.getColumn_slices().get(i).finish, false).bound; int compare = metadata.comparator.compare(start, finish); if (!request.reversed && compare > 0) diff --git a/src/java/org/apache/cassandra/tools/JsonTransformer.java b/src/java/org/apache/cassandra/tools/JsonTransformer.java index 93bb6866be..5fc4fb97e1 100644 --- a/src/java/org/apache/cassandra/tools/JsonTransformer.java +++ b/src/java/org/apache/cassandra/tools/JsonTransformer.java @@ -9,11 +9,7 @@ import java.util.stream.Stream; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.db.ClusteringPrefix; -import org.apache.cassandra.db.DecoratedKey; -import org.apache.cassandra.db.DeletionTime; -import org.apache.cassandra.db.LivenessInfo; -import org.apache.cassandra.db.RangeTombstone; +import org.apache.cassandra.db.*; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.CollectionType; import org.apache.cassandra.db.marshal.CompositeType; @@ -305,7 +301,7 @@ public final class JsonTransformer } } - private void serializeBound(RangeTombstone.Bound bound, DeletionTime deletionTime) throws IOException + private void serializeBound(ClusteringBound bound, DeletionTime deletionTime) throws IOException { json.writeFieldName(bound.isStart() ? "start" : "end"); json.writeStartObject(); diff --git a/test/unit/org/apache/cassandra/cql3/TombstonesWithIndexedSSTableTest.java b/test/unit/org/apache/cassandra/cql3/TombstonesWithIndexedSSTableTest.java index 41a7d91f6b..787c309b4e 100644 --- a/test/unit/org/apache/cassandra/cql3/TombstonesWithIndexedSSTableTest.java +++ b/test/unit/org/apache/cassandra/cql3/TombstonesWithIndexedSSTableTest.java @@ -108,7 +108,6 @@ public class TombstonesWithIndexedSSTableTest extends CQLTester assertRowCount(execute("SELECT DISTINCT s FROM %s WHERE k = ? ORDER BY t DESC", 0), 1); } - // Creates a random string public static String makeRandomString(int length) { Random random = new Random(); diff --git a/test/unit/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictionsTest.java b/test/unit/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictionsTest.java index 5c816da7a0..f78967d2c9 100644 --- a/test/unit/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictionsTest.java +++ b/test/unit/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictionsTest.java @@ -48,7 +48,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertEmptyStart(get(bounds, 0)); @@ -71,7 +71,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(eq); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), true, clustering_0); @@ -94,7 +94,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(eq); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), true, clustering_0); @@ -120,7 +120,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(in); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(3, bounds.size()); assertStartBound(get(bounds, 0), true, value1); assertStartBound(get(bounds, 1), true, value2); @@ -148,7 +148,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), false, value1); @@ -234,7 +234,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertEmptyStart(get(bounds, 0)); @@ -321,7 +321,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(eq).mergeWith(in); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(3, bounds.size()); assertStartBound(get(bounds, 0), true, value1, value1); assertStartBound(get(bounds, 1), true, value1, value2); @@ -352,7 +352,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(eq).mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), false, value3, value1); @@ -437,7 +437,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(eq); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), true, value1, value2); @@ -461,7 +461,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(in); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(2, bounds.size()); assertStartBound(get(bounds, 0), true, value1, value2); assertStartBound(get(bounds, 1), true, value2, value3); @@ -488,7 +488,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), false, value1); @@ -575,7 +575,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertEmptyStart(get(bounds, 0)); @@ -662,7 +662,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), false, value1, value2); @@ -754,7 +754,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertEmptyStart(get(bounds, 0)); @@ -848,7 +848,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(2, bounds.size()); assertEmptyStart(get(bounds, 0)); assertStartBound(get(bounds, 1), false, value1, value2); @@ -971,7 +971,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(2, bounds.size()); assertStartBound(get(bounds, 0), true, value1); assertStartBound(get(bounds, 1), false, value1); @@ -1080,7 +1080,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(2, bounds.size()); assertStartBound(get(bounds, 0), true, value1, value2); assertStartBound(get(bounds, 1), false, value1, value2); @@ -1240,7 +1240,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(slice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(4, bounds.size()); assertStartBound(get(bounds, 0), true, value1); assertStartBound(get(bounds, 1), true, value1, value2, value3); @@ -1414,7 +1414,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(singleEq).mergeWith(multiEq); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), true, value1, value2, value3); @@ -1487,7 +1487,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(singleEq).mergeWith(multiIN); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(2, bounds.size()); assertStartBound(get(bounds, 0), true, value1, value2, value3); assertStartBound(get(bounds, 1), true, value1, value4, value5); @@ -1550,7 +1550,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(singleEq).mergeWith(multiSlice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), false, value1, value2, value3); @@ -1608,7 +1608,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(multiEq).mergeWith(singleSlice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), false, value1, value2, value3); @@ -1634,7 +1634,7 @@ public class ClusteringColumnRestrictionsTest ClusteringColumnRestrictions restrictions = new ClusteringColumnRestrictions(cfMetaData); restrictions = restrictions.mergeWith(multiEq).mergeWith(multiSlice); - SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); + SortedSet bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT); assertEquals(1, bounds.size()); assertStartBound(get(bounds, 0), false, value1, value2, value3, value4); @@ -1678,9 +1678,9 @@ public class ClusteringColumnRestrictionsTest * * @param bound the bound to check */ - private static void assertEmptyStart(Slice.Bound bound) + private static void assertEmptyStart(ClusteringBound bound) { - assertEquals(Slice.Bound.BOTTOM, bound); + assertEquals(ClusteringBound.BOTTOM, bound); } /** @@ -1688,36 +1688,36 @@ public class ClusteringColumnRestrictionsTest * * @param bound the bound to check */ - private static void assertEmptyEnd(Slice.Bound bound) + private static void assertEmptyEnd(ClusteringBound bound) { - assertEquals(Slice.Bound.TOP, bound); + assertEquals(ClusteringBound.TOP, bound); } /** - * Asserts that the specified Slice.Bound is a start with the specified elements. + * Asserts that the specified ClusteringBound is a start with the specified elements. * * @param bound the bound to check * @param isInclusive if the bound is expected to be inclusive * @param elements the expected elements of the clustering */ - private static void assertStartBound(Slice.Bound bound, boolean isInclusive, ByteBuffer... elements) + private static void assertStartBound(ClusteringBound bound, boolean isInclusive, ByteBuffer... elements) { assertBound(bound, true, isInclusive, elements); } /** - * Asserts that the specified Slice.Bound is a end with the specified elements. + * Asserts that the specified ClusteringBound is a end with the specified elements. * * @param bound the bound to check * @param isInclusive if the bound is expected to be inclusive * @param elements the expected elements of the clustering */ - private static void assertEndBound(Slice.Bound bound, boolean isInclusive, ByteBuffer... elements) + private static void assertEndBound(ClusteringBound bound, boolean isInclusive, ByteBuffer... elements) { assertBound(bound, false, isInclusive, elements); } - private static void assertBound(Slice.Bound bound, boolean isStart, boolean isInclusive, ByteBuffer... elements) + private static void assertBound(ClusteringBound bound, boolean isStart, boolean isInclusive, ByteBuffer... elements) { assertEquals("the bound size is not the expected one:", elements.length, bound.size()); assertEquals("the bound should be a " + (isStart ? "start" : "end") + " but is a " + (bound.isStart() ? "start" : "end"), isStart, bound.isStart()); diff --git a/test/unit/org/apache/cassandra/db/KeyspaceTest.java b/test/unit/org/apache/cassandra/db/KeyspaceTest.java index b0820ecd70..5036749896 100644 --- a/test/unit/org/apache/cassandra/db/KeyspaceTest.java +++ b/test/unit/org/apache/cassandra/db/KeyspaceTest.java @@ -251,12 +251,12 @@ public class KeyspaceTest extends CQLTester private static ClusteringIndexSliceFilter slices(ColumnFamilyStore cfs, Integer sliceStart, Integer sliceEnd, boolean reversed) { - Slice.Bound startBound = sliceStart == null - ? Slice.Bound.BOTTOM - : Slice.Bound.create(ClusteringPrefix.Kind.INCL_START_BOUND, new ByteBuffer[]{ByteBufferUtil.bytes(sliceStart)}); - Slice.Bound endBound = sliceEnd == null - ? Slice.Bound.TOP - : Slice.Bound.create(ClusteringPrefix.Kind.INCL_END_BOUND, new ByteBuffer[]{ByteBufferUtil.bytes(sliceEnd)}); + ClusteringBound startBound = sliceStart == null + ? ClusteringBound.BOTTOM + : ClusteringBound.create(ClusteringPrefix.Kind.INCL_START_BOUND, new ByteBuffer[]{ByteBufferUtil.bytes(sliceStart)}); + ClusteringBound endBound = sliceEnd == null + ? ClusteringBound.TOP + : ClusteringBound.create(ClusteringPrefix.Kind.INCL_END_BOUND, new ByteBuffer[]{ByteBufferUtil.bytes(sliceEnd)}); Slices slices = Slices.with(cfs.getComparator(), Slice.make(startBound, endBound)); return new ClusteringIndexSliceFilter(slices, reversed); } diff --git a/test/unit/org/apache/cassandra/db/RangeTombstoneListTest.java b/test/unit/org/apache/cassandra/db/RangeTombstoneListTest.java index 1e637b3edf..d3dc835875 100644 --- a/test/unit/org/apache/cassandra/db/RangeTombstoneListTest.java +++ b/test/unit/org/apache/cassandra/db/RangeTombstoneListTest.java @@ -620,12 +620,12 @@ public class RangeTombstoneListTest private static RangeTombstone rt(int start, boolean startInclusive, int end, boolean endInclusive, long tstamp) { - return new RangeTombstone(Slice.make(Slice.Bound.create(cmp, true, startInclusive, start), Slice.Bound.create(cmp, false, endInclusive, end)), new DeletionTime(tstamp, 0)); + return new RangeTombstone(Slice.make(ClusteringBound.create(cmp, true, startInclusive, start), ClusteringBound.create(cmp, false, endInclusive, end)), new DeletionTime(tstamp, 0)); } private static RangeTombstone rt(int start, int end, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.inclusiveStartOf(bb(start)), Slice.Bound.inclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.inclusiveStartOf(bb(start)), ClusteringBound.inclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); } private static RangeTombstone rtei(int start, int end, long tstamp) @@ -635,7 +635,7 @@ public class RangeTombstoneListTest private static RangeTombstone rtei(int start, int end, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.exclusiveStartOf(bb(start)), Slice.Bound.inclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.exclusiveStartOf(bb(start)), ClusteringBound.inclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); } private static RangeTombstone rtie(int start, int end, long tstamp) @@ -645,26 +645,26 @@ public class RangeTombstoneListTest private static RangeTombstone rtie(int start, int end, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.inclusiveStartOf(bb(start)), Slice.Bound.exclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.inclusiveStartOf(bb(start)), ClusteringBound.exclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); } private static RangeTombstone atLeast(int start, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.inclusiveStartOf(bb(start)), Slice.Bound.TOP), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.inclusiveStartOf(bb(start)), ClusteringBound.TOP), new DeletionTime(tstamp, delTime)); } private static RangeTombstone atMost(int end, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.BOTTOM, Slice.Bound.inclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.BOTTOM, ClusteringBound.inclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); } private static RangeTombstone lessThan(int end, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.BOTTOM, Slice.Bound.exclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.BOTTOM, ClusteringBound.exclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); } private static RangeTombstone greaterThan(int start, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.exclusiveStartOf(bb(start)), Slice.Bound.TOP), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.exclusiveStartOf(bb(start)), ClusteringBound.TOP), new DeletionTime(tstamp, delTime)); } } diff --git a/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java b/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java index 4be46ff1cf..91205460e4 100644 --- a/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java +++ b/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java @@ -207,8 +207,8 @@ public class RangeTombstoneTest assertEquals(1, rt.size()); Slices.Builder sb = new Slices.Builder(cfs.getComparator()); - sb.add(Slice.Bound.create(cfs.getComparator(), true, true, 1), Slice.Bound.create(cfs.getComparator(), false, true, 10)); - sb.add(Slice.Bound.create(cfs.getComparator(), true, true, 16), Slice.Bound.create(cfs.getComparator(), false, true, 20)); + sb.add(ClusteringBound.create(cfs.getComparator(), true, true, 1), ClusteringBound.create(cfs.getComparator(), false, true, 10)); + sb.add(ClusteringBound.create(cfs.getComparator(), true, true, 16), ClusteringBound.create(cfs.getComparator(), false, true, 20)); partition = Util.getOnlyPartitionUnfiltered(SinglePartitionReadCommand.create(cfs.metadata, FBUtilities.nowInSeconds(), Util.dk(key), sb.build())); rt = rangeTombstones(partition); diff --git a/test/unit/org/apache/cassandra/db/RowTest.java b/test/unit/org/apache/cassandra/db/RowTest.java index 30a4f982bc..7294b3a190 100644 --- a/test/unit/org/apache/cassandra/db/RowTest.java +++ b/test/unit/org/apache/cassandra/db/RowTest.java @@ -108,12 +108,12 @@ public class RowTest while (merged.hasNext()) { RangeTombstoneBoundMarker openMarker = (RangeTombstoneBoundMarker)merged.next(); - Slice.Bound openBound = openMarker.clustering(); + ClusteringBound openBound = openMarker.clustering(); DeletionTime openDeletion = new DeletionTime(openMarker.deletionTime().markedForDeleteAt(), openMarker.deletionTime().localDeletionTime()); RangeTombstoneBoundMarker closeMarker = (RangeTombstoneBoundMarker)merged.next(); - Slice.Bound closeBound = closeMarker.clustering(); + ClusteringBound closeBound = closeMarker.clustering(); DeletionTime closeDeletion = new DeletionTime(closeMarker.deletionTime().markedForDeleteAt(), closeMarker.deletionTime().localDeletionTime()); @@ -185,16 +185,16 @@ public class RowTest assertEquals(Integer.valueOf(1), map.get(row)); } - private void assertRangeTombstoneMarkers(Slice.Bound start, Slice.Bound end, DeletionTime deletionTime, Object[] expected) + private void assertRangeTombstoneMarkers(ClusteringBound start, ClusteringBound end, DeletionTime deletionTime, Object[] expected) { AbstractType clusteringType = (AbstractType)cfm.comparator.subtype(0); assertEquals(1, start.size()); - assertEquals(start.kind(), Slice.Bound.Kind.INCL_START_BOUND); + assertEquals(start.kind(), ClusteringPrefix.Kind.INCL_START_BOUND); assertEquals(expected[0], clusteringType.getString(start.get(0))); assertEquals(1, end.size()); - assertEquals(end.kind(), Slice.Bound.Kind.INCL_END_BOUND); + assertEquals(end.kind(), ClusteringPrefix.Kind.INCL_END_BOUND); assertEquals(expected[1], clusteringType.getString(end.get(0))); assertEquals(expected[2], deletionTime.markedForDeleteAt()); diff --git a/test/unit/org/apache/cassandra/db/SinglePartitionSliceCommandTest.java b/test/unit/org/apache/cassandra/db/SinglePartitionSliceCommandTest.java index 1e4f6960a8..8de0c75c8a 100644 --- a/test/unit/org/apache/cassandra/db/SinglePartitionSliceCommandTest.java +++ b/test/unit/org/apache/cassandra/db/SinglePartitionSliceCommandTest.java @@ -94,7 +94,7 @@ public class SinglePartitionSliceCommandTest ColumnFilter columnFilter = ColumnFilter.selection(PartitionColumns.of(v)); ByteBuffer zero = ByteBufferUtil.bytes(0); - Slices slices = Slices.with(cfm.comparator, Slice.make(Slice.Bound.inclusiveStartOf(zero), Slice.Bound.inclusiveEndOf(zero))); + Slices slices = Slices.with(cfm.comparator, Slice.make(ClusteringBound.inclusiveStartOf(zero), ClusteringBound.inclusiveEndOf(zero))); ClusteringIndexSliceFilter sliceFilter = new ClusteringIndexSliceFilter(slices, false); ReadCommand cmd = new SinglePartitionReadCommand(false, MessagingService.VERSION_30, true, cfm, FBUtilities.nowInSeconds(), diff --git a/test/unit/org/apache/cassandra/db/filter/SliceTest.java b/test/unit/org/apache/cassandra/db/filter/SliceTest.java index 2f07a240c3..b0705cebb5 100644 --- a/test/unit/org/apache/cassandra/db/filter/SliceTest.java +++ b/test/unit/org/apache/cassandra/db/filter/SliceTest.java @@ -367,14 +367,14 @@ public class SliceTest assertSlicesNormalization(cc, slices(s(-1, 2), s(-1, 3), s(5, 9)), slices(s(-1, 3), s(5, 9))); } - private static Slice.Bound makeBound(ClusteringPrefix.Kind kind, Integer... components) + private static ClusteringBound makeBound(ClusteringPrefix.Kind kind, Integer... components) { ByteBuffer[] values = new ByteBuffer[components.length]; for (int i = 0; i < components.length; i++) { values[i] = ByteBufferUtil.bytes(components[i]); } - return Slice.Bound.create(kind, values); + return ClusteringBound.create(kind, values); } private static List columnNames(Integer ... components) diff --git a/test/unit/org/apache/cassandra/db/partition/PartitionImplementationTest.java b/test/unit/org/apache/cassandra/db/partition/PartitionImplementationTest.java index 6cbab7ac65..90d6310237 100644 --- a/test/unit/org/apache/cassandra/db/partition/PartitionImplementationTest.java +++ b/test/unit/org/apache/cassandra/db/partition/PartitionImplementationTest.java @@ -39,7 +39,6 @@ import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; import org.apache.cassandra.cql3.ColumnIdentifier; import org.apache.cassandra.db.*; -import org.apache.cassandra.db.Slice.Bound; import org.apache.cassandra.db.filter.ColumnFilter; import org.apache.cassandra.db.marshal.AsciiType; import org.apache.cassandra.db.partitions.AbstractBTreePartition; @@ -355,7 +354,7 @@ public class PartitionImplementationTest Clustering start = clustering(pos); pos += sz; Clustering end = clustering(pos); - Slice slice = Slice.make(skip == 0 ? Bound.exclusiveStartOf(start) : Bound.inclusiveStartOf(start), Bound.inclusiveEndOf(end)); + Slice slice = Slice.make(skip == 0 ? ClusteringBound.exclusiveStartOf(start) : ClusteringBound.inclusiveStartOf(start), ClusteringBound.inclusiveEndOf(end)); builder.add(slice); } return builder.build(); diff --git a/test/unit/org/apache/cassandra/db/rows/RowAndDeletionMergeIteratorTest.java b/test/unit/org/apache/cassandra/db/rows/RowAndDeletionMergeIteratorTest.java index e8ac339311..a3289c2888 100644 --- a/test/unit/org/apache/cassandra/db/rows/RowAndDeletionMergeIteratorTest.java +++ b/test/unit/org/apache/cassandra/db/rows/RowAndDeletionMergeIteratorTest.java @@ -8,8 +8,6 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.apache.cassandra.db.Slice.Bound; -import org.apache.cassandra.db.ClusteringPrefix; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.db.*; import org.apache.cassandra.db.filter.ColumnFilter; @@ -21,9 +19,6 @@ import org.apache.cassandra.db.marshal.Int32Type; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.Util; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.db.ColumnFamilyStore; -import org.apache.cassandra.db.DecoratedKey; -import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.db.marshal.AsciiType; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.schema.KeyspaceParams; @@ -110,7 +105,7 @@ public class RowAndDeletionMergeIteratorTest assertRtMarker(iterator.next(), ClusteringPrefix.Kind.INCL_START_BOUND, 4); assertTrue(iterator.hasNext()); - assertRtMarker(iterator.next(), Bound.TOP); + assertRtMarker(iterator.next(), ClusteringBound.TOP); assertFalse(iterator.hasNext()); } @@ -128,7 +123,7 @@ public class RowAndDeletionMergeIteratorTest UnfilteredRowIterator iterator = createMergeIterator(rowIterator, rangeTombstoneIterator, false); assertTrue(iterator.hasNext()); - assertRtMarker(iterator.next(), Bound.BOTTOM); + assertRtMarker(iterator.next(), ClusteringBound.BOTTOM); assertTrue(iterator.hasNext()); assertRtMarker(iterator.next(), ClusteringPrefix.Kind.INCL_END_BOUND, 0); @@ -173,7 +168,7 @@ public class RowAndDeletionMergeIteratorTest assertRtMarker(iterator.next(), ClusteringPrefix.Kind.EXCL_START_BOUND, 2); assertTrue(iterator.hasNext()); - assertRtMarker(iterator.next(), Bound.TOP); + assertRtMarker(iterator.next(), ClusteringBound.TOP); assertFalse(iterator.hasNext()); } @@ -192,7 +187,7 @@ public class RowAndDeletionMergeIteratorTest UnfilteredRowIterator iterator = createMergeIterator(rowIterator, rangeTombstoneIterator, false); assertTrue(iterator.hasNext()); - assertRtMarker(iterator.next(), Bound.BOTTOM); + assertRtMarker(iterator.next(), ClusteringBound.BOTTOM); assertTrue(iterator.hasNext()); assertRtMarker(iterator.next(), ClusteringPrefix.Kind.INCL_END_BOUND, 0); @@ -207,7 +202,7 @@ public class RowAndDeletionMergeIteratorTest assertRtMarker(iterator.next(), ClusteringPrefix.Kind.EXCL_START_BOUND, 2); assertTrue(iterator.hasNext()); - assertRtMarker(iterator.next(), Bound.TOP); + assertRtMarker(iterator.next(), ClusteringBound.TOP); assertFalse(iterator.hasNext()); } @@ -233,13 +228,13 @@ public class RowAndDeletionMergeIteratorTest UnfilteredRowIterator iterator = createMergeIterator(rowIterator, rangeTombstoneIterator, false); assertTrue(iterator.hasNext()); - assertRtMarker(iterator.next(), Bound.BOTTOM); + assertRtMarker(iterator.next(), ClusteringBound.BOTTOM); assertTrue(iterator.hasNext()); assertRtMarker(iterator.next(), ClusteringPrefix.Kind.INCL_END_EXCL_START_BOUNDARY, 2); assertTrue(iterator.hasNext()); - assertRtMarker(iterator.next(), Bound.TOP); + assertRtMarker(iterator.next(), ClusteringBound.TOP); assertFalse(iterator.hasNext()); } @@ -258,13 +253,13 @@ public class RowAndDeletionMergeIteratorTest UnfilteredRowIterator iterator = createMergeIterator(rowIterator, rangeTombstoneIterator, false); assertTrue(iterator.hasNext()); - assertRtMarker(iterator.next(), Bound.BOTTOM); + assertRtMarker(iterator.next(), ClusteringBound.BOTTOM); assertTrue(iterator.hasNext()); assertRtMarker(iterator.next(), ClusteringPrefix.Kind.EXCL_END_INCL_START_BOUNDARY, 2); assertTrue(iterator.hasNext()); - assertRtMarker(iterator.next(), Bound.TOP); + assertRtMarker(iterator.next(), ClusteringBound.TOP); assertFalse(iterator.hasNext()); } @@ -279,7 +274,7 @@ public class RowAndDeletionMergeIteratorTest UnfilteredRowIterator iterator = createMergeIterator(rowIterator, rangeTombstoneIterator, false); assertTrue(iterator.hasNext()); - assertRtMarker(iterator.next(), Bound.BOTTOM); + assertRtMarker(iterator.next(), ClusteringBound.BOTTOM); assertTrue(iterator.hasNext()); assertRow(iterator.next(), 0); @@ -325,7 +320,7 @@ public class RowAndDeletionMergeIteratorTest } - private void assertRtMarker(Unfiltered unfiltered, Bound bound) + private void assertRtMarker(Unfiltered unfiltered, ClusteringBoundOrBoundary bound) { assertEquals(Unfiltered.Kind.RANGE_TOMBSTONE_MARKER, unfiltered.kind()); assertEquals(bound, unfiltered.clustering()); @@ -390,28 +385,28 @@ public class RowAndDeletionMergeIteratorTest private static RangeTombstone atLeast(int start, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.inclusiveStartOf(bb(start)), Slice.Bound.TOP), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.inclusiveStartOf(bb(start)), ClusteringBound.TOP), new DeletionTime(tstamp, delTime)); } private static RangeTombstone atMost(int end, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.BOTTOM, Slice.Bound.inclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.BOTTOM, ClusteringBound.inclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); } private static RangeTombstone lessThan(int end, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.BOTTOM, Slice.Bound.exclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.BOTTOM, ClusteringBound.exclusiveEndOf(bb(end))), new DeletionTime(tstamp, delTime)); } private static RangeTombstone greaterThan(int start, long tstamp, int delTime) { - return new RangeTombstone(Slice.make(Slice.Bound.exclusiveStartOf(bb(start)), Slice.Bound.TOP), new DeletionTime(tstamp, delTime)); + return new RangeTombstone(Slice.make(ClusteringBound.exclusiveStartOf(bb(start)), ClusteringBound.TOP), new DeletionTime(tstamp, delTime)); } private static RangeTombstone rt(int start, boolean startInclusive, int end, boolean endInclusive, long tstamp, int delTime) { - Slice.Bound startBound = startInclusive ? Slice.Bound.inclusiveStartOf(bb(start)) : Slice.Bound.exclusiveStartOf(bb(start)); - Slice.Bound endBound = endInclusive ? Slice.Bound.inclusiveEndOf(bb(end)) : Slice.Bound.exclusiveEndOf(bb(end)); + ClusteringBound startBound = startInclusive ? ClusteringBound.inclusiveStartOf(bb(start)) : ClusteringBound.exclusiveStartOf(bb(start)); + ClusteringBound endBound = endInclusive ? ClusteringBound.inclusiveEndOf(bb(end)) : ClusteringBound.exclusiveEndOf(bb(end)); return new RangeTombstone(Slice.make(startBound, endBound), new DeletionTime(tstamp, delTime)); } diff --git a/test/unit/org/apache/cassandra/db/rows/UnfilteredRowIteratorsMergeTest.java b/test/unit/org/apache/cassandra/db/rows/UnfilteredRowIteratorsMergeTest.java index 0c47cbbdec..0eeb3790fd 100644 --- a/test/unit/org/apache/cassandra/db/rows/UnfilteredRowIteratorsMergeTest.java +++ b/test/unit/org/apache/cassandra/db/rows/UnfilteredRowIteratorsMergeTest.java @@ -33,7 +33,6 @@ import org.junit.Test; import org.apache.cassandra.Util; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.db.*; -import org.apache.cassandra.db.Slice.Bound; import org.apache.cassandra.db.marshal.AsciiType; import org.apache.cassandra.db.marshal.Int32Type; import org.apache.cassandra.db.rows.Unfiltered.Kind; @@ -230,9 +229,12 @@ public class UnfilteredRowIteratorsMergeTest if (prev != null && curr != null && prev.isClose(false) && curr.isOpen(false) && prev.clustering().invert().equals(curr.clustering())) { // Join. Prefer not to use merger to check its correctness. - RangeTombstone.Bound b = prev.clustering(); - b = b.withNewKind(b.isInclusive() ? RangeTombstone.Bound.Kind.INCL_END_EXCL_START_BOUNDARY : RangeTombstone.Bound.Kind.EXCL_END_INCL_START_BOUNDARY); - prev = new RangeTombstoneBoundaryMarker(b, prev.closeDeletionTime(false), curr.openDeletionTime(false)); + ClusteringBound b = ((RangeTombstoneBoundMarker) prev).clustering(); + ClusteringBoundary boundary = ClusteringBoundary.create(b.isInclusive() + ? ClusteringPrefix.Kind.INCL_END_EXCL_START_BOUNDARY + : ClusteringPrefix.Kind.EXCL_END_INCL_START_BOUNDARY, + b.getRawValues()); + prev = new RangeTombstoneBoundaryMarker(boundary, prev.closeDeletionTime(false), curr.openDeletionTime(false)); currUnfiltered = prev; --di; } @@ -357,9 +359,9 @@ public class UnfilteredRowIteratorsMergeTest return def; } - private static Bound boundFor(int pos, boolean start, boolean inclusive) + private static ClusteringBound boundFor(int pos, boolean start, boolean inclusive) { - return Bound.create(Bound.boundKind(start, inclusive), new ByteBuffer[] {Int32Type.instance.decompose(pos)}); + return ClusteringBound.create(ClusteringBound.boundKind(start, inclusive), new ByteBuffer[] {Int32Type.instance.decompose(pos)}); } private static Clustering clusteringFor(int i) @@ -485,8 +487,8 @@ public class UnfilteredRowIteratorsMergeTest private RangeTombstoneMarker marker(int pos, int delTime, boolean isStart, boolean inclusive) { - return new RangeTombstoneBoundMarker(Bound.create(Bound.boundKind(isStart, inclusive), - new ByteBuffer[] {clusteringFor(pos).get(0)}), + return new RangeTombstoneBoundMarker(ClusteringBound.create(ClusteringBound.boundKind(isStart, inclusive), + new ByteBuffer[] {clusteringFor(pos).get(0)}), new DeletionTime(delTime, delTime)); } }