You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by to...@apache.org on 2015/06/18 19:06:19 UTC

incubator-usergrid git commit: Comparators partially implemented.

Repository: incubator-usergrid
Updated Branches:
  refs/heads/USERGRID-752 bb2837caa -> d62cdcacf


Comparators partially implemented.


Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/d62cdcac
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/d62cdcac
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/d62cdcac

Branch: refs/heads/USERGRID-752
Commit: d62cdcacf176600011964d5e69c71202e2b22c4c
Parents: bb2837c
Author: Todd Nine <tn...@apigee.com>
Authored: Thu Jun 18 11:06:17 2015 -0600
Committer: Todd Nine <tn...@apigee.com>
Committed: Thu Jun 18 11:06:17 2015 -0600

----------------------------------------------------------------------
 .../persistence/query/ir/SearchVisitor.java     |   8 +-
 .../query/ir/result/AbstractScanColumn.java     |   6 +-
 .../query/ir/result/GatherIterator.java         |  49 +++--
 .../ir/result/SecondaryIndexSliceParser.java    | 180 +++++++++++++++++--
 4 files changed, 211 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/d62cdcac/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/SearchVisitor.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/SearchVisitor.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/SearchVisitor.java
index 410b99f..271fc67 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/SearchVisitor.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/SearchVisitor.java
@@ -49,8 +49,6 @@ import org.apache.usergrid.persistence.query.ir.result.UnionIterator;
  */
 public abstract class SearchVisitor implements NodeVisitor {
 
-    private static final SecondaryIndexSliceParser COLLECTION_PARSER = new SecondaryIndexSliceParser();
-
     protected final Query query;
 
     protected final QueryProcessor queryProcessor;
@@ -211,7 +209,7 @@ public abstract class SearchVisitor implements NodeVisitor {
             if ( subResults == null ) {
                 QuerySlice firstFieldSlice = new QuerySlice( slice.getPropertyName(), -1 );
                 subResults =
-                        new SliceIterator( slice, secondaryIndexScan( orderByNode, firstFieldSlice ), COLLECTION_PARSER );
+                        new SliceIterator( slice, secondaryIndexScan( orderByNode, firstFieldSlice ), new SecondaryIndexSliceParser() );
             }
 
             orderIterator = new OrderByIterator( slice, orderByNode.getSecondarySorts(), subResults, em,
@@ -230,7 +228,7 @@ public abstract class SearchVisitor implements NodeVisitor {
                 scanner = secondaryIndexScan( orderByNode, slice );
             }
 
-            SliceIterator joinSlice = new SliceIterator( slice, scanner, COLLECTION_PARSER);
+            SliceIterator joinSlice = new SliceIterator( slice, scanner, new SecondaryIndexSliceParser());
 
             IntersectionIterator union = new IntersectionIterator( queryProcessor.getPageSizeHint( orderByNode ) );
             union.addIterator( joinSlice );
@@ -261,7 +259,7 @@ public abstract class SearchVisitor implements NodeVisitor {
         for ( QuerySlice slice : node.getAllSlices() ) {
             IndexScanner scanner = secondaryIndexScan( node, slice );
 
-            intersections.addIterator( new SliceIterator( slice, scanner, COLLECTION_PARSER) );
+            intersections.addIterator( new SliceIterator( slice, scanner, new SecondaryIndexSliceParser()) );
         }
 
         results.push( intersections );

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/d62cdcac/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/AbstractScanColumn.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/AbstractScanColumn.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/AbstractScanColumn.java
index 383ead7..d5d130e 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/AbstractScanColumn.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/AbstractScanColumn.java
@@ -30,9 +30,9 @@ import org.apache.cassandra.utils.ByteBufferUtil;
  */
 public abstract class AbstractScanColumn implements ScanColumn {
 
-    private final UUID uuid;
-    private final ByteBuffer buffer;
-    private ScanColumn child;
+    protected final UUID uuid;
+    protected final ByteBuffer buffer;
+    protected ScanColumn child;
 
 
     protected AbstractScanColumn( final UUID uuid, final ByteBuffer columnNameBuffer ) {

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/d62cdcac/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/GatherIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/GatherIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/GatherIterator.java
index 29912cc..b91f3bc 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/GatherIterator.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/GatherIterator.java
@@ -1,9 +1,11 @@
 package org.apache.usergrid.persistence.query.ir.result;
 
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.Set;
 import java.util.TreeSet;
@@ -21,18 +23,18 @@ import org.apache.usergrid.persistence.query.ir.SearchVisitor;
 public class GatherIterator implements ResultIterator {
 
 
-    private final Collection<SearchVisitor> searchVisitors;
     private final QueryNode rootNode;
     private final int pageSize;
 
 
     private Set<ScanColumn> next;
+    private List<ResultIterator> iterators;
 
 
     public GatherIterator(final int pageSize, final QueryNode rootNode, final Collection<SearchVisitor> searchVisitors) {
         this.pageSize = pageSize;
         this.rootNode = rootNode;
-        this.searchVisitors = searchVisitors;
+        createIterators(searchVisitors);
     }
 
 
@@ -56,8 +58,7 @@ public class GatherIterator implements ResultIterator {
 
     @Override
     public boolean hasNext() {
-
-        if(next() == null){
+        if(next == null){
             advance();
         }
 
@@ -76,33 +77,55 @@ public class GatherIterator implements ResultIterator {
         return results;
     }
 
+    private void createIterators(final Collection<SearchVisitor> searchVisitors ){
+
+        this.iterators = new ArrayList<ResultIterator>( searchVisitors.size() );
+
+        for(SearchVisitor visitor: searchVisitors){
+
+            try {
+                rootNode.visit( visitor );
+            }
+            catch ( Exception e ) {
+                throw new RuntimeException( "Unable to process query", e );
+            }
+
+            final ResultIterator iterator = visitor.getResults();
+
+            iterators.add( iterator );
+
+        }
+
+    }
 
     /**
      * Advance the iterator
      */
     private void advance(){
         //TODO make this concurrent
-
-
         final TreeSet<ScanColumn> results = new TreeSet<ScanColumn>(  );
 
 
-        for(SearchVisitor visitor: searchVisitors){
-              merge(results, visitor);
+        for(ResultIterator iterator: this.iterators){
+              merge(results, iterator);
         }
 
-        this.next = results;
+        if(results.size() == 0){
+            this.next = null;
+        }else {
+            this.next = results;
+        }
     }
 
 
+
+
     /**
      * Merge this interator into our final column results
      * @param results
-     * @param visitor
+     * @param iterator
      */
-    private void merge(final TreeSet<ScanColumn> results, final SearchVisitor visitor){
-
-        final ResultIterator iterator = visitor.getResults();
+    private void merge(final TreeSet<ScanColumn> results, final ResultIterator iterator){
 
 
         //nothing to do, return

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/d62cdcac/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java
index e27d99c..3d8f073 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java
@@ -19,33 +19,69 @@ package org.apache.usergrid.persistence.query.ir.result;
 
 import java.nio.ByteBuffer;
 import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.UUID;
 
+import com.fasterxml.uuid.UUIDComparator;
+
 import me.prettyprint.hector.api.beans.DynamicComposite;
 
 
 /**
- * Parser for reading and writing secondary index composites
+ * Parser for reading and writing secondary index composites.  Instances of this class should not be shared among
+ * iterators.
+ *
+ * It it designed with the following assumptions in mind.
+ *
+ * 1) The slice contains the same data type for every element 2) Evaluating the first parse call for a comparator is
+ * sufficient for subsequent use
  *
  * @author tnine
  */
 public class SecondaryIndexSliceParser implements SliceParser {
 
+    //the type comparator
+    private Comparator<Object> typeComparator;
+
+
+    public SecondaryIndexSliceParser() {}
+
 
     /* (non-Javadoc)
      * @see org.apache.usergrid.persistence.query.ir.result.SliceParser#parse(java.nio.ByteBuffer)
      */
     @Override
-    public ScanColumn parse( ByteBuffer buff, final boolean isReversed) {
-        DynamicComposite composite = DynamicComposite.fromByteBuffer( buff.duplicate() );
+    public ScanColumn parse( ByteBuffer buff, final boolean isReversed ) {
+        final DynamicComposite composite = DynamicComposite.fromByteBuffer( buff.duplicate() );
+
+        final UUID uuid = ( UUID ) composite.get( 2 );
+        final Object value = composite.get( 1 );
 
-        throw new UnsupportedOperationException( "Implement me with static comparators" );
+        if ( typeComparator == null ) {
+            typeComparator = getTypeComparator( value, isReversed );
+        }
 
-//        return new SecondaryIndexColumn( ( UUID ) composite.get( 2 ), composite.get( 1 ), buff, null );
+        return new SecondaryIndexColumn( uuid, value, buff, typeComparator );
     }
 
 
+    private Comparator<Object> getTypeComparator( final Object value, final boolean isReversed ) {
 
+        final Class clazz = value.getClass();
+        final Comparator<Object> comparator = COMPARATOR_MAP.get( new MapKey( clazz, isReversed ) );
+
+        if ( comparator == null ) {
+            throw new NullPointerException( "comparator was not found for runtime type '" + clazz + "'" );
+        }
+
+        return comparator;
+    }
+
+
+    /**
+     * Column for our secondary index type
+     */
     public static class SecondaryIndexColumn extends AbstractScanColumn {
 
         private final Object value;
@@ -54,13 +90,11 @@ public class SecondaryIndexSliceParser implements SliceParser {
 
         /**
          * Create the secondary index column
-         * @param uuid
-         * @param value
-         * @param columnNameBuffer
+         *
          * @param valueComparator The comparator for the values
          */
         public SecondaryIndexColumn( final UUID uuid, final Object value, final ByteBuffer columnNameBuffer,
-                                  final Comparator<Object> valueComparator ) {
+                                     final Comparator<Object> valueComparator ) {
             super( uuid, columnNameBuffer );
             this.value = value;
             this.valueComparator = valueComparator;
@@ -74,8 +108,132 @@ public class SecondaryIndexSliceParser implements SliceParser {
 
 
         @Override
-        public int compareTo( final ScanColumn o ) {
-            throw new UnsupportedOperationException( "Impelment me" );
+        public int compareTo( final ScanColumn other ) {
+            if ( other == null ) {
+                return 1;
+            }
+
+            final int compare =  valueComparator.compare( value, ( ( SecondaryIndexColumn ) other ).value );
+
+            //same value, compare uuids
+            if(compare == 0){
+                return com.fasterxml.uuid.UUIDComparator.staticCompare( uuid, ( ( SecondaryIndexColumn ) other ).uuid );
+            }
+
+            return compare;
+        }
+    }
+
+
+
+
+    private static final Map<MapKey, Comparator<Object>> COMPARATOR_MAP = new HashMap<MapKey, Comparator<Object>>();
+
+    static {
+
+        final LongComparator longComparator = new LongComparator();
+        COMPARATOR_MAP.put( new MapKey( Long.class, false ), longComparator );
+        COMPARATOR_MAP.put( new MapKey( Long.class, true ), new ReverseComparator( longComparator ) );
+
+        final StringComparator stringComparator = new StringComparator();
+
+        COMPARATOR_MAP.put( new MapKey( String.class, false ), stringComparator );
+        COMPARATOR_MAP.put( new MapKey( String.class, true ), new ReverseComparator( stringComparator ) );
+
+
+        final UUIDComparator uuidComparator = new UUIDComparator();
+
+        COMPARATOR_MAP.put( new MapKey( UUID.class, false ), uuidComparator );
+        COMPARATOR_MAP.put( new MapKey( UUID.class, true ), new ReverseComparator( uuidComparator ) );
+    }
+
+
+    /**
+     * The key for the map
+     */
+    private static final class MapKey {
+        public final Class<?> clazz;
+        public final boolean reversed;
+
+
+        private MapKey( final Class<?> clazz, final boolean reversed ) {
+            this.clazz = clazz;
+            this.reversed = reversed;
+        }
+
+
+        @Override
+        public boolean equals( final Object o ) {
+            if ( this == o ) {
+                return true;
+            }
+            if ( !( o instanceof MapKey ) ) {
+                return false;
+            }
+
+            final MapKey mapKey = ( MapKey ) o;
+
+            if ( reversed != mapKey.reversed ) {
+                return false;
+            }
+            return clazz.equals( mapKey.clazz );
+        }
+
+
+        @Override
+        public int hashCode() {
+            int result = clazz.hashCode();
+            result = 31 * result + ( reversed ? 1 : 0 );
+            return result;
+        }
+    }
+
+
+
+
+    private static final class LongComparator implements Comparator<Object> {
+
+        @Override
+        public int compare( final Object first, final Object second ) {
+            return Long.compare( ( Long ) first, ( Long ) second );
+        }
+    }
+
+
+    private static final class StringComparator implements Comparator<Object> {
+        @Override
+        public int compare( final Object first, final Object second ) {
+            if ( first == null && second != null ) {
+                return -1;
+            }
+
+            return ( ( String ) first ).compareTo( ( String ) second );
+        }
+    }
+
+
+    private static final class UUIDComparator implements Comparator<Object> {
+        @Override
+        public int compare( final Object first, final Object second ) {
+            return ( ( UUID ) first ).compareTo( ( UUID ) second );
+        }
+    }
+
+
+    /**
+     * Reversed our comparator
+     */
+    private static final class ReverseComparator implements Comparator<Object> {
+
+        private final Comparator<Object> comparator;
+
+
+        private ReverseComparator( final Comparator<Object> comparator ) {this.comparator = comparator;}
+
+
+        @Override
+        public int compare( final Object first, final Object second ) {
+            return comparator.compare( first, second ) * -1;
         }
     }
 }