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;
}
}
}