Repository: cassandra
Updated Branches:
  refs/heads/cassandra-3.0 5034f4495 -> 8210075c5
  refs/heads/trunk 74ee6684c -> a88d3e896


On CFS::reload, execute the reload task for each secondary index

Patch by Sam Tunnicliffe; reviewed by Tyler Hobbs for CASSANDRA-10604


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/8210075c
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/8210075c
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/8210075c

Branch: refs/heads/cassandra-3.0
Commit: 8210075c57af696e78000e8cd0019737b2373875
Parents: 5034f44
Author: Sam Tunnicliffe <[email protected]>
Authored: Wed Oct 28 13:16:15 2015 +0000
Committer: Sam Tunnicliffe <[email protected]>
Committed: Wed Oct 28 17:23:57 2015 +0000

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 src/java/org/apache/cassandra/index/Index.java  | 11 ++++++
 .../cassandra/index/SecondaryIndexManager.java  | 16 +++-----
 .../index/internal/CassandraIndex.java          |  1 -
 .../apache/cassandra/index/CustomIndexTest.java | 40 ++++++++++++++++++++
 .../index/internal/CassandraIndexTest.java      |  9 +++++
 6 files changed, 66 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 4ead854..c945bd2 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.0
+ * Execute the metadata reload task of all registered indexes on CFS::reload 
(CASSANDRA-10604)
  * Fix thrift cas operations with defined columns (CASSANDRA-10576)
  * Fix PartitionUpdate.operationCount()for updates with static column 
operations (CASSANDRA-10606)
  * Fix thrift get() queries with defined columns (CASSANDRA-10586)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/src/java/org/apache/cassandra/index/Index.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/index/Index.java 
b/src/java/org/apache/cassandra/index/Index.java
index 0f4ecbd..b6c12a9 100644
--- a/src/java/org/apache/cassandra/index/Index.java
+++ b/src/java/org/apache/cassandra/index/Index.java
@@ -296,9 +296,20 @@ public interface Index
      * Listener for processing events emitted during a single partition update.
      * Instances of this are responsible for applying modifications to the 
index in response to a single update
      * operation on a particular partition of the base table.
+     *
      * That update may be generated by the normal write path, by iterating 
SSTables during streaming operations or when
      * building or rebuilding an index from source. Updates also occur during 
compaction when multiple versions of a
      * source partition from different SSTables are merged.
+     *
+     * Implementations should not make assumptions about resolution or 
filtering of the partition update being
+     * processed. That is to say that it is possible for an Indexer instance 
to receive notification of a
+     * PartitionDelete or RangeTombstones which shadow a Row it then receives 
via insertRow/updateRow.
+     *
+     * It is important to note that the only ordering guarantee made for the 
methods here is that the first call will
+     * be to begin() and the last call to finish(). The other methods may be 
called to process update events in any
+     * order. This can also include duplicate calls, in cases where a memtable 
partition is under contention from
+     * several updates. In that scenario, the same set of events may be 
delivered to the Indexer as memtable update
+     * which failed due to contention is re-applied.
      */
     public interface Indexer
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/src/java/org/apache/cassandra/index/SecondaryIndexManager.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/index/SecondaryIndexManager.java 
b/src/java/org/apache/cassandra/index/SecondaryIndexManager.java
index 3ed9714..92b04fe 100644
--- a/src/java/org/apache/cassandra/index/SecondaryIndexManager.java
+++ b/src/java/org/apache/cassandra/index/SecondaryIndexManager.java
@@ -142,17 +142,11 @@ public class SecondaryIndexManager implements 
IndexRegistry
 
     private Future<?> reloadIndex(IndexMetadata indexDef)
     {
-        // if the index metadata has changed, reload the index
-        IndexMetadata registered = 
indexes.get(indexDef.name).getIndexMetadata();
-        if (!registered.equals(indexDef))
-        {
-            Index index = indexes.remove(registered.name);
-            index.register(this);
-            return 
blockingExecutor.submit(index.getMetadataReloadTask(indexDef));
-        }
-
-        // otherwise, nothing to do
-        return Futures.immediateFuture(null);
+        Index index = indexes.get(indexDef.name);
+        Callable<?> reloadTask = index.getMetadataReloadTask(indexDef);
+        return reloadTask == null
+               ? Futures.immediateFuture(null)
+               : 
blockingExecutor.submit(index.getMetadataReloadTask(indexDef));
     }
 
     private Future<?> createIndex(IndexMetadata indexDef)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/index/internal/CassandraIndex.java 
b/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
index 5b5b7e4..674cd20 100644
--- a/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
+++ b/src/java/org/apache/cassandra/index/internal/CassandraIndex.java
@@ -183,7 +183,6 @@ public abstract class CassandraIndex implements Index
 
     public Callable<?> getMetadataReloadTask(IndexMetadata indexDef)
     {
-        setMetadata(indexDef);
         return () -> {
             indexCfs.metadata.reloadIndexMetadataProperties(baseCfs.metadata);
             indexCfs.reload();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/test/unit/org/apache/cassandra/index/CustomIndexTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/index/CustomIndexTest.java 
b/test/unit/org/apache/cassandra/index/CustomIndexTest.java
index b2c9257..b372c59 100644
--- a/test/unit/org/apache/cassandra/index/CustomIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/CustomIndexTest.java
@@ -1,6 +1,8 @@
 package org.apache.cassandra.index;
 
 import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 import com.google.common.collect.ImmutableList;
@@ -452,6 +454,23 @@ public class CustomIndexTest extends CQLTester
                              "SELECT * FROM %s WHERE expr(int_index, 'foo')");
     }
 
+    @Test
+    public void reloadIndexMetadataOnBaseCfsReload() throws Throwable
+    {
+        // verify that whenever the base table CFMetadata is reloaded, a 
reload of the index
+        // metadata is performed
+        createTable("CREATE TABLE %s (k int, v1 int, PRIMARY KEY(k))");
+        createIndex(String.format("CREATE CUSTOM INDEX reload_counter ON %%s() 
USING '%s'",
+                                  CountMetadataReloadsIndex.class.getName()));
+        ColumnFamilyStore cfs = getCurrentColumnFamilyStore();
+        CountMetadataReloadsIndex index = 
(CountMetadataReloadsIndex)cfs.indexManager.getIndexByName("reload_counter");
+        assertEquals(0, index.reloads.get());
+
+        // reloading the CFS, even without any metadata changes invokes the 
index's metadata reload task
+        cfs.reload();
+        assertEquals(1, index.reloads.get());
+    }
+
     private void testCreateIndex(String indexName, String... 
targetColumnNames) throws Throwable
     {
         createIndex(String.format("CREATE CUSTOM INDEX %s ON %%s(%s) USING 
'%s'",
@@ -495,6 +514,27 @@ public class CustomIndexTest extends CQLTester
         return new IndexTarget(ColumnIdentifier.getInterned(name, true), type);
     }
 
+    public static final class CountMetadataReloadsIndex extends StubIndex
+    {
+        private final AtomicInteger reloads = new AtomicInteger(0);
+
+        public CountMetadataReloadsIndex(ColumnFamilyStore baseCfs, 
IndexMetadata metadata)
+        {
+            super(baseCfs, metadata);
+        }
+
+        public void reset()
+        {
+            super.reset();
+            reloads.set(0);
+        }
+
+        public Callable<?> getMetadataReloadTask(IndexMetadata indexMetadata)
+        {
+            return reloads::incrementAndGet;
+        }
+    }
+
     public static final class IndexIncludedInBuild extends StubIndex
     {
         public IndexIncludedInBuild(ColumnFamilyStore baseCfs, IndexMetadata 
metadata)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8210075c/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java 
b/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
index 2ca858d..934e551 100644
--- a/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
@@ -639,9 +639,18 @@ public class CassandraIndexTest extends CQLTester
             assertRows(execute(selectFirstRowCql), firstRow);
             assertEmpty(execute(selectSecondRowCql));
 
+            // reload the base cfs and verify queries still work as expected
+            getCurrentColumnFamilyStore().reload();
+            assertRows(execute(selectFirstRowCql), firstRow);
+            assertEmpty(execute(selectSecondRowCql));
+
             // drop the index and assert we can no longer query using it
             execute(dropIndexCql);
             assertInvalidThrowMessage(missingIndexMessage, 
InvalidRequestException.class, selectFirstRowCql);
+            // reload the base cfs and verify again
+            getCurrentColumnFamilyStore().reload();
+            assertInvalidThrowMessage(missingIndexMessage, 
InvalidRequestException.class, selectFirstRowCql);
+
             flush();
             compact();
 

Reply via email to