Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions src/java/org/apache/cassandra/db/rows/BTreeRow.java
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@ public ColumnData resolve(Object[] cells, int lb, int ub)
private final boolean isSorted;
private BTree.Builder<Cell<?>> cells_;
private boolean hasComplex = false;
private long minCellDeletionTime = Cell.MAX_DELETION_TIME;

// For complex column at index i of 'columns', we store at complexDeletions[i] its complex deletion.

Expand Down Expand Up @@ -888,6 +889,7 @@ protected Builder(Builder builder)
cells_ = builder.cells_ == null ? null : builder.cells_.copy();
isSorted = builder.isSorted;
hasComplex = builder.hasComplex;
minCellDeletionTime = builder.minCellDeletionTime;
}

@Override
Expand Down Expand Up @@ -919,6 +921,7 @@ protected void reset()
this.deletion = Deletion.LIVE;
this.cells_.reuse();
this.hasComplex = false;
this.minCellDeletionTime = Cell.MAX_DELETION_TIME;
if (pool != null)
{
pool.offer(this);
Expand Down Expand Up @@ -951,12 +954,14 @@ public void addCell(Cell<?> cell)

getCells().add(cell);
hasComplex |= cell.column.isComplex();
minCellDeletionTime = Math.min(minCellDeletionTime, minDeletionTime(cell));
}

public void addComplexDeletion(ColumnMetadata column, DeletionTime complexDeletion)
{
getCells().add(new ComplexColumnDeletion(column, complexDeletion));
hasComplex = true;
minCellDeletionTime = Math.min(minCellDeletionTime, minDeletionTime(complexDeletion));
}

public Row build()
Expand All @@ -965,14 +970,33 @@ public Row build()
getCells().sort();
// we can avoid resolving if we're sorted and have no complex values
// (because we'll only have unique simple cells, which are already in their final condition)
if (!isSorted | hasComplex)
boolean resolved = !isSorted | hasComplex;
if (resolved)
getCells().resolve(CellResolver.instance);
Object[] btree = getCells().build();

if (deletion.isShadowedBy(primaryKeyLivenessInfo))
deletion = Deletion.LIVE;

long minDeletionTime = minDeletionTime(btree, primaryKeyLivenessInfo, deletion.time());
long minDeletionTime;
// Use the incrementally tracked min when it is guaranteed to be exact:
// - !resolved: CellResolver did not run, so no cells were merged or shadowed.
// - minCellDeletionTime == Cell.MAX_DELETION_TIME: no cell or complex deletion contributed
// any deletion info, so reconciliation in CellResolver cannot have made the tracked min
// pessimistic (every cell has localDeletionTime == NO_DELETION_TIME).
// Otherwise fall back to the exact O(N) computation, since reconciliation between expiring
// cells with equal timestamps may keep a cell whose localDeletionTime is larger than what
// we tracked.
if (!resolved || minCellDeletionTime == Cell.MAX_DELETION_TIME)
{
minDeletionTime = Math.min(minCellDeletionTime,
Math.min(minDeletionTime(primaryKeyLivenessInfo),
minDeletionTime(deletion.time())));
}
else
{
minDeletionTime = minDeletionTime(btree, primaryKeyLivenessInfo, deletion.time());
}
Row row = BTreeRow.create(clustering, primaryKeyLivenessInfo, deletion, btree, minDeletionTime);
reset();
return row;
Expand Down