You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by br...@apache.org on 2014/04/02 21:57:40 UTC

[8/8] git commit: Merge branch 'cassandra-2.0' into cassandra-2.1

Merge branch 'cassandra-2.0' into cassandra-2.1

Conflicts:
	src/java/org/apache/cassandra/db/marshal/CompositeType.java
	test/unit/org/apache/cassandra/db/marshal/CompositeTypeTest.java


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

Branch: refs/heads/trunk
Commit: e34d1af963b85c46afc973221a296498eaba8264
Parents: 5ab1a34 f4f7417
Author: Tyler Hobbs <ty...@datastax.com>
Authored: Wed Apr 2 14:55:48 2014 -0500
Committer: Tyler Hobbs <ty...@datastax.com>
Committed: Wed Apr 2 14:55:48 2014 -0500

----------------------------------------------------------------------
 src/java/org/apache/cassandra/db/filter/ColumnSlice.java    | 9 ++++++---
 .../org/apache/cassandra/db/filter/ColumnSliceTest.java     | 4 ++++
 2 files changed, 10 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/e34d1af9/src/java/org/apache/cassandra/db/filter/ColumnSlice.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/filter/ColumnSlice.java
index 3838ee5,9eff12a..227297e
--- a/src/java/org/apache/cassandra/db/filter/ColumnSlice.java
+++ b/src/java/org/apache/cassandra/db/filter/ColumnSlice.java
@@@ -52,63 -47,20 +52,66 @@@ public class ColumnSlic
          this.finish = finish;
      }
  
 -    public boolean isAlwaysEmpty(AbstractType<?> comparator, boolean reversed)
 +    public boolean isAlwaysEmpty(CellNameType comparator, boolean reversed)
      {
 -        Comparator<ByteBuffer> orderedComparator = reversed ? comparator.reverseComparator : comparator;
 -        return (start.remaining() > 0 && finish.remaining() > 0 && orderedComparator.compare(start, finish) > 0);
 +        Comparator<Composite> orderedComparator = reversed ? comparator.reverseComparator() : comparator;
 +        return !start.isEmpty() && !finish.isEmpty() && orderedComparator.compare(start, finish) > 0;
      }
  
 -    public boolean includes(Comparator<ByteBuffer> cmp, ByteBuffer name)
 +    public boolean includes(Comparator<Composite> cmp, Composite name)
      {
 -        return cmp.compare(start, name) <= 0 && (finish.equals(ByteBufferUtil.EMPTY_BYTE_BUFFER) || cmp.compare(finish, name) >= 0);
 +        return cmp.compare(start, name) <= 0 && (finish.isEmpty() || cmp.compare(finish, name) >= 0);
      }
  
 -    public boolean isBefore(Comparator<ByteBuffer> cmp, ByteBuffer name)
 +    public boolean isBefore(Comparator<Composite> cmp, Composite name)
      {
 -        return !finish.equals(ByteBufferUtil.EMPTY_BYTE_BUFFER) && cmp.compare(finish, name) < 0;
 +        return !finish.isEmpty() && cmp.compare(finish, name) < 0;
 +    }
 +
 +    public boolean intersects(List<ByteBuffer> minCellNames, List<ByteBuffer> maxCellNames, CellNameType comparator, boolean reversed)
 +    {
 +        assert minCellNames.size() == maxCellNames.size();
 +
 +        Composite sStart = reversed ? finish : start;
 +        Composite sEnd = reversed ? start : finish;
 +
 +        if (compare(sStart, maxCellNames, comparator, true) > 0 || compare(sEnd, minCellNames, comparator, false) < 0)
 +            return false;
 +
 +        // We could safely return true here, but there's a minor optimization: if the first component is restricted
 +        // to a single value, we can check that the second component falls within the min/max for that component
 +        // (and repeat for all components).
-         for (int i = 0; i < Math.min(Math.min(sStart.size(), sEnd.size()), minCellNames.size()); i++)
++        for (int i = 0; i < minCellNames.size(); i++)
 +        {
 +            AbstractType<?> t = comparator.subtype(i);
++            ByteBuffer s = i < sStart.size() ? sStart.get(i) : ByteBufferUtil.EMPTY_BYTE_BUFFER;
++            ByteBuffer f = i < sEnd.size() ? sEnd.get(i) : ByteBufferUtil.EMPTY_BYTE_BUFFER;
++
 +            // we already know the first component falls within its min/max range (otherwise we wouldn't get here)
-             if (i > 0 && (t.compare(sEnd.get(i), minCellNames.get(i)) < 0 || t.compare(sStart.get(i), maxCellNames.get(i)) > 0))
++            if (i > 0 && (t.compare(f, minCellNames.get(i)) < 0 || t.compare(s, maxCellNames.get(i)) > 0))
 +                return false;
 +
 +            // if this component isn't equal in the start and finish, we don't need to check any more
-             if (t.compare(sStart.get(i), sEnd.get(i)) != 0)
++            if (i >= sStart.size() || i >= sEnd.size() || t.compare(s, f) != 0)
 +                break;
 +        }
 +
 +        return true;
 +    }
 +
 +    /** Helper method for intersects() */
 +    private int compare(Composite sliceBounds, List<ByteBuffer> sstableBounds, CellNameType comparator, boolean isSliceStart)
 +    {
 +        for (int i = 0; i < sstableBounds.size(); i++)
 +        {
 +            if (i >= sliceBounds.size())
 +                return isSliceStart ? -1 : 1;
 +
 +            int comparison = comparator.subtype(i).compare(sliceBounds.get(i), sstableBounds.get(i));
 +            if (comparison != 0)
 +                return comparison;
 +        }
 +        return 0;
      }
  
      @Override

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e34d1af9/test/unit/org/apache/cassandra/db/filter/ColumnSliceTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/db/filter/ColumnSliceTest.java
index 4718795,0000000..e2de0e6
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/db/filter/ColumnSliceTest.java
+++ b/test/unit/org/apache/cassandra/db/filter/ColumnSliceTest.java
@@@ -1,290 -1,0 +1,294 @@@
 +/*
 + * * Licensed to the Apache Software Foundation (ASF) under one
 + * * or more contributor license agreements.  See the NOTICE file
 + * * distributed with this work for additional information
 + * * regarding copyright ownership.  The ASF licenses this file
 + * * to you under the Apache License, Version 2.0 (the
 + * * "License"); you may not use this file except in compliance
 + * * with the License.  You may obtain a copy of the License at
 + * *
 + * *    http://www.apache.org/licenses/LICENSE-2.0
 + * *
 + * * Unless required by applicable law or agreed to in writing,
 + * * software distributed under the License is distributed on an
 + * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 + * * KIND, either express or implied.  See the License for the
 + * * specific language governing permissions and limitations
 + * * under the License.
 + * */
 +package org.apache.cassandra.db.filter;
 +
 +import org.apache.cassandra.db.composites.Composite;
 +import org.apache.cassandra.db.composites.CompoundDenseCellNameType;
 +import org.apache.cassandra.db.marshal.AbstractType;
 +import org.apache.cassandra.db.marshal.Int32Type;
 +import org.apache.cassandra.utils.ByteBufferUtil;
 +import org.junit.Test;
 +
 +import java.nio.ByteBuffer;
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertTrue;
 +
 +public class ColumnSliceTest
 +{
 +    @Test
 +    public void testIntersectsSingleSlice()
 +    {
 +        List<AbstractType<?>> types = new ArrayList<>();
 +        types.add(Int32Type.instance);
 +        types.add(Int32Type.instance);
 +        types.add(Int32Type.instance);
 +        CompoundDenseCellNameType nameType = new CompoundDenseCellNameType(types);
 +
 +        // filter falls entirely before sstable
 +        ColumnSlice slice = new ColumnSlice(composite(0, 0, 0), composite(1, 0, 0));
 +        assertFalse(slice.intersects(columnNames(2, 0, 0), columnNames(3, 0, 0), nameType, false));
 +
 +        // same case, but with empty start
 +        slice = new ColumnSlice(composite(), composite(1, 0, 0));
 +        assertFalse(slice.intersects(columnNames(2, 0, 0), columnNames(3, 0, 0), nameType, false));
 +
 +        // same case, but with missing components for start
 +        slice = new ColumnSlice(composite(0), composite(1, 0, 0));
 +        assertFalse(slice.intersects(columnNames(2, 0, 0), columnNames(3, 0, 0), nameType, false));
 +
 +        // same case, but with missing components for start and end
 +        slice = new ColumnSlice(composite(0), composite(1, 0));
 +        assertFalse(slice.intersects(columnNames(2, 0, 0), columnNames(3, 0, 0), nameType, false));
 +
 +
 +        // end of slice matches start of sstable for the first component, but not the second component
 +        slice = new ColumnSlice(composite(0, 0, 0), composite(1, 0, 0));
 +        assertFalse(slice.intersects(columnNames(1, 1, 0), columnNames(3, 0, 0), nameType, false));
 +
 +        // same case, but with missing components for start
 +        slice = new ColumnSlice(composite(0), composite(1, 0, 0));
 +        assertFalse(slice.intersects(columnNames(1, 1, 0), columnNames(3, 0, 0), nameType, false));
 +
 +        // same case, but with missing components for start and end
 +        slice = new ColumnSlice(composite(0), composite(1, 0));
 +        assertFalse(slice.intersects(columnNames(1, 1, 0), columnNames(3, 0, 0), nameType, false));
 +
 +        // first two components match, but not the last
 +        slice = new ColumnSlice(composite(0, 0, 0), composite(1, 1, 0));
 +        assertFalse(slice.intersects(columnNames(1, 1, 1), columnNames(3, 1, 1), nameType, false));
 +
 +        // all three components in slice end match the start of the sstable
 +        slice = new ColumnSlice(composite(0, 0, 0), composite(1, 1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 1, 1), columnNames(3, 1, 1), nameType, false));
 +
 +
 +        // filter falls entirely after sstable
 +        slice = new ColumnSlice(composite(4, 0, 0), composite(4, 0, 0));
 +        assertFalse(slice.intersects(columnNames(2, 0, 0), columnNames(3, 0, 0), nameType, false));
 +
 +        // same case, but with empty end
 +        slice = new ColumnSlice(composite(4, 0, 0), composite());
 +        assertFalse(slice.intersects(columnNames(2, 0, 0), columnNames(3, 0, 0), nameType, false));
 +
 +        // same case, but with missing components for end
 +        slice = new ColumnSlice(composite(4, 0, 0), composite(1));
 +        assertFalse(slice.intersects(columnNames(2, 0, 0), columnNames(3, 0, 0), nameType, false));
 +
 +        // same case, but with missing components for start and end
 +        slice = new ColumnSlice(composite(4, 0), composite(1));
 +        assertFalse(slice.intersects(columnNames(2, 0, 0), columnNames(3, 0, 0), nameType, false));
 +
 +
 +        // start of slice matches end of sstable for the first component, but not the second component
 +        slice = new ColumnSlice(composite(1, 1, 1), composite(2, 0, 0));
 +        assertFalse(slice.intersects(columnNames(0, 0, 0), columnNames(1, 0, 0), nameType, false));
 +
 +        // start of slice matches end of sstable for the first two components, but not the last component
 +        slice = new ColumnSlice(composite(1, 1, 1), composite(2, 0, 0));
 +        assertFalse(slice.intersects(columnNames(0, 0, 0), columnNames(1, 1, 0), nameType, false));
 +
 +        // all three components in the slice start match the end of the sstable
 +        slice = new ColumnSlice(composite(1, 1, 1), composite(2, 0, 0));
 +        assertTrue(slice.intersects(columnNames(0, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +
 +        // slice covers entire sstable (with no matching edges)
 +        slice = new ColumnSlice(composite(0, 0, 0), composite(2, 0, 0));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +        // same case, but with empty ends
 +        slice = new ColumnSlice(composite(), composite());
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +        // same case, but with missing components
 +        slice = new ColumnSlice(composite(0), composite(2, 0));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +        // slice covers entire sstable (with matching start)
 +        slice = new ColumnSlice(composite(1, 0, 0), composite(2, 0, 0));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +        // slice covers entire sstable (with matching end)
 +        slice = new ColumnSlice(composite(0, 0, 0), composite(1, 1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +        // slice covers entire sstable (with matching start and end)
 +        slice = new ColumnSlice(composite(1, 0, 0), composite(1, 1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +
 +        // slice falls entirely within sstable (with matching start)
 +        slice = new ColumnSlice(composite(1, 0, 0), composite(1, 1, 0));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +        // same case, but with a missing end component
 +        slice = new ColumnSlice(composite(1, 0, 0), composite(1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +        // slice falls entirely within sstable (with matching end)
 +        slice = new ColumnSlice(composite(1, 1, 0), composite(1, 1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +        // same case, but with a missing start component
 +        slice = new ColumnSlice(composite(1, 1), composite(1, 1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(1, 1, 1), nameType, false));
 +
 +
 +        // slice falls entirely within sstable
 +        slice = new ColumnSlice(composite(1, 1, 0), composite(1, 1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 2, 2), nameType, false));
 +
 +        // same case, but with a missing start component
 +        slice = new ColumnSlice(composite(1, 1), composite(1, 1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 2, 2), nameType, false));
 +
 +        // same case, but with a missing start and end components
 +        slice = new ColumnSlice(composite(1), composite(1, 2));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 2, 2), nameType, false));
 +
 +        // slice falls entirely within sstable (slice start and end are the same)
 +        slice = new ColumnSlice(composite(1, 1, 1), composite(1, 1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 2, 2), nameType, false));
 +
 +
 +        // slice starts within sstable, empty end
 +        slice = new ColumnSlice(composite(1, 1, 1), composite());
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +        // same case, but with missing end components
 +        slice = new ColumnSlice(composite(1, 1, 1), composite(3));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +        // slice starts within sstable (matching sstable start), empty end
 +        slice = new ColumnSlice(composite(1, 0, 0), composite());
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +        // same case, but with missing end components
 +        slice = new ColumnSlice(composite(1, 0, 0), composite(3));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +        // slice starts within sstable (matching sstable end), empty end
 +        slice = new ColumnSlice(composite(2, 0, 0), composite());
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +        // same case, but with missing end components
 +        slice = new ColumnSlice(composite(2, 0, 0), composite(3));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +
 +        // slice ends within sstable, empty end
 +        slice = new ColumnSlice(composite(), composite(1, 1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +        // same case, but with missing start components
 +        slice = new ColumnSlice(composite(0), composite(1, 1, 1));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +        // slice ends within sstable (matching sstable start), empty start
 +        slice = new ColumnSlice(composite(), composite(1, 0, 0));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +        // same case, but with missing start components
 +        slice = new ColumnSlice(composite(0), composite(1, 0, 0));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +        // slice ends within sstable (matching sstable end), empty start
 +        slice = new ColumnSlice(composite(), composite(2, 0, 0));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +        // same case, but with missing start components
 +        slice = new ColumnSlice(composite(0), composite(2, 0, 0));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 0, 0), nameType, false));
 +
 +
 +        // the slice technically falls within the sstable range, but since the first component is restricted to
 +        // a single value, we can check that the second component does not fall within its min/max
 +        slice = new ColumnSlice(composite(1, 2, 0), composite(1, 3, 0));
 +        assertFalse(slice.intersects(columnNames(1, 0, 0), columnNames(2, 1, 0), nameType, false));
 +
 +        // same case, but with a missing start component
 +        slice = new ColumnSlice(composite(1, 2), composite(1, 3, 0));
 +        assertFalse(slice.intersects(columnNames(1, 0, 0), columnNames(2, 1, 0), nameType, false));
 +
 +        // same case, but with a missing end component
 +        slice = new ColumnSlice(composite(1, 2, 0), composite(1, 3));
 +        assertFalse(slice.intersects(columnNames(1, 0, 0), columnNames(2, 1, 0), nameType, false));
 +
 +        // same case, but with a missing start and end components
 +        slice = new ColumnSlice(composite(1, 2), composite(1, 3));
 +        assertFalse(slice.intersects(columnNames(1, 0, 0), columnNames(2, 1, 0), nameType, false));
 +
++        // same case, but with missing start and end components and different lengths for start and end
++        slice = new ColumnSlice(composite(1, 2), composite(1));
++        assertFalse(slice.intersects(columnNames(1, 0, 0), columnNames(2, 1, 0), nameType, false));
++
 +
 +        // same as the previous set of tests, but the second component is equal in the slice start and end
 +        slice = new ColumnSlice(composite(1, 2, 0), composite(1, 2, 0));
 +        assertFalse(slice.intersects(columnNames(1, 0, 0), columnNames(2, 1, 0), nameType, false));
 +
 +        // same case, but with a missing start component
 +        slice = new ColumnSlice(composite(1, 2), composite(1, 2, 0));
 +        assertFalse(slice.intersects(columnNames(1, 0, 0), columnNames(2, 1, 0), nameType, false));
 +
 +        // same case, but with a missing end component
 +        slice = new ColumnSlice(composite(1, 2, 0), composite(1, 2));
 +        assertFalse(slice.intersects(columnNames(1, 0, 0), columnNames(2, 1, 0), nameType, false));
 +
 +        // same case, but with a missing start and end components
 +        slice = new ColumnSlice(composite(1, 2), composite(1, 2));
 +        assertFalse(slice.intersects(columnNames(1, 0, 0), columnNames(2, 1, 0), nameType, false));
 +
 +        // same as the previous tests, but it's the third component that doesn't fit in its range this time
 +        slice = new ColumnSlice(composite(1, 1, 2), composite(1, 1, 3));
 +        assertFalse(slice.intersects(columnNames(1, 1, 0), columnNames(2, 2, 1), nameType, false));
 +
 +
 +        // basic check on reversed slices
 +        slice = new ColumnSlice(composite(1, 0, 0), composite(0, 0, 0));
 +        assertFalse(slice.intersects(columnNames(2, 0, 0), columnNames(3, 0, 0), nameType, true));
 +
 +        slice = new ColumnSlice(composite(1, 0, 0), composite(0, 0, 0));
 +        assertFalse(slice.intersects(columnNames(1, 1, 0), columnNames(3, 0, 0), nameType, true));
 +
 +        slice = new ColumnSlice(composite(1, 1, 1), composite(1, 1, 0));
 +        assertTrue(slice.intersects(columnNames(1, 0, 0), columnNames(2, 2, 2), nameType, true));
 +    }
 +
 +    private static Composite composite(Integer ... components)
 +    {
 +        List<AbstractType<?>> types = new ArrayList<>();
 +        types.add(Int32Type.instance);
 +        types.add(Int32Type.instance);
 +        types.add(Int32Type.instance);
 +        CompoundDenseCellNameType nameType = new CompoundDenseCellNameType(types);
 +        return nameType.make(components);
 +    }
 +
 +    private static List<ByteBuffer> columnNames(Integer ... components)
 +    {
 +        List<ByteBuffer> names = new ArrayList<>(components.length);
 +        for (int component : components)
 +            names.add(ByteBufferUtil.bytes(component));
 +        return names;
 +    }
 +}