use of org.apache.cassandra.db.RegularAndStaticColumns in project cassandra by apache.
the class ReplicaFilteringProtection method mergeController.
/**
* Returns a merge listener that skips the merged rows for which any of the replicas doesn't have a version,
* pessimistically assuming that they are outdated. It is intended to be used during a first merge of per-replica
* query results to ensure we fetch enough results from the replicas to ensure we don't miss any potentially
* outdated result.
* <p>
* The listener will track both the accepted data and the primary keys of the rows that are considered as outdated.
* That way, once the query results would have been merged using this listener, further calls to
* {@link #queryProtectedPartitions(PartitionIterator, int)} will use the collected data to return a copy of the
* data originally collected from the specified replica, completed with the potentially outdated rows.
*/
UnfilteredPartitionIterators.MergeListener mergeController() {
return new UnfilteredPartitionIterators.MergeListener() {
@Override
public void close() {
// If we hit the failure threshold before consuming a single partition, record the current rows cached.
tableMetrics.rfpRowsCachedPerQuery.update(Math.max(currentRowsCached, maxRowsCached));
}
@Override
public UnfilteredRowIterators.MergeListener getRowMergeListener(DecoratedKey partitionKey, List<UnfilteredRowIterator> versions) {
List<PartitionBuilder> builders = new ArrayList<>(sources.size());
RegularAndStaticColumns columns = columns(versions);
EncodingStats stats = EncodingStats.merge(versions, NULL_TO_NO_STATS);
for (int i = 0; i < sources.size(); i++) builders.add(i, new PartitionBuilder(partitionKey, sources.get(i), columns, stats));
return new UnfilteredRowIterators.MergeListener() {
@Override
public void onMergedPartitionLevelDeletion(DeletionTime mergedDeletion, DeletionTime[] versions) {
// cache the deletion time versions to be able to regenerate the original row iterator
for (int i = 0; i < versions.length; i++) builders.get(i).setDeletionTime(versions[i]);
}
@Override
public Row onMergedRows(Row merged, Row[] versions) {
// cache the row versions to be able to regenerate the original row iterator
for (int i = 0; i < versions.length; i++) builders.get(i).addRow(versions[i]);
if (merged.isEmpty())
return merged;
boolean isPotentiallyOutdated = false;
boolean isStatic = merged.isStatic();
for (int i = 0; i < versions.length; i++) {
Row version = versions[i];
if (version == null || (isStatic && version.isEmpty())) {
isPotentiallyOutdated = true;
builders.get(i).addToFetch(merged);
}
}
// to look at enough data to ultimately fulfill the query limit.
return isPotentiallyOutdated ? null : merged;
}
@Override
public void onMergedRangeTombstoneMarkers(RangeTombstoneMarker merged, RangeTombstoneMarker[] versions) {
// cache the marker versions to be able to regenerate the original row iterator
for (int i = 0; i < versions.length; i++) builders.get(i).addRangeTombstoneMarker(versions[i]);
}
@Override
public void close() {
for (int i = 0; i < sources.size(); i++) originalPartitions.get(i).add(builders.get(i));
}
};
}
};
}
use of org.apache.cassandra.db.RegularAndStaticColumns in project cassandra by apache.
the class CollatedViewIndexBuilder method build.
public void build() {
try {
int pageSize = cfs.indexManager.calculateIndexingPageSize();
RegularAndStaticColumns targetPartitionColumns = extractIndexedColumns();
while (iter.hasNext()) {
if (isStopRequested())
throw new CompactionInterruptedException(getCompactionInfo());
DecoratedKey key = iter.next();
cfs.indexManager.indexPartition(key, indexers, pageSize, targetPartitionColumns);
}
} finally {
iter.close();
}
}
use of org.apache.cassandra.db.RegularAndStaticColumns in project cassandra by apache.
the class CollatedViewIndexBuilder method extractIndexedColumns.
private RegularAndStaticColumns extractIndexedColumns() {
RegularAndStaticColumns.Builder builder = RegularAndStaticColumns.builder();
for (Index index : indexers) {
boolean isPartitionIndex = true;
for (ColumnMetadata column : cfs.metadata().regularAndStaticColumns()) {
if (index.dependsOn(column)) {
builder.add(column);
isPartitionIndex = false;
}
}
// so we can use the base partition columns as the input source
if (isPartitionIndex)
return cfs.metadata().regularAndStaticColumns();
}
return builder.build();
}
use of org.apache.cassandra.db.RegularAndStaticColumns in project cassandra by apache.
the class RowFilterTest method testCQLFilterClose.
@Test
public void testCQLFilterClose() {
// CASSANDRA-15126
TableMetadata metadata = TableMetadata.builder("testks", "testcf").addPartitionKeyColumn("pk", Int32Type.instance).addStaticColumn("s", Int32Type.instance).addRegularColumn("r", Int32Type.instance).build();
ColumnMetadata s = metadata.getColumn(new ColumnIdentifier("s", true));
ColumnMetadata r = metadata.getColumn(new ColumnIdentifier("r", true));
ByteBuffer one = Int32Type.instance.decompose(1);
RowFilter filter = RowFilter.NONE.withNewExpressions(new ArrayList<>());
filter.add(s, Operator.NEQ, one);
AtomicBoolean closed = new AtomicBoolean();
UnfilteredPartitionIterator iter = filter.filter(new SingletonUnfilteredPartitionIterator(new UnfilteredRowIterator() {
public DeletionTime partitionLevelDeletion() {
return null;
}
public EncodingStats stats() {
return null;
}
public TableMetadata metadata() {
return metadata;
}
public boolean isReverseOrder() {
return false;
}
public RegularAndStaticColumns columns() {
return null;
}
public DecoratedKey partitionKey() {
return null;
}
public boolean hasNext() {
return false;
}
public Unfiltered next() {
return null;
}
public Row staticRow() {
return BTreeRow.create(Clustering.STATIC_CLUSTERING, LivenessInfo.EMPTY, Row.Deletion.LIVE, BTree.singleton(new BufferCell(s, 1, Cell.NO_TTL, Cell.NO_DELETION_TIME, one, null)));
}
public void close() {
closed.set(true);
}
}), 1);
Assert.assertFalse(iter.hasNext());
Assert.assertTrue(closed.get());
filter = RowFilter.NONE.withNewExpressions(new ArrayList<>());
filter.add(r, Operator.NEQ, one);
closed.set(false);
iter = filter.filter(new SingletonUnfilteredPartitionIterator(new UnfilteredRowIterator() {
boolean hasNext = true;
public DeletionTime partitionLevelDeletion() {
return null;
}
public EncodingStats stats() {
return null;
}
public TableMetadata metadata() {
return metadata;
}
public boolean isReverseOrder() {
return false;
}
public RegularAndStaticColumns columns() {
return null;
}
public DecoratedKey partitionKey() {
return null;
}
public Row staticRow() {
return Rows.EMPTY_STATIC_ROW;
}
public boolean hasNext() {
boolean r = hasNext;
hasNext = false;
return r;
}
public Unfiltered next() {
return BTreeRow.create(Clustering.EMPTY, LivenessInfo.EMPTY, Row.Deletion.LIVE, BTree.singleton(new BufferCell(r, 1, Cell.NO_TTL, Cell.NO_DELETION_TIME, one, null)));
}
public void close() {
closed.set(true);
}
}), 1);
Assert.assertFalse(iter.hasNext());
Assert.assertTrue(closed.get());
}
use of org.apache.cassandra.db.RegularAndStaticColumns in project cassandra by apache.
the class ReplicaFilteringProtection method columns.
private static RegularAndStaticColumns columns(List<UnfilteredRowIterator> versions) {
Columns statics = Columns.NONE;
Columns regulars = Columns.NONE;
for (UnfilteredRowIterator iter : versions) {
if (iter == null)
continue;
RegularAndStaticColumns cols = iter.columns();
statics = statics.mergeTo(cols.statics);
regulars = regulars.mergeTo(cols.regulars);
}
return new RegularAndStaticColumns(statics, regulars);
}
Aggregations