You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sa...@apache.org on 2015/10/02 18:08:48 UTC
[3/4] cassandra git commit: Fix index selectivity comparison
Fix index selectivity comparison
Patch by Sam Tunnicliffe; reviewed by Sylvain Lebresne for
CASSANDRA-10435
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/2d472370
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/2d472370
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/2d472370
Branch: refs/heads/cassandra-3.0
Commit: 2d472370b4a6dbf5c6c6f892b9036ef027842dbf
Parents: 30e14a3
Author: Sam Tunnicliffe <sa...@beobal.com>
Authored: Fri Oct 2 12:08:36 2015 +0100
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 2 17:05:42 2015 +0100
----------------------------------------------------------------------
.../cassandra/index/SecondaryIndexManager.java | 7 +--
.../apache/cassandra/index/CustomIndexTest.java | 56 ++++++++++++++++++++
2 files changed, 60 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2d472370/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 3daf147..b04de2a 100644
--- a/src/java/org/apache/cassandra/index/SecondaryIndexManager.java
+++ b/src/java/org/apache/cassandra/index/SecondaryIndexManager.java
@@ -27,6 +27,7 @@ import java.util.stream.Stream;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.primitives.Longs;
import com.google.common.util.concurrent.Futures;
@@ -579,7 +580,7 @@ public class SecondaryIndexManager implements IndexRegistry
if (indexes.isEmpty() || command.rowFilter().isEmpty())
return null;
- List<Index> searchableIndexes = new ArrayList<>();
+ Set<Index> searchableIndexes = new HashSet<>();
for (RowFilter.Expression expression : command.rowFilter())
{
if (expression.isCustom())
@@ -603,9 +604,9 @@ public class SecondaryIndexManager implements IndexRegistry
}
Index selected = searchableIndexes.size() == 1
- ? searchableIndexes.get(0)
+ ? Iterables.getOnlyElement(searchableIndexes)
: searchableIndexes.stream()
- .max((a, b) -> Longs.compare(a.getEstimatedResultRows(),
+ .min((a, b) -> Longs.compare(a.getEstimatedResultRows(),
b.getEstimatedResultRows()))
.orElseThrow(() -> new AssertionError("Could not select most selective index"));
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2d472370/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 40fb526..ceff839 100644
--- a/test/unit/org/apache/cassandra/index/CustomIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/CustomIndexTest.java
@@ -374,6 +374,35 @@ public class CustomIndexTest extends CQLTester
"UPDATE %s SET d=0 WHERE expr(custom_index, 'foo bar baz ')");
}
+ @Test
+ public void indexSelectionPrefersMostSelectiveIndex() throws Throwable
+ {
+ createTable("CREATE TABLE %s(a int, b int, c int, PRIMARY KEY (a))");
+ createIndex(String.format("CREATE CUSTOM INDEX more_selective ON %%s(b) USING '%s'",
+ SettableSelectivityIndex.class.getName()));
+ createIndex(String.format("CREATE CUSTOM INDEX less_selective ON %%s(c) USING '%s'",
+ SettableSelectivityIndex.class.getName()));
+ SettableSelectivityIndex moreSelective =
+ (SettableSelectivityIndex)getCurrentColumnFamilyStore().indexManager.getIndexByName("more_selective");
+ SettableSelectivityIndex lessSelective =
+ (SettableSelectivityIndex)getCurrentColumnFamilyStore().indexManager.getIndexByName("less_selective");
+ assertEquals(0, moreSelective.searchersProvided);
+ assertEquals(0, lessSelective.searchersProvided);
+
+ // the more selective index should be chosen
+ moreSelective.setEstimatedResultRows(1);
+ lessSelective.setEstimatedResultRows(1000);
+ execute("SELECT * FROM %s WHERE b=0 AND c=0 ALLOW FILTERING");
+ assertEquals(1, moreSelective.searchersProvided);
+ assertEquals(0, lessSelective.searchersProvided);
+
+ // and adjusting the selectivity should have an observable effect
+ moreSelective.setEstimatedResultRows(10000);
+ execute("SELECT * FROM %s WHERE b=0 AND c=0 ALLOW FILTERING");
+ assertEquals(1, moreSelective.searchersProvided);
+ assertEquals(1, lessSelective.searchersProvided);
+ }
+
private void testCreateIndex(String indexName, String... targetColumnNames) throws Throwable
{
createIndex(String.format("CREATE CUSTOM INDEX %s ON %%s(%s) USING '%s'",
@@ -430,6 +459,33 @@ public class CustomIndexTest extends CQLTester
}
}
+ public static final class SettableSelectivityIndex extends StubIndex
+ {
+ private int searchersProvided = 0;
+ private long estimatedResultRows = 0;
+
+ public SettableSelectivityIndex(ColumnFamilyStore baseCfs, IndexMetadata metadata)
+ {
+ super(baseCfs, metadata);
+ }
+
+ public void setEstimatedResultRows(long estimate)
+ {
+ estimatedResultRows = estimate;
+ }
+
+ public long getEstimatedResultRows()
+ {
+ return estimatedResultRows;
+ }
+
+ public Searcher searcherFor(ReadCommand command)
+ {
+ searchersProvided++;
+ return super.searcherFor(command);
+ }
+ }
+
public static final class IndexExcludedFromBuild extends StubIndex
{
public IndexExcludedFromBuild(ColumnFamilyStore baseCfs, IndexMetadata metadata)