You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by bl...@apache.org on 2016/07/14 07:43:20 UTC

cassandra git commit: Optimize RestrictionSet

Repository: cassandra
Updated Branches:
  refs/heads/trunk da995b72e -> 677aaf0f7


Optimize RestrictionSet

patch by Benjamin Lerer; reviewed by Tyler Hobbs for CASSANDRA-12153


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

Branch: refs/heads/trunk
Commit: 677aaf0f7916f2f23108d378e20859c0aae4d913
Parents: da995b7
Author: Benjamin Lerer <b....@gmail.com>
Authored: Thu Jul 14 09:41:51 2016 +0200
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Thu Jul 14 09:41:51 2016 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../ClusteringColumnRestrictions.java           | 14 +++-
 .../cql3/restrictions/RestrictionSet.java       | 88 +++++++++++++++-----
 3 files changed, 79 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/677aaf0f/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index f63bd2b..808b91e 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.10
+ * Optimize RestrictionSet (CASSANDRA-12153)
  * cqlsh does not automatically downgrade CQL version (CASSANDRA-12150)
  * Omit (de)serialization of state variable in UDAs (CASSANDRA-9613)
  * Create a system table to expose prepared statements (CASSANDRA-8831)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/677aaf0f/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java
index dc349d9..8e2d744 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java
@@ -152,7 +152,12 @@ final class ClusteringColumnRestrictions extends RestrictionSetWrapper
      */
     public final boolean hasContains()
     {
-        return restrictions.stream().anyMatch(SingleRestriction::isContains);
+        for (SingleRestriction restriction : restrictions)
+        {
+            if (restriction.isContains())
+                return true;
+        }
+        return false;
     }
 
     /**
@@ -163,7 +168,12 @@ final class ClusteringColumnRestrictions extends RestrictionSetWrapper
      */
     public final boolean hasSlice()
     {
-        return restrictions.stream().anyMatch(SingleRestriction::isSlice);
+        for (SingleRestriction restriction : restrictions)
+        {
+            if (restriction.isSlice())
+                return true;
+        }
+        return false;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/677aaf0f/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java b/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
index 2648f62..bb943d5 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
@@ -18,7 +18,8 @@
 package org.apache.cassandra.cql3.restrictions;
 
 import java.util.*;
-import java.util.stream.Stream;
+
+import com.google.common.collect.AbstractIterator;
 
 import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.cql3.QueryOptions;
@@ -53,14 +54,21 @@ final class RestrictionSet implements Restrictions, Iterable<SingleRestriction>
      */
     protected final TreeMap<ColumnDefinition, SingleRestriction> restrictions;
 
+    /**
+     * {@code true} if it contains multi-column restrictions, {@code false} otherwise.
+     */
+    private final boolean hasMultiColumnRestrictions;
+
     public RestrictionSet()
     {
-        this(new TreeMap<ColumnDefinition, SingleRestriction>(COLUMN_DEFINITION_COMPARATOR));
+        this(new TreeMap<ColumnDefinition, SingleRestriction>(COLUMN_DEFINITION_COMPARATOR), false);
     }
 
-    private RestrictionSet(TreeMap<ColumnDefinition, SingleRestriction> restrictions)
+    private RestrictionSet(TreeMap<ColumnDefinition, SingleRestriction> restrictions,
+                           boolean hasMultiColumnRestrictions)
     {
         this.restrictions = restrictions;
+        this.hasMultiColumnRestrictions = hasMultiColumnRestrictions;
     }
 
     @Override
@@ -76,24 +84,11 @@ final class RestrictionSet implements Restrictions, Iterable<SingleRestriction>
         return new ArrayList<>(restrictions.keySet());
     }
 
-    public Stream<SingleRestriction> stream()
-    {
-        return new LinkedHashSet<>(restrictions.values()).stream();
-    }
-
     @Override
     public void addFunctionsTo(List<Function> functions)
     {
-        Restriction previous = null;
-        for (Restriction restriction : restrictions.values())
-        {
-            // For muti-column restriction, we can have multiple time the same restriction.
-            if (!restriction.equals(previous))
-            {
-                previous = restriction;
-                restriction.addFunctionsTo(functions);
-            }
-        }
+        for (Restriction restriction : this)
+            restriction.addFunctionsTo(functions);
     }
 
     @Override
@@ -118,7 +113,7 @@ final class RestrictionSet implements Restrictions, Iterable<SingleRestriction>
     {
         // RestrictionSet is immutable so we need to clone the restrictions map.
         TreeMap<ColumnDefinition, SingleRestriction> newRestrictions = new TreeMap<>(this.restrictions);
-        return new RestrictionSet(mergeRestrictions(newRestrictions, restriction));
+        return new RestrictionSet(mergeRestrictions(newRestrictions, restriction), hasMultiColumnRestrictions || restriction.isMultiColumn());
     }
 
     private TreeMap<ColumnDefinition, SingleRestriction> mergeRestrictions(TreeMap<ColumnDefinition, SingleRestriction> restrictions,
@@ -246,7 +241,8 @@ final class RestrictionSet implements Restrictions, Iterable<SingleRestriction>
     @Override
     public Iterator<SingleRestriction> iterator()
     {
-        return new LinkedHashSet<>(restrictions.values()).iterator();
+        Iterator<SingleRestriction> iterator = restrictions.values().iterator();
+        return hasMultiColumnRestrictions ? new DistinctIterator<>(iterator) : iterator;
     }
 
     /**
@@ -255,7 +251,12 @@ final class RestrictionSet implements Restrictions, Iterable<SingleRestriction>
      */
     public final boolean hasIN()
     {
-        return stream().anyMatch(SingleRestriction::isIN);
+        for (SingleRestriction restriction : this)
+        {
+            if (restriction.isIN())
+                return true;
+        }
+        return false;
     }
 
     /**
@@ -266,6 +267,49 @@ final class RestrictionSet implements Restrictions, Iterable<SingleRestriction>
      */
     public final boolean hasOnlyEqualityRestrictions()
     {
-        return stream().allMatch(p -> p.isEQ() || p.isIN());
+        for (SingleRestriction restriction : this)
+        {
+            if (!restriction.isEQ() && !restriction.isIN())
+                return false;
+        }
+        return true;
+    }
+
+    /**
+     * {@code Iterator} decorator that removes duplicates in an ordered one.
+     *
+     * @param iterator the decorated iterator
+     * @param <E> the iterator element type.
+     */
+    private static final class DistinctIterator<E> extends AbstractIterator<E>
+    {
+        /**
+         * The decorated iterator.
+         */
+        private final Iterator<E> iterator;
+
+        /**
+         * The previous element.
+         */
+        private E previous;
+
+        public DistinctIterator(Iterator<E> iterator)
+        {
+            this.iterator = iterator;
+        }
+
+        protected E computeNext()
+        {
+            while(iterator.hasNext())
+            {
+                E next = iterator.next();
+                if (!next.equals(previous))
+                {
+                    previous = next;
+                    return next;
+                }
+            }
+            return endOfData();
+        }
     }
 }