use of org.apache.cassandra.db.PartitionRangeReadCommand in project cassandra by apache.
the class ShortReadPartitionsProtection method makeAndExecuteFetchAdditionalPartitionReadCommand.
private UnfilteredPartitionIterator makeAndExecuteFetchAdditionalPartitionReadCommand(int toQuery) {
PartitionRangeReadCommand cmd = (PartitionRangeReadCommand) command;
DataLimits newLimits = cmd.limits().forShortReadRetry(toQuery);
AbstractBounds<PartitionPosition> bounds = cmd.dataRange().keyRange();
AbstractBounds<PartitionPosition> newBounds = bounds.inclusiveRight() ? new Range<>(lastPartitionKey, bounds.right) : new ExcludingBounds<>(lastPartitionKey, bounds.right);
DataRange newDataRange = cmd.dataRange().forSubRange(newBounds);
ReplicaPlan.ForRangeRead replicaPlan = ReplicaPlans.forSingleReplicaRead(Keyspace.open(command.metadata().keyspace), cmd.dataRange().keyRange(), source, 1);
return executeReadCommand(cmd.withUpdatedLimitsAndDataRange(newLimits, newDataRange), ReplicaPlan.shared(replicaPlan));
}
use of org.apache.cassandra.db.PartitionRangeReadCommand in project cassandra by apache.
the class RangeCommandsTest method command.
private static PartitionRangeReadCommand command(ColumnFamilyStore cfs, int limit, int commandEstimate, Integer indexEstimate) {
AbstractReadCommandBuilder.PartitionRangeBuilder commandBuilder = Util.cmd(cfs);
if (indexEstimate != null) {
commandBuilder.filterOn("v", Operator.EQ, 0);
MockedIndex.estimatedResultRows = indexEstimate;
}
PartitionRangeReadCommand command = (PartitionRangeReadCommand) commandBuilder.build();
return command.withUpdatedLimit(new MockedDataLimits(DataLimits.cqlLimits(limit), commandEstimate));
}
use of org.apache.cassandra.db.PartitionRangeReadCommand in project cassandra by apache.
the class RangeCommandsTest method tesConcurrencyFactor.
@Test
public void tesConcurrencyFactor() {
new TokenUpdater().withTokens("127.0.0.1", 1, 2).withTokens("127.0.0.2", 3, 4).update();
String table = createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
Keyspace keyspace = Keyspace.open(KEYSPACE);
ColumnFamilyStore cfs = keyspace.getColumnFamilyStore(table);
// verify that a low concurrency factor is not capped by the max concurrency factor
PartitionRangeReadCommand command = command(cfs, 50, 50);
try (RangeCommandIterator partitions = RangeCommands.rangeCommandIterator(command, ONE, nanoTime());
ReplicaPlanIterator ranges = new ReplicaPlanIterator(command.dataRange().keyRange(), keyspace, ONE)) {
assertEquals(2, partitions.concurrencyFactor());
assertEquals(MAX_CONCURRENCY_FACTOR, partitions.maxConcurrencyFactor());
assertEquals(5, ranges.size());
}
// verify that a high concurrency factor is capped by the max concurrency factor
command = command(cfs, 1000, 50);
try (RangeCommandIterator partitions = RangeCommands.rangeCommandIterator(command, ONE, nanoTime());
ReplicaPlanIterator ranges = new ReplicaPlanIterator(command.dataRange().keyRange(), keyspace, ONE)) {
assertEquals(MAX_CONCURRENCY_FACTOR, partitions.concurrencyFactor());
assertEquals(MAX_CONCURRENCY_FACTOR, partitions.maxConcurrencyFactor());
assertEquals(5, ranges.size());
}
// with 0 estimated results per range the concurrency factor should be 1
command = command(cfs, 1000, 0);
try (RangeCommandIterator partitions = RangeCommands.rangeCommandIterator(command, ONE, nanoTime());
ReplicaPlanIterator ranges = new ReplicaPlanIterator(command.dataRange().keyRange(), keyspace, ONE)) {
assertEquals(1, partitions.concurrencyFactor());
assertEquals(MAX_CONCURRENCY_FACTOR, partitions.maxConcurrencyFactor());
assertEquals(5, ranges.size());
}
}
use of org.apache.cassandra.db.PartitionRangeReadCommand in project cassandra by apache.
the class RangeCommandIteratorTest method testRangeQueried.
@Test
public void testRangeQueried() {
List<Token> tokens = setTokens(100, 200, 300, 400);
// n tokens divide token ring into n+1 ranges
int vnodeCount = tokens.size() + 1;
Keyspace keyspace = Keyspace.open(KEYSPACE1);
ColumnFamilyStore cfs = keyspace.getColumnFamilyStore(CF_STANDARD1);
cfs.clearUnsafe();
int rows = 100;
for (int i = 0; i < rows; ++i) {
RowUpdateBuilder builder = new RowUpdateBuilder(cfs.metadata(), 10, String.valueOf(i));
builder.clustering("c");
builder.add("val", String.valueOf(i));
builder.build().applyUnsafe();
}
cfs.forceBlockingFlush();
PartitionRangeReadCommand command = (PartitionRangeReadCommand) Util.cmd(cfs).build();
AbstractBounds<PartitionPosition> keyRange = command.dataRange().keyRange();
// without range merger, there will be 2 batches requested: 1st batch with 1 range and 2nd batch with remaining ranges
CloseableIterator<ReplicaPlan.ForRangeRead> replicaPlans = replicaPlanIterator(keyRange, keyspace, false);
RangeCommandIterator data = new RangeCommandIterator(replicaPlans, command, 1, 1000, vnodeCount, nanoTime());
verifyRangeCommandIterator(data, rows, 2, vnodeCount);
// without range merger and initial cf=5, there will be 1 batches requested: 5 vnode ranges for 1st batch
replicaPlans = replicaPlanIterator(keyRange, keyspace, false);
data = new RangeCommandIterator(replicaPlans, command, vnodeCount, 1000, vnodeCount, nanoTime());
verifyRangeCommandIterator(data, rows, 1, vnodeCount);
// without range merger and max cf=1, there will be 5 batches requested: 1 vnode range per batch
replicaPlans = replicaPlanIterator(keyRange, keyspace, false);
data = new RangeCommandIterator(replicaPlans, command, 1, 1, vnodeCount, nanoTime());
verifyRangeCommandIterator(data, rows, vnodeCount, vnodeCount);
// with range merger, there will be only 1 batch requested, as all ranges share the same replica - localhost
replicaPlans = replicaPlanIterator(keyRange, keyspace, true);
data = new RangeCommandIterator(replicaPlans, command, 1, 1000, vnodeCount, nanoTime());
verifyRangeCommandIterator(data, rows, 1, vnodeCount);
// with range merger and max cf=1, there will be only 1 batch requested, as all ranges share the same replica - localhost
replicaPlans = replicaPlanIterator(keyRange, keyspace, true);
data = new RangeCommandIterator(replicaPlans, command, 1, 1, vnodeCount, nanoTime());
verifyRangeCommandIterator(data, rows, 1, vnodeCount);
}
use of org.apache.cassandra.db.PartitionRangeReadCommand in project cassandra by apache.
the class RangeCommandIterator method query.
/**
* Queries the provided sub-range.
*
* @param replicaPlan the subRange to query.
* @param isFirst in the case where multiple queries are sent in parallel, whether that's the first query on
* that batch or not. The reason it matters is that whe paging queries, the command (more specifically the
* {@code DataLimits}) may have "state" information and that state may only be valid for the first query (in
* that it's the query that "continues" whatever we're previously queried).
*/
private SingleRangeResponse query(ReplicaPlan.ForRangeRead replicaPlan, boolean isFirst) {
PartitionRangeReadCommand rangeCommand = command.forSubRange(replicaPlan.range(), isFirst);
// If enabled, request repaired data tracking info from full replicas, but
// only if there are multiple full replicas to compare results from.
boolean trackRepairedStatus = DatabaseDescriptor.getRepairedDataTrackingForRangeReadsEnabled() && replicaPlan.contacts().filter(Replica::isFull).size() > 1;
ReplicaPlan.SharedForRangeRead sharedReplicaPlan = ReplicaPlan.shared(replicaPlan);
ReadRepair<EndpointsForRange, ReplicaPlan.ForRangeRead> readRepair = ReadRepair.create(command, sharedReplicaPlan, queryStartNanoTime);
DataResolver<EndpointsForRange, ReplicaPlan.ForRangeRead> resolver = new DataResolver<>(rangeCommand, sharedReplicaPlan, readRepair, queryStartNanoTime, trackRepairedStatus);
ReadCallback<EndpointsForRange, ReplicaPlan.ForRangeRead> handler = new ReadCallback<>(resolver, rangeCommand, sharedReplicaPlan, queryStartNanoTime);
if (replicaPlan.contacts().size() == 1 && replicaPlan.contacts().get(0).isSelf()) {
Stage.READ.execute(new StorageProxy.LocalReadRunnable(rangeCommand, handler, trackRepairedStatus));
} else {
for (Replica replica : replicaPlan.contacts()) {
Tracing.trace("Enqueuing request to {}", replica);
ReadCommand command = replica.isFull() ? rangeCommand : rangeCommand.copyAsTransientQuery(replica);
Message<ReadCommand> message = command.createMessage(trackRepairedStatus && replica.isFull());
MessagingService.instance().sendWithCallback(message, replica.endpoint(), handler);
}
}
return new SingleRangeResponse(resolver, handler, readRepair);
}
Aggregations