use of org.apache.cassandra.index.StubIndex in project cassandra by apache.
the class RangeTombstoneTest method testRowWithRangeTombstonesUpdatesSecondaryIndex.
@Test
public void testRowWithRangeTombstonesUpdatesSecondaryIndex() throws Exception {
Keyspace table = Keyspace.open(KSNAME);
ColumnFamilyStore cfs = table.getColumnFamilyStore(CFNAME);
ByteBuffer key = ByteBufferUtil.bytes("k5");
ByteBuffer indexedColumnName = ByteBufferUtil.bytes("val");
cfs.truncateBlocking();
cfs.disableAutoCompaction();
ColumnMetadata cd = cfs.metadata().getColumn(indexedColumnName).copy();
IndexMetadata indexDef = IndexMetadata.fromIndexTargets(Collections.singletonList(new IndexTarget(cd.name, IndexTarget.Type.VALUES)), "test_index", IndexMetadata.Kind.CUSTOM, ImmutableMap.of(IndexTarget.CUSTOM_INDEX_OPTION_NAME, StubIndex.class.getName()));
TableMetadata current = cfs.metadata();
if (!current.indexes.get("test_index").isPresent()) {
TableMetadata updated = current.unbuild().indexes(current.indexes.with(indexDef)).build();
MigrationManager.announceTableUpdate(updated, true);
}
Future<?> rebuild = cfs.indexManager.addIndex(indexDef, false);
// If rebuild there is, wait for the rebuild to finish so it doesn't race with the following insertions
if (rebuild != null)
rebuild.get();
StubIndex index = (StubIndex) cfs.indexManager.listIndexes().stream().filter(i -> "test_index".equals(i.getIndexMetadata().name)).findFirst().orElseThrow(() -> new RuntimeException(new AssertionError("Index not found")));
index.reset();
UpdateBuilder builder = UpdateBuilder.create(cfs.metadata(), key).withTimestamp(0);
for (int i = 0; i < 10; i++) builder.newRow(i).add("val", i);
builder.applyUnsafe();
cfs.forceBlockingFlush();
new RowUpdateBuilder(cfs.metadata(), 0, key).addRangeTombstone(0, 7).build().applyUnsafe();
cfs.forceBlockingFlush();
assertEquals(10, index.rowsInserted.size());
CompactionManager.instance.performMaximal(cfs, false);
// compacted down to single sstable
assertEquals(1, cfs.getLiveSSTables().size());
assertEquals(8, index.rowsDeleted.size());
}
use of org.apache.cassandra.index.StubIndex in project cassandra by apache.
the class RangeTombstoneTest method testOverwritesToDeletedColumns.
@Test
public void testOverwritesToDeletedColumns() throws Exception {
Keyspace table = Keyspace.open(KSNAME);
ColumnFamilyStore cfs = table.getColumnFamilyStore(CFNAME);
ByteBuffer key = ByteBufferUtil.bytes("k6");
ByteBuffer indexedColumnName = ByteBufferUtil.bytes("val");
cfs.truncateBlocking();
cfs.disableAutoCompaction();
ColumnMetadata cd = cfs.metadata().getColumn(indexedColumnName).copy();
IndexMetadata indexDef = IndexMetadata.fromIndexTargets(Collections.singletonList(new IndexTarget(cd.name, IndexTarget.Type.VALUES)), "test_index", IndexMetadata.Kind.CUSTOM, ImmutableMap.of(IndexTarget.CUSTOM_INDEX_OPTION_NAME, StubIndex.class.getName()));
TableMetadata current = cfs.metadata();
if (!current.indexes.get("test_index").isPresent()) {
TableMetadata updated = current.unbuild().indexes(current.indexes.with(indexDef)).build();
MigrationManager.announceTableUpdate(updated, true);
}
Future<?> rebuild = cfs.indexManager.addIndex(indexDef, false);
// If rebuild there is, wait for the rebuild to finish so it doesn't race with the following insertions
if (rebuild != null)
rebuild.get();
StubIndex index = (StubIndex) cfs.indexManager.getIndexByName("test_index");
index.reset();
UpdateBuilder.create(cfs.metadata(), key).withTimestamp(0).newRow(1).add("val", 1).applyUnsafe();
// add a RT which hides the column we just inserted
new RowUpdateBuilder(cfs.metadata(), 1, key).addRangeTombstone(0, 1).build().applyUnsafe();
// now re-insert that column
UpdateBuilder.create(cfs.metadata(), key).withTimestamp(2).newRow(1).add("val", 1).applyUnsafe();
cfs.forceBlockingFlush();
// We should have 1 insert and 1 update to the indexed "1" column
// CASSANDRA-6640 changed index update to just update, not insert then delete
assertEquals(1, index.rowsInserted.size());
assertEquals(1, index.rowsUpdated.size());
}
use of org.apache.cassandra.index.StubIndex in project cassandra by apache.
the class CancelCompactionsTest method testIndexRebuild.
/**
* Make sure index rebuilds get cancelled
*/
@Test
public void testIndexRebuild() throws ExecutionException, InterruptedException {
ColumnFamilyStore cfs = MockSchema.newCFS();
List<SSTableReader> sstables = createSSTables(cfs, 5, 0);
Index idx = new StubIndex(cfs, null);
CountDownLatch indexBuildStarted = new CountDownLatch(1);
CountDownLatch indexBuildRunning = new CountDownLatch(1);
CountDownLatch compactionsStopped = new CountDownLatch(1);
ReducingKeyIterator reducingKeyIterator = new ReducingKeyIterator(sstables) {
@Override
public boolean hasNext() {
indexBuildStarted.countDown();
try {
indexBuildRunning.await();
} catch (InterruptedException e) {
throw new RuntimeException();
}
return false;
}
};
Future<?> f = CompactionManager.instance.submitIndexBuild(new CollatedViewIndexBuilder(cfs, Collections.singleton(idx), reducingKeyIterator, ImmutableSet.copyOf(sstables)));
// wait for hasNext to get called
indexBuildStarted.await();
assertEquals(1, getActiveCompactionsForTable(cfs).size());
boolean foundCompaction = false;
for (CompactionInfo.Holder holder : getActiveCompactionsForTable(cfs)) {
if (holder.getCompactionInfo().getSSTables().equals(new HashSet<>(sstables))) {
assertFalse(holder.isStopRequested());
foundCompaction = true;
}
}
assertTrue(foundCompaction);
cfs.runWithCompactionsDisabled(() -> {
compactionsStopped.countDown();
return null;
}, (sstable) -> true, false, false, true);
// wait for the runWithCompactionsDisabled callable
compactionsStopped.await();
assertEquals(1, getActiveCompactionsForTable(cfs).size());
foundCompaction = false;
for (CompactionInfo.Holder holder : getActiveCompactionsForTable(cfs)) {
if (holder.getCompactionInfo().getSSTables().equals(new HashSet<>(sstables))) {
assertTrue(holder.isStopRequested());
foundCompaction = true;
}
}
assertTrue(foundCompaction);
// signal that the index build should be finished
indexBuildRunning.countDown();
f.get();
assertTrue(getActiveCompactionsForTable(cfs).isEmpty());
}
use of org.apache.cassandra.index.StubIndex in project cassandra by apache.
the class SecondaryIndexTest method testUpdatesToMemtableData.
@Test
public void testUpdatesToMemtableData() throws Throwable {
// verify the contract specified by Index.Indexer::updateRow(oldRowData, newRowData),
// when a row in the memtable is updated, the indexer should be informed of:
// * new columns
// * removed columns
// * columns whose value, timestamp or ttl have been modified.
// Any columns which are unchanged by the update are not passed to the Indexer
// Note that for simplicity this test resets the index between each scenario
createTable("CREATE TABLE %s (k int, c int, v1 int, v2 int, PRIMARY KEY (k,c))");
createIndex(format("CREATE CUSTOM INDEX test_index ON %%s() USING '%s'", StubIndex.class.getName()));
execute("INSERT INTO %s (k, c, v1, v2) VALUES (0, 0, 0, 0) USING TIMESTAMP 0");
ColumnMetadata v1 = getCurrentColumnFamilyStore().metadata().getColumn(new ColumnIdentifier("v1", true));
ColumnMetadata v2 = getCurrentColumnFamilyStore().metadata().getColumn(new ColumnIdentifier("v2", true));
StubIndex index = (StubIndex) getCurrentColumnFamilyStore().indexManager.getIndexByName("test_index");
assertEquals(1, index.rowsInserted.size());
// Overwrite a single value, leaving the other untouched
execute("UPDATE %s USING TIMESTAMP 1 SET v1=1 WHERE k=0 AND c=0");
assertEquals(1, index.rowsUpdated.size());
Row oldRow = index.rowsUpdated.get(0).left;
assertEquals(1, oldRow.columnCount());
validateCell(oldRow.getCell(v1), v1, ByteBufferUtil.bytes(0), 0);
Row newRow = index.rowsUpdated.get(0).right;
assertEquals(1, newRow.columnCount());
validateCell(newRow.getCell(v1), v1, ByteBufferUtil.bytes(1), 1);
index.reset();
// Overwrite both values
execute("UPDATE %s USING TIMESTAMP 2 SET v1=2, v2=2 WHERE k=0 AND c=0");
assertEquals(1, index.rowsUpdated.size());
oldRow = index.rowsUpdated.get(0).left;
assertEquals(2, oldRow.columnCount());
validateCell(oldRow.getCell(v1), v1, ByteBufferUtil.bytes(1), 1);
validateCell(oldRow.getCell(v2), v2, ByteBufferUtil.bytes(0), 0);
newRow = index.rowsUpdated.get(0).right;
assertEquals(2, newRow.columnCount());
validateCell(newRow.getCell(v1), v1, ByteBufferUtil.bytes(2), 2);
validateCell(newRow.getCell(v2), v2, ByteBufferUtil.bytes(2), 2);
index.reset();
// Delete one value
execute("DELETE v1 FROM %s USING TIMESTAMP 3 WHERE k=0 AND c=0");
assertEquals(1, index.rowsUpdated.size());
oldRow = index.rowsUpdated.get(0).left;
assertEquals(1, oldRow.columnCount());
validateCell(oldRow.getCell(v1), v1, ByteBufferUtil.bytes(2), 2);
newRow = index.rowsUpdated.get(0).right;
assertEquals(1, newRow.columnCount());
Cell<?> newCell = newRow.getCell(v1);
assertTrue(newCell.isTombstone());
assertEquals(3, newCell.timestamp());
index.reset();
// Modify the liveness of the primary key, the delta rows should contain
// no cell data as only the pk was altered, but it should illustrate the
// change to the liveness info
execute("INSERT INTO %s(k, c) VALUES (0, 0) USING TIMESTAMP 4");
assertEquals(1, index.rowsUpdated.size());
oldRow = index.rowsUpdated.get(0).left;
assertEquals(0, oldRow.columnCount());
assertEquals(0, oldRow.primaryKeyLivenessInfo().timestamp());
newRow = index.rowsUpdated.get(0).right;
assertEquals(0, newRow.columnCount());
assertEquals(4, newRow.primaryKeyLivenessInfo().timestamp());
}
use of org.apache.cassandra.index.StubIndex in project cassandra by apache.
the class SecondaryIndexTest method testDeletions.
@Test
public void testDeletions() throws Throwable {
// Test for bugs like CASSANDRA-10694. These may not be readily visible with the built-in secondary index
// implementation because of the stale entry handling.
String indexClassName = StubIndex.class.getName();
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY ((a), b))");
createIndex(format("CREATE CUSTOM INDEX c_idx ON %%s(c) USING '%s'", indexClassName));
ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
TableMetadata cfm = cfs.metadata();
StubIndex index1 = (StubIndex) cfs.indexManager.getIndex(cfm.indexes.get("c_idx").orElseThrow(throwAssert("index not found")));
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?) USING TIMESTAMP 1", 0, 0, 0);
assertEquals(1, index1.rowsInserted.size());
execute("DELETE FROM %s USING TIMESTAMP 2 WHERE a = ? AND b = ?", 0, 0);
assertEquals(1, index1.rowsUpdated.size());
Pair<Row, Row> update = index1.rowsUpdated.get(0);
Row existingRow = update.left;
Row newRow = update.right;
// check the existing row from the update call
assertTrue(existingRow.deletion().isLive());
assertEquals(DeletionTime.LIVE, existingRow.deletion().time());
assertEquals(1L, existingRow.primaryKeyLivenessInfo().timestamp());
// check the new row from the update call
assertFalse(newRow.deletion().isLive());
assertEquals(2L, newRow.deletion().time().markedForDeleteAt());
assertFalse(newRow.cells().iterator().hasNext());
// delete the same row again
execute("DELETE FROM %s USING TIMESTAMP 3 WHERE a = ? AND b = ?", 0, 0);
assertEquals(2, index1.rowsUpdated.size());
update = index1.rowsUpdated.get(1);
existingRow = update.left;
newRow = update.right;
// check the new row from the update call
assertFalse(existingRow.deletion().isLive());
assertEquals(2L, existingRow.deletion().time().markedForDeleteAt());
assertFalse(existingRow.cells().iterator().hasNext());
// check the new row from the update call
assertFalse(newRow.deletion().isLive());
assertEquals(3L, newRow.deletion().time().markedForDeleteAt());
assertFalse(newRow.cells().iterator().hasNext());
}
Aggregations