blob: cce85990906c3f36b065dcf5bd62db678af24633 [file] [log] [blame]
/*
* 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.rows;
import java.util.Arrays;
import java.util.Iterator;
import org.junit.Test;
import junit.framework.Assert;
import org.apache.cassandra.Util;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.BufferDecoratedKey;
import org.apache.cassandra.db.DecoratedKey;
import org.apache.cassandra.db.DeletionTime;
import org.apache.cassandra.db.EmptyIterators;
import org.apache.cassandra.db.PartitionColumns;
import org.apache.cassandra.db.filter.DataLimits;
import org.apache.cassandra.db.marshal.Int32Type;
import org.apache.cassandra.dht.Murmur3Partitioner;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.FBUtilities;
public class UnfilteredRowIteratorsTest
{
static final CFMetaData metadata;
static final ColumnDefinition v1Metadata;
static final ColumnDefinition v2Metadata;
static
{
// Required because of metadata creation, assertion is thrown otherwise
DatabaseDescriptor.daemonInitialization();
metadata = CFMetaData.Builder.create("", "")
.addPartitionKey("pk", Int32Type.instance)
.addClusteringColumn("ck", Int32Type.instance)
.addRegularColumn("v1", Int32Type.instance)
.addRegularColumn("v2", Int32Type.instance)
.build();
v1Metadata = metadata.partitionColumns().columns(false).getSimple(0);
v2Metadata = metadata.partitionColumns().columns(false).getSimple(1);
}
@Test
public void concatTest()
{
UnfilteredRowIterator iter1, iter2, iter3, concat;
// simple concatenation
iter1 = rows(metadata.partitionColumns(), 1,
row(1, cell(v1Metadata, 1), cell(v2Metadata, 1)),
row(2, cell(v1Metadata, 2), cell(v2Metadata, 2)));
iter2 = rows(metadata.partitionColumns(), 1,
row(3, cell(v1Metadata, 3), cell(v2Metadata, 3)),
row(4, cell(v1Metadata, 4), cell(v2Metadata, 4)));
concat = UnfilteredRowIterators.concat(iter1, iter2);
Assert.assertEquals(concat.columns(), metadata.partitionColumns());
assertRows(concat,
row(1, cell(v1Metadata, 1), cell(v2Metadata, 1)),
row(2, cell(v1Metadata, 2), cell(v2Metadata, 2)),
row(3, cell(v1Metadata, 3), cell(v2Metadata, 3)),
row(4, cell(v1Metadata, 4), cell(v2Metadata, 4)));
// concat with RHS empty iterator
iter1 = rows(metadata.partitionColumns(), 1,
row(1, cell(v1Metadata, 1), cell(v2Metadata, 1)),
row(2, cell(v1Metadata, 2), cell(v2Metadata, 2)));
Assert.assertEquals(concat.columns(), metadata.partitionColumns());
assertRows(UnfilteredRowIterators.concat(iter1, EmptyIterators.unfilteredRow(metadata, dk(1), false, Rows.EMPTY_STATIC_ROW, DeletionTime.LIVE)),
row(1, cell(v1Metadata, 1), cell(v2Metadata, 1)),
row(2, cell(v1Metadata, 2), cell(v2Metadata, 2)));
// concat with LHS empty iterator
iter1 = rows(metadata.partitionColumns(), 1,
row(1, cell(v1Metadata, 1), cell(v2Metadata, 1)),
row(2, cell(v1Metadata, 2), cell(v2Metadata, 2)));
Assert.assertEquals(concat.columns(), metadata.partitionColumns());
assertRows(UnfilteredRowIterators.concat(EmptyIterators.unfilteredRow(metadata, dk(1), false, Rows.EMPTY_STATIC_ROW, DeletionTime.LIVE), iter1),
row(1, cell(v1Metadata, 1), cell(v2Metadata, 1)),
row(2, cell(v1Metadata, 2), cell(v2Metadata, 2)));
// concat with different columns
iter1 = rows(metadata.partitionColumns().without(v1Metadata), 1,
row(1, cell(v2Metadata, 1)), row(2, cell(v2Metadata, 2)));
iter2 = rows(metadata.partitionColumns().without(v2Metadata), 1,
row(3, cell(v1Metadata, 3)), row(4, cell(v1Metadata, 4)));
concat = UnfilteredRowIterators.concat(iter1, iter2);
Assert.assertEquals(concat.columns(), PartitionColumns.of(v1Metadata).mergeTo(PartitionColumns.of(v2Metadata)));
assertRows(concat,
row(1, cell(v2Metadata, 1)), row(2, cell(v2Metadata, 2)),
row(3, cell(v1Metadata, 3)), row(4, cell(v1Metadata, 4)));
// concat with CQL limits
iter1 = rows(metadata.partitionColumns(), 1,
row(1, cell(v1Metadata, 1), cell(v2Metadata, 1)),
row(2, cell(v1Metadata, 2), cell(v2Metadata, 2)));
iter2 = rows(metadata.partitionColumns(), 1,
row(3, cell(v1Metadata, 3), cell(v2Metadata, 3)),
row(4, cell(v1Metadata, 4), cell(v2Metadata, 4)));
concat = UnfilteredRowIterators.concat(DataLimits.cqlLimits(1).filter(iter1, FBUtilities.nowInSeconds(), true),
DataLimits.cqlLimits(1).filter(iter2, FBUtilities.nowInSeconds(), true));
Assert.assertEquals(concat.columns(), metadata.partitionColumns());
assertRows(concat,
row(1, cell(v1Metadata, 1), cell(v2Metadata, 1)),
row(3, cell(v1Metadata, 3), cell(v2Metadata, 3)));
// concat concatenated iterators
iter1 = rows(metadata.partitionColumns(), 1,
row(1, cell(v1Metadata, 1), cell(v2Metadata, 1)),
row(2, cell(v1Metadata, 2), cell(v2Metadata, 2)));
iter2 = rows(metadata.partitionColumns(), 1,
row(3, cell(v1Metadata, 3), cell(v2Metadata, 3)),
row(4, cell(v1Metadata, 4), cell(v2Metadata, 4)));
concat = UnfilteredRowIterators.concat(DataLimits.cqlLimits(1).filter(iter1, FBUtilities.nowInSeconds(), true),
DataLimits.cqlLimits(1).filter(iter2, FBUtilities.nowInSeconds(), true));
iter3 = rows(metadata.partitionColumns(), 1,
row(4, cell(v1Metadata, 4), cell(v2Metadata, 4)),
row(5, cell(v1Metadata, 5), cell(v2Metadata, 5)));
concat = UnfilteredRowIterators.concat(concat, DataLimits.cqlLimits(1).filter(iter3, FBUtilities.nowInSeconds(), true));
Assert.assertEquals(concat.columns(), metadata.partitionColumns());
assertRows(concat,
row(1, cell(v1Metadata, 1), cell(v2Metadata, 1)),
row(3, cell(v1Metadata, 3), cell(v2Metadata, 3)),
row(4, cell(v1Metadata, 4), cell(v2Metadata, 4)));
}
public static void assertRows(UnfilteredRowIterator iterator, Row... rows)
{
Iterator<Row> rowsIterator = Arrays.asList(rows).iterator();
while (iterator.hasNext() && rowsIterator.hasNext())
Assert.assertEquals(iterator.next(), rowsIterator.next());
Assert.assertTrue(iterator.hasNext() == rowsIterator.hasNext());
}
public static DecoratedKey dk(int pk)
{
return new BufferDecoratedKey(new Murmur3Partitioner.LongToken(pk), ByteBufferUtil.bytes(pk));
}
public static UnfilteredRowIterator rows(PartitionColumns columns, int pk, Row... rows)
{
Iterator<Row> rowsIterator = Arrays.asList(rows).iterator();
return new AbstractUnfilteredRowIterator(metadata, dk(pk), DeletionTime.LIVE, columns, Rows.EMPTY_STATIC_ROW, false, EncodingStats.NO_STATS) {
protected Unfiltered computeNext()
{
return rowsIterator.hasNext() ? rowsIterator.next() : endOfData();
}
};
}
public Row row(int ck, Cell... columns)
{
BTreeRow.Builder builder = new BTreeRow.Builder(true);
builder.newRow(Util.clustering(metadata.comparator, ck));
for (Cell cell : columns)
builder.addCell(cell);
return builder.build();
}
public Cell cell(ColumnDefinition metadata, int v)
{
return new BufferCell(metadata,
1L, BufferCell.NO_TTL, BufferCell.NO_DELETION_TIME, ByteBufferUtil.bytes(v), null);
}
}