in harry-core/src/harry/corruptor/AddExtraRowCorruptor.java [56:90]
public boolean maybeCorrupt(Query query, SystemUnderTest sut)
{
Set<Long> cds = new HashSet<>();
long maxLts = tracker.maxStarted();
for (Object[] obj : sut.execute(query.toSelectStatement(), SystemUnderTest.ConsistencyLevel.ALL))
{
ResultSetRow row = SelectHelper.resultSetToRow(schema, clock, obj);
// TODO: extract CD cheaper
cds.add(row.cd);
}
boolean partitionIsFull = cds.size() >= descriptorSelector.maxPartitionSize();
long attempt = 0;
long cd = descriptorSelector.randomCd(query.pd, attempt, schema);
while (!query.match(cd) || cds.contains(cd))
{
if (partitionIsFull)
// We can't pick from the existing CDs, so let's try to come up with a new one that would match the query
cd += descriptorSelector.randomCd(query.pd, attempt, schema);
else
cd = descriptorSelector.randomCd(query.pd, attempt, schema);
if (attempt++ == 1000)
return false;
}
long[] vds = descriptorSelector.vds(query.pd, cd, maxLts, 0, OpSelectors.OperationKind.INSERT, schema);
// We do not know if the row was deleted. We could try inferring it, but that
// still won't help since we can't use it anyways, since collisions between a
// written value and tombstone are resolved in favour of tombstone, so we're
// just going to take the next lts.
logger.info("Corrupting the resultset by writing a row with cd {}", cd);
sut.execute(WriteHelper.inflateInsert(schema, query.pd, cd, vds, null, clock.rts(maxLts) + 1), SystemUnderTest.ConsistencyLevel.ALL);
return true;
}