You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2015/07/30 19:19:43 UTC
[05/25] incubator-usergrid git commit: Comparators partially
implemented.
Comparators partially implemented.
Merges iterators. Paging still incomplete.
Merges iterators. Paging still incomplete.
WIP overwrite
WIP overwrite
Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/68c7eae1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/68c7eae1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/68c7eae1
Branch: refs/heads/master
Commit: 68c7eae1eb4409b067c8f3c3e4923b6b5e5a8e86
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 25 11:14:49 2015 -0600
----------------------------------------------------------------------
.../persistence/cassandra/CassandraService.java | 42 ++--
.../persistence/cassandra/QueryProcessor.java | 15 +-
.../cassandra/index/ConnectedIndexScanner.java | 4 +-
.../index/DynamicCompositeStartToBytes.java | 48 ++++
.../cassandra/index/IndexBucketScanner.java | 81 +++++--
.../cassandra/index/StartToBytes.java | 34 +++
.../cassandra/index/UUIDStartToBytes.java | 41 ++++
.../persistence/query/ir/SearchVisitor.java | 10 +-
.../query/ir/result/AbstractScanColumn.java | 32 +--
.../query/ir/result/GatherIterator.java | 111 +++++++---
.../ir/result/SearchCollectionVisitor.java | 14 +-
.../ir/result/SearchConnectionVisitor.java | 3 +-
.../ir/result/SecondaryIndexSliceParser.java | 220 ++++++++++++++++++-
.../query/ir/result/SliceIterator.java | 17 +-
.../persistence/query/ir/result/UUIDColumn.java | 36 +--
.../query/ir/result/UUIDIndexSliceParser.java | 2 +-
.../query/ir/result/UnionIterator.java | 18 +-
.../usergrid/persistence/CollectionIT.java | 2 +-
18 files changed, 552 insertions(+), 178 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java
index 58d5d0f..12ea338 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java
@@ -39,6 +39,7 @@ import org.apache.usergrid.persistence.IndexBucketLocator;
import org.apache.usergrid.persistence.IndexBucketLocator.IndexType;
import org.apache.usergrid.persistence.cassandra.index.IndexBucketScanner;
import org.apache.usergrid.persistence.cassandra.index.IndexScanner;
+import org.apache.usergrid.persistence.cassandra.index.UUIDStartToBytes;
import org.apache.usergrid.persistence.hector.CountingMutator;
import me.prettyprint.cassandra.connection.HConnectionManager;
@@ -1027,29 +1028,27 @@ public class CassandraService {
*
* @throws Exception the exception
*/
- public IndexScanner getIdList( Keyspace ko, Object key, UUID start, UUID finish, int count, boolean reversed,
- IndexBucketLocator locator, UUID applicationId, String collectionName, boolean keepFirst )
+ public IndexScanner getIdList( Object key, UUID start, UUID finish, int count, boolean reversed,
+ final String bucket, UUID applicationId, boolean keepFirst )
throws Exception {
- //TODO, refactor this
- throw new UnsupportedOperationException( "Implement me" );
-
- // if ( count <= 0 ) {
- // count = DEFAULT_COUNT;
- // }
- //
- // if ( NULL_ID.equals( start ) ) {
- // start = null;
- // }
- //
- //
- // final boolean skipFirst = start != null && !keepFirst;
- //
- // IndexScanner scanner =
- // new IndexBucketScanner( this, locator, ENTITY_ID_SETS, applicationId, IndexType.COLLECTION, key, start,
- // finish, reversed, count, skipFirst, collectionName );
- //
- // return scanner;
+ if ( count <= 0 ) {
+ count = DEFAULT_COUNT;
+ }
+
+ if ( NULL_ID.equals( start ) ) {
+ start = null;
+ }
+
+
+ final boolean skipFirst = start != null && !keepFirst;
+
+
+ IndexScanner scanner =
+ new IndexBucketScanner<UUID>( this, ENTITY_ID_SETS, UUIDStartToBytes.INSTANCE, applicationId, key, bucket, start,
+ finish, reversed, count, skipFirst );
+
+ return scanner;
}
@@ -1064,4 +1063,5 @@ public class CassandraService {
}
cluster = null;
}
+
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/QueryProcessor.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/QueryProcessor.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/QueryProcessor.java
index f55aa67..ebaacf4 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/QueryProcessor.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/QueryProcessor.java
@@ -448,7 +448,7 @@ public class QueryProcessor {
node = newSliceNode();
}
else {
- node = getUnionNode( op );
+ node = getUnionNode( );
}
String fieldName = op.getProperty().getIndexedValue();
@@ -485,7 +485,7 @@ public class QueryProcessor {
checkIndexed( propertyName );
- getUnionNode( op ).setFinish( propertyName, op.getLiteral().getValue(), false );
+ getUnionNode( ).setFinish( propertyName, op.getLiteral().getValue(), false );
}
@@ -502,7 +502,7 @@ public class QueryProcessor {
checkIndexed( propertyName );
- getUnionNode( op ).setFinish( propertyName, op.getLiteral().getValue(), true );
+ getUnionNode( ).setFinish( propertyName, op.getLiteral().getValue(), true );
}
@@ -519,7 +519,7 @@ public class QueryProcessor {
//checkIndexed( fieldName );
Literal<?> literal = op.getLiteral();
- SliceNode node = getUnionNode( op );
+ SliceNode node = getUnionNode( );
// this is an edge case. If we get more edge cases, we need to push
// this down into the literals and let the objects
@@ -554,7 +554,7 @@ public class QueryProcessor {
checkIndexed( propertyName );
- getUnionNode( op ).setStart( propertyName, op.getLiteral().getValue(), false );
+ getUnionNode( ).setStart( propertyName, op.getLiteral().getValue(), false );
}
@@ -570,7 +570,7 @@ public class QueryProcessor {
checkIndexed( propertyName );
- getUnionNode( op ).setStart( propertyName, op.getLiteral().getValue(), true );
+ getUnionNode( ).setStart( propertyName, op.getLiteral().getValue(), true );
}
@@ -578,9 +578,8 @@ public class QueryProcessor {
* Return the current leaf node to add to if it exists. This means that we can compress multiple 'AND'
* operations and ranges into a single node. Otherwise a new node is created and pushed to the stack
*
- * @param current The current operand node
*/
- private SliceNode getUnionNode( EqualityOperand current ) {
+ private SliceNode getUnionNode( ) {
/**
* we only create a new slice node in 3 situations 1. No nodes exist 2.
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/ConnectedIndexScanner.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/ConnectedIndexScanner.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/ConnectedIndexScanner.java
index 87726cb..6c6152a 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/ConnectedIndexScanner.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/ConnectedIndexScanner.java
@@ -174,11 +174,11 @@ public class ConnectedIndexScanner implements IndexScanner {
}
//remove the first element, we need to skip it
- if ( skipFirst && lastResults.size() > 0) {
+ if ( skipFirst && lastResults != null && lastResults.size() > 0) {
lastResults.remove( 0 );
}
- if ( hasMore && lastResults.size() > 0 ) {
+ if ( hasMore && lastResults !=null && lastResults.size() > 0 ) {
// set the bytebuffer for the next pass
lastResults.remove( lastResults.size() - 1 );
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/DynamicCompositeStartToBytes.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/DynamicCompositeStartToBytes.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/DynamicCompositeStartToBytes.java
new file mode 100644
index 0000000..072e8ca
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/DynamicCompositeStartToBytes.java
@@ -0,0 +1,48 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one or more
+ * * contributor license agreements. See the NOTICE file distributed with
+ * * this work for additional information regarding copyright ownership.
+ * * The ASF licenses this file to You under the Apache License, Version 2.0
+ * * (the "License"); you may not use this file except in compliance with
+ * * the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ *
+ */
+package org.apache.usergrid.persistence.cassandra.index;
+
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+import me.prettyprint.cassandra.serializers.UUIDSerializer;
+import me.prettyprint.hector.api.beans.DynamicComposite;
+
+
+/**
+ * Converts a DynamicComposite to bytes
+ */
+public class DynamicCompositeStartToBytes implements StartToBytes<DynamicComposite> {
+
+ public static final DynamicCompositeStartToBytes INSTANCE = new DynamicCompositeStartToBytes();
+
+ private DynamicCompositeStartToBytes(){}
+
+
+ @Override
+ public ByteBuffer toBytes( final DynamicComposite toBytes ) {
+
+ if(toBytes == null){
+ return null;
+ }
+
+ return toBytes.serialize();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/IndexBucketScanner.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/IndexBucketScanner.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/IndexBucketScanner.java
index e568575..bf61846 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/IndexBucketScanner.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/IndexBucketScanner.java
@@ -18,19 +18,16 @@ package org.apache.usergrid.persistence.cassandra.index;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.NavigableSet;
-import java.util.Set;
-import java.util.TreeSet;
import java.util.UUID;
-import org.apache.usergrid.persistence.IndexBucketLocator;
-import org.apache.usergrid.persistence.IndexBucketLocator.IndexType;
+import org.apache.cassandra.utils.FBUtilities;
+
import org.apache.usergrid.persistence.cassandra.ApplicationCF;
import org.apache.usergrid.persistence.cassandra.CassandraService;
+import com.google.common.primitives.UnsignedBytes;
import com.yammer.metrics.annotation.Metered;
import me.prettyprint.hector.api.beans.HColumn;
@@ -44,7 +41,7 @@ import static org.apache.usergrid.persistence.cassandra.CassandraPersistenceUtil
*
* @author tnine
*/
-public class IndexBucketScanner implements IndexScanner {
+public class IndexBucketScanner<T> implements IndexScanner {
private final CassandraService cass;
private final UUID applicationId;
@@ -55,12 +52,13 @@ public class IndexBucketScanner implements IndexScanner {
private final int pageSize;
private final boolean skipFirst;
private final String bucket;
+ private final StartToBytes<T> scanStartSerializer;
/** Pointer to our next start read */
- private Object start;
+ private ByteBuffer start;
/** Set to the original value to start scanning from */
- private Object scanStart;
+ private T initialStartValue;
/** Iterator for our results from the last page load */
private List<HColumn<ByteBuffer, ByteBuffer>> lastResults;
@@ -70,14 +68,14 @@ public class IndexBucketScanner implements IndexScanner {
- public IndexBucketScanner( CassandraService cass, ApplicationCF columnFamily,
- UUID applicationId, Object keyPrefix, String bucket, Object start, Object finish,
+ public IndexBucketScanner( CassandraService cass, ApplicationCF columnFamily, StartToBytes<T> scanStartSerializer,
+ UUID applicationId, Object keyPrefix, String bucket, T start, T finish,
boolean reversed, int pageSize, boolean skipFirst) {
this.cass = cass;
+ this.scanStartSerializer = scanStartSerializer;
this.applicationId = applicationId;
this.keyPrefix = keyPrefix;
this.columnFamily = columnFamily;
- this.start = start;
this.finish = finish;
this.reversed = reversed;
this.skipFirst = skipFirst;
@@ -85,7 +83,10 @@ public class IndexBucketScanner implements IndexScanner {
//we always add 1 to the page size. This is because we pop the last column for the next page of results
this.pageSize = pageSize+1;
- this.scanStart = start;
+
+ //the initial value set when we started scanning
+ this.initialStartValue = start;
+ this.start = scanStartSerializer.toBytes( initialStartValue );
}
@@ -95,7 +96,7 @@ public class IndexBucketScanner implements IndexScanner {
@Override
public void reset() {
hasMore = true;
- start = scanStart;
+ start = scanStartSerializer.toBytes( initialStartValue );
}
@@ -122,12 +123,10 @@ public class IndexBucketScanner implements IndexScanner {
//we purposefully use instance equality. If it's a pointer to the same value, we need to increase by 1
//since we'll be skipping the first value
- final boolean firstPageSkipFirst = this.skipFirst && start == scanStart;
-
- if(firstPageSkipFirst){
- selectSize++;
- }
+ final boolean shouldCheckFirst =
+ //we should skip the value it's a cursor resume OR it's a previous page from a stateful iterator
+ (this.skipFirst && initialStartValue != null) || start != null;
final List<HColumn<ByteBuffer, ByteBuffer>>
resultsTree = cass.getColumns( cass.getApplicationKeyspace( applicationId ), columnFamily, rowKey,
@@ -140,7 +139,6 @@ public class IndexBucketScanner implements IndexScanner {
if ( resultsTree.size() == selectSize ) {
hasMore = true;
-
// set the bytebuffer for the next pass
start = resultsTree.get( resultsTree.size() - 1 ).getName();
}
@@ -149,8 +147,25 @@ public class IndexBucketScanner implements IndexScanner {
}
//remove the first element since it needs to be skipped AFTER the size check. Otherwise it will fail
- if ( firstPageSkipFirst ) {
- resultsTree.remove( 0 );
+ //we only want to skip if our byte value are the same as our expected start. Since we aren't stateful you can't
+ //be sure your start even comes back, and you don't want to erroneously remove columns
+ if ( shouldCheckFirst && resultsTree.size() > 0 && start != null) {
+ final int startIndex = start.position();
+ final int startLength = start.remaining();
+
+
+
+ final ByteBuffer returnedBuffer = resultsTree.get( 0 ).getName();
+ final int returnedIndex = returnedBuffer.position();
+ final int returnedLength = returnedBuffer.remaining();
+
+
+ final int compare = FBUtilities.compareUnsigned( start.array(), returnedBuffer.array(), startIndex, returnedIndex, startLength, returnedLength ) ;
+
+ //the byte buffers are the same as our seek (which may or may not be the case in the first seek)
+ if(compare == 0){
+ resultsTree.remove( 0 );
+ }
}
lastResults = resultsTree;
@@ -159,6 +174,27 @@ public class IndexBucketScanner implements IndexScanner {
}
+ /**
+ * Returns true if the 2 byte buffers contain the same bytes, false otherwise
+ * @param first
+ * @param second
+ * @return
+ */
+ private boolean compareBuffer(final ByteBuffer first, final ByteBuffer second){
+ int firstLength = first.remaining();
+ int firstPosition = first.position();
+
+ int secondLength = second.remaining();
+ int secondPosition = second.position();
+
+ final int compare = FBUtilities.compareUnsigned( first.array(), second.array(), firstPosition, secondPosition, firstLength, secondLength);
+
+ return compare == 0;
+
+
+ }
+
+
/*
* (non-Javadoc)
*
@@ -235,4 +271,5 @@ public class IndexBucketScanner implements IndexScanner {
public boolean isReversed() {
return this.reversed;
}
+
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/StartToBytes.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/StartToBytes.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/StartToBytes.java
new file mode 100644
index 0000000..c6516b8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/StartToBytes.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.usergrid.persistence.cassandra.index;
+
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * Parse our index values into byte buffer
+ */
+public interface StartToBytes<T> {
+
+ /**
+ * Convert the start scanning type to bytes
+ * @param toBytes
+ * @return
+ */
+ ByteBuffer toBytes(final T toBytes);
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/UUIDStartToBytes.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/UUIDStartToBytes.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/UUIDStartToBytes.java
new file mode 100644
index 0000000..2cdf9fd
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/index/UUIDStartToBytes.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.usergrid.persistence.cassandra.index;
+
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+import me.prettyprint.cassandra.serializers.UUIDSerializer;
+
+
+/**
+ * Converts a UUID to bytes
+ */
+public class UUIDStartToBytes implements StartToBytes<UUID> {
+
+ public static final UUIDStartToBytes INSTANCE = new UUIDStartToBytes();
+
+ private UUIDStartToBytes(){}
+
+ private static final UUIDSerializer UUID_SERIALIZER = UUIDSerializer.get();
+
+ @Override
+ public ByteBuffer toBytes( final UUID toBytes ) {
+ return UUID_SERIALIZER.toByteBuffer( toBytes );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/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..fc2df4d 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;
@@ -162,7 +160,7 @@ public abstract class SearchVisitor implements NodeVisitor {
final int nodeId = node.getId();
- UnionIterator union = new UnionIterator( queryProcessor.getPageSizeHint( node ), nodeId, queryProcessor.getCursorCache( nodeId ) );
+ UnionIterator union = new UnionIterator( queryProcessor.getPageSizeHint( node ), nodeId );
if ( left != null ) {
union.addIterator( left );
@@ -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/68c7eae1/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..2a359be 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 ) {
@@ -58,13 +58,13 @@ public abstract class AbstractScanColumn implements ScanColumn {
if ( this == o ) {
return true;
}
- if ( !( o instanceof AbstractScanColumn ) ) {
+ if ( !( o instanceof ScanColumn ) ) {
return false;
}
- AbstractScanColumn that = ( AbstractScanColumn ) o;
+ ScanColumn that = ( ScanColumn ) o;
- return uuid.equals( that.uuid );
+ return uuid.equals( that.getUUID() );
}
@@ -94,24 +94,4 @@ public abstract class AbstractScanColumn implements ScanColumn {
return child;
}
-
- /**
- * Comparator for comparing children. A null safe call
- * @param otherScanColumn
- * @return
- */
- protected int compareChildren( final ScanColumn otherScanColumn ) {
-
- if ( otherScanColumn == null ) {
- return 1;
- }
-
- final ScanColumn otherChild = otherScanColumn.getChild();
-
- if ( child != null && otherChild != null ) {
- return child.compareTo( otherChild );
- }
-
- return 0;
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/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..5bc91e0 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,11 +1,16 @@
package org.apache.usergrid.persistence.query.ir.result;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
@@ -21,18 +26,20 @@ 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 Iterator<ScanColumn> mergedIterators;
+ private Map<UUID, ResultIterator> cursorMap;
+ 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;
+ this.cursorMap = new HashMap<UUID, ResultIterator>( pageSize );
+ createIterators( searchVisitors );
}
@@ -45,6 +52,14 @@ public class GatherIterator implements ResultIterator {
@Override
public void finalizeCursor( final CursorCache cache, final UUID lastValue ) {
//find the last value in the tree, and return it's cursor
+ final ResultIterator sourceIterator = cursorMap.get( lastValue );
+
+ if(sourceIterator == null){
+ throw new IllegalArgumentException( "Could not find the iterator that provided the candidate with uuid " + lastValue );
+ }
+
+ //delegate to the source iterator
+ sourceIterator.finalizeCursor( cache, lastValue );
}
@@ -56,12 +71,11 @@ public class GatherIterator implements ResultIterator {
@Override
public boolean hasNext() {
-
- if(next() == null){
- advance();
+ if(mergedIterators == null || !mergedIterators.hasNext()){
+ mergeIterators();
}
- return next != null;
+ return mergedIterators.hasNext();
}
@@ -71,38 +85,76 @@ public class GatherIterator implements ResultIterator {
throw new NoSuchElementException( "No more elements" );
}
- final Set<ScanColumn> results = next;
- next = null;
- return results;
+ return getNextPage();
+ }
+
+ 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 );
+
+ }
+
}
/**
+ * Get the next page of results
+ * @return
+ */
+ private Set<ScanColumn> getNextPage(){
+
+ //try to take from our PageSize
+ LinkedHashSet<ScanColumn> resultSet = new LinkedHashSet<ScanColumn>( pageSize );
+
+ for(int i = 0; i < pageSize && mergedIterators.hasNext(); i ++){
+ resultSet.add( mergedIterators.next() );
+ }
+
+
+ return resultSet;
+ }
+
+ /**
* Advance the iterator
*/
- private void advance(){
+ private void mergeIterators(){
//TODO make this concurrent
+ //clear the cursor map
+ cursorMap.clear();
- final TreeSet<ScanColumn> results = new TreeSet<ScanColumn>( );
-
+ TreeSet<ScanColumn> merged = new TreeSet<ScanColumn>( );
- for(SearchVisitor visitor: searchVisitors){
- merge(results, visitor);
+ for(ResultIterator iterator: this.iterators){
+ merge(merged, iterator);
}
- this.next = results;
+ mergedIterators = merged.iterator();
+
}
+
+
/**
* 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
@@ -110,19 +162,24 @@ public class GatherIterator implements ResultIterator {
return;
}
-
final Iterator<ScanColumn> nextPage = iterator.next().iterator();
-
//only take from the iterator what we need to create a full page.
for(int i = 0 ; i < pageSize && nextPage.hasNext(); i ++){
- results.add( nextPage.next() );
+ final ScanColumn next = nextPage.next();
+
+ results.add(next);
+ cursorMap.put( next.getUUID(), iterator );
+
+// //results are too large, trim them
+// if(results.size() > pageSize){
+// final ScanColumn toRemove = results.pollLast();
+// cursorMap.remove( toRemove.getUUID() );
+// }
- //results are too large, trim them
- if(results.size() > pageSize){
- results.pollLast();
- }
}
}
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SearchCollectionVisitor.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SearchCollectionVisitor.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SearchCollectionVisitor.java
index 78abbca..c20baf4 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SearchCollectionVisitor.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SearchCollectionVisitor.java
@@ -7,6 +7,7 @@ import org.apache.usergrid.persistence.EntityRef;
import org.apache.usergrid.persistence.IndexBucketLocator;
import org.apache.usergrid.persistence.cassandra.CassandraService;
import org.apache.usergrid.persistence.cassandra.QueryProcessor;
+import org.apache.usergrid.persistence.cassandra.index.DynamicCompositeStartToBytes;
import org.apache.usergrid.persistence.cassandra.index.IndexBucketScanner;
import org.apache.usergrid.persistence.cassandra.index.IndexScanner;
import org.apache.usergrid.persistence.cassandra.index.NoOpIndexScanner;
@@ -77,7 +78,7 @@ public class SearchCollectionVisitor extends SearchVisitor {
// perform the search
else {
columns =
- searchIndexBuckets( indexKey, slice, collection.getName(), queryProcessor.getPageSizeHint( node ) );
+ searchIndexBuckets( indexKey, slice, queryProcessor.getPageSizeHint( node ) );
}
return columns;
@@ -100,10 +101,10 @@ public class SearchCollectionVisitor extends SearchVisitor {
IndexScanner indexScanner = cassandraService
- .getIdList( cassandraService.getApplicationKeyspace( applicationId ),
+ .getIdList(
key( headEntity.getUuid(), DICTIONARY_COLLECTIONS, collectionName ), startId, null,
- queryProcessor.getPageSizeHint( node ), query.isReversed(), indexBucketLocator, applicationId,
- collectionName, node.isForceKeepFirst() );
+ queryProcessor.getPageSizeHint( node ), query.isReversed(), bucket, applicationId,
+ node.isForceKeepFirst() );
this.results.push( new SliceIterator( slice, indexScanner, UUID_PARSER ) );
}
@@ -149,10 +150,9 @@ public class SearchCollectionVisitor extends SearchVisitor {
*
* @param indexKey The index key to read
* @param slice Slice set in the query
- * @param collectionName The name of the collection to search
* @param pageSize The page size to load when iterating
*/
- private IndexScanner searchIndexBuckets( Object indexKey, QuerySlice slice, String collectionName, int pageSize )
+ private IndexScanner searchIndexBuckets( Object indexKey, QuerySlice slice, int pageSize )
throws Exception {
DynamicComposite[] range = slice.getRange();
@@ -160,7 +160,7 @@ public class SearchCollectionVisitor extends SearchVisitor {
Object keyPrefix = key( indexKey, slice.getPropertyName() );
IndexScanner scanner =
- new IndexBucketScanner( cassandraService, ENTITY_INDEX, applicationId, keyPrefix, bucket, range[0],
+ new IndexBucketScanner( cassandraService, ENTITY_INDEX, DynamicCompositeStartToBytes.INSTANCE, applicationId, keyPrefix, bucket, range[0],
range[1], slice.isReversed(), pageSize, slice.hasCursor() );
return scanner;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SearchConnectionVisitor.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SearchConnectionVisitor.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SearchConnectionVisitor.java
index 74ff19f..6f833db 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SearchConnectionVisitor.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SearchConnectionVisitor.java
@@ -13,6 +13,7 @@ import org.apache.usergrid.persistence.cassandra.CassandraService;
import org.apache.usergrid.persistence.cassandra.ConnectionRefImpl;
import org.apache.usergrid.persistence.cassandra.QueryProcessor;
import org.apache.usergrid.persistence.cassandra.index.ConnectedIndexScanner;
+import org.apache.usergrid.persistence.cassandra.index.DynamicCompositeStartToBytes;
import org.apache.usergrid.persistence.cassandra.index.IndexBucketScanner;
import org.apache.usergrid.persistence.cassandra.index.IndexScanner;
import org.apache.usergrid.persistence.cassandra.index.NoOpIndexScanner;
@@ -205,7 +206,7 @@ public class SearchConnectionVisitor extends SearchVisitor {
IndexScanner scanner =
- new IndexBucketScanner( cassandraService, ENTITY_INDEX, applicationId,
+ new IndexBucketScanner( cassandraService, ENTITY_INDEX, DynamicCompositeStartToBytes.INSTANCE, applicationId,
keyPrefix, shardBucket, range[0], range[1], slice.isReversed(), pageSize, slice.hasCursor());
return scanner;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/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..b26f684 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
@@ -17,50 +17,85 @@
package org.apache.usergrid.persistence.query.ir.result;
+import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
import java.util.UUID;
+import org.apache.usergrid.utils.UUIDUtils;
+
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<SecondaryIndexColumn> 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() );
- throw new UnsupportedOperationException( "Implement me with static comparators" );
+ final UUID uuid = ( UUID ) composite.get( 2 );
+ final Object value = composite.get( 1 );
-// return new SecondaryIndexColumn( ( UUID ) composite.get( 2 ), composite.get( 1 ), buff, null );
+ if ( typeComparator == null ) {
+ typeComparator = getTypeComparator( value, isReversed );
+ }
+
+ return new SecondaryIndexColumn( uuid, value, buff, typeComparator );
}
+ private Comparator<SecondaryIndexColumn> getTypeComparator( final Object value, final boolean isReversed ) {
+
+ final Class clazz = value.getClass();
+ final Comparator<SecondaryIndexColumn> 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;
- private final Comparator<Object> valueComparator;
+ private final Comparator<SecondaryIndexColumn> valueComparator;
/**
* 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<SecondaryIndexColumn> valueComparator ) {
super( uuid, columnNameBuffer );
this.value = value;
this.valueComparator = valueComparator;
@@ -74,8 +109,169 @@ 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;
+ }
+
+ return valueComparator.compare( this, ( SecondaryIndexColumn ) other );
+ }
+ }
+
+
+ private static final Map<MapKey, Comparator<SecondaryIndexColumn>> COMPARATOR_MAP =
+ new HashMap<MapKey, Comparator<SecondaryIndexColumn>>();
+
+ 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 ) );
+
+ final BigIntegerComparator bigIntegerComparator = new BigIntegerComparator();
+
+ COMPARATOR_MAP.put( new MapKey( BigInteger.class, false ), bigIntegerComparator );
+ COMPARATOR_MAP.put( new MapKey( BigInteger.class, true ), new ReverseComparator( bigIntegerComparator ) );
+ }
+
+
+ /**
+ * 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 abstract class SecondaryIndexColumnComparator implements Comparator<SecondaryIndexColumn> {
+
+ /**
+ * If the result of compare is != 0 it is returned, otherwise the uuids are compared
+ */
+ protected int compareValues( final int compare, final SecondaryIndexColumn first,
+ SecondaryIndexColumn second ) {
+ if ( compare != 0 ) {
+ return compare;
+ }
+
+ return com.fasterxml.uuid.UUIDComparator.staticCompare( first.uuid, second.uuid );
+ }
+ }
+
+
+ private static final class LongComparator extends SecondaryIndexColumnComparator {
+
+ @Override
+ public int compare( final SecondaryIndexColumn first, final SecondaryIndexColumn second ) {
+
+ final Long firstLong = ( Long ) first.value;
+ final Long secondLong = ( Long ) second.value;
+
+
+ return compareValues( Long.compare( firstLong, secondLong ), first, second );
+ }
+ }
+
+
+ private static final class StringComparator extends SecondaryIndexColumnComparator {
+ @Override
+ public int compare( final SecondaryIndexColumn first, final SecondaryIndexColumn second ) {
+
+ if ( first == null && second != null ) {
+ return -1;
+ }
+
+ final String firstString = ( String ) first.value;
+ final String secondString = ( String ) second.value;
+
+
+ return compareValues( firstString.compareTo( secondString ), first, second );
+ }
+ }
+
+
+ private static final class UUIDComparator extends SecondaryIndexColumnComparator {
+ @Override
+ public int compare( final SecondaryIndexColumn first, final SecondaryIndexColumn second ) {
+ final UUID firstUUID = ( UUID ) first.value;
+ final UUID secondUUID = ( UUID ) second.value;
+
+
+ return compareValues( UUIDUtils.compare( firstUUID, secondUUID ), first, second );
+ }
+ }
+
+
+ private static final class BigIntegerComparator extends SecondaryIndexColumnComparator {
+ @Override
+ public int compare( final SecondaryIndexColumn first, final SecondaryIndexColumn second ) {
+ final BigInteger firstInt = ( BigInteger ) first.value;
+ final BigInteger secondInt = ( BigInteger ) second.value;
+
+
+ return compareValues( firstInt.compareTo( secondInt ), first, second );
+ }
+ }
+
+
+ /**
+ * Reversed our comparator
+ */
+ private static final class ReverseComparator implements Comparator<SecondaryIndexColumn> {
+
+ private final Comparator<SecondaryIndexColumn> comparator;
+
+
+ private ReverseComparator( final Comparator<SecondaryIndexColumn> comparator ) {this.comparator = comparator;}
+
+
+ @Override
+ public int compare( final SecondaryIndexColumn first, final SecondaryIndexColumn second ) {
+ return comparator.compare( first, second ) * -1;
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java
index 3f052da..a386159 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java
@@ -26,6 +26,7 @@ import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import org.apache.usergrid.persistence.cassandra.CursorCache;
import org.apache.usergrid.persistence.cassandra.index.IndexScanner;
import org.apache.usergrid.persistence.exceptions.QueryIterationException;
@@ -127,9 +128,9 @@ public class SliceIterator implements ResultIterator {
while ( results.hasNext() ) {
- ByteBuffer colName = results.next().getName().duplicate();
+ final ByteBuffer colName = results.next().getName().duplicate();
- ScanColumn parsed = parser.parse( colName, isReversed );
+ final ScanColumn parsed = parser.parse( colName, isReversed );
//skip this value, the parser has discarded it
if ( parsed == null ) {
@@ -215,22 +216,22 @@ public class SliceIterator implements ResultIterator {
//this is a bug
if ( scanner.hasNext() ) {
logger.error(
- "An iterator attempted to access a slice that was not iterated over. This will result in the" +
- " cursor construction failing" );
+ "An iterator attempted to access a slice that was not iterated over. This will result in the"
+ + " cursor construction failing" );
throw new QueryIterationException(
- "An iterator attempted to access a slice that was not iterated over. This will result in the" +
- " cursor construction failing" );
+ "An iterator attempted to access a slice that was not iterated over. This will result in the"
+ + " cursor construction failing" );
}
final ByteBuffer sliceCursor = slice.getCursor();
//we've never loaded anything, just re-use the existing slice
- if (last == null && sliceCursor != null ) {
+ if ( last == null && sliceCursor != null ) {
bytes = sliceCursor;
}
//use the last column we loaded. This way our scan returns nothing next time since start == finish
- else if(last != null) {
+ else if ( last != null ) {
bytes = last.getCursorValue();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDColumn.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDColumn.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDColumn.java
index a5e09c1..640b391 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDColumn.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDColumn.java
@@ -4,53 +4,35 @@ package org.apache.usergrid.persistence.query.ir.result;
import java.nio.ByteBuffer;
import java.util.UUID;
+import org.apache.usergrid.persistence.cassandra.Serializers;
import org.apache.usergrid.utils.UUIDUtils;
/**
* Used as a comparator for columns
*/
-class UUIDColumn implements ScanColumn{
+class UUIDColumn extends AbstractScanColumn{
- private final UUID uuid;
private final int compareReversed;
- private ScanColumn child;
-
- UUIDColumn( final UUID uuid, final int compareReversed ) {
- this.uuid = uuid;
+ protected UUIDColumn( final UUID uuid, final ByteBuffer columnNameBuffer, final int compareReversed ) {
+ super( uuid, columnNameBuffer );
this.compareReversed = compareReversed;
}
- @Override
- public UUID getUUID() {
- return uuid;
- }
-
-
- @Override
- public ByteBuffer getCursorValue() {
- return null;
- }
-
-
- @Override
- public void setChild( final ScanColumn childColumn ) {
- this.child = childColumn;
+ public UUIDColumn( final UUID uuid, final int compareReversed ) {
+ super(uuid, Serializers.ue.toByteBuffer( uuid ));
+ this.compareReversed = compareReversed;
}
- @Override
- public ScanColumn getChild() {
- return child;
- }
@Override
public int compareTo( final ScanColumn other ) {
-
return UUIDUtils.compare( uuid, other.getUUID() ) * compareReversed;
-
}
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java
index 91644ce..2c5b1ba 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java
@@ -33,6 +33,6 @@ public class UUIDIndexSliceParser implements SliceParser {
@Override
public ScanColumn parse( final ByteBuffer columnNameBytes, final boolean isReversed ) {
final int compare = isReversed? -1: 1;
- return new UUIDColumn( ue.fromByteBuffer( columnNameBytes.duplicate() ), compare );
+ return new UUIDColumn( ue.fromByteBuffer( columnNameBytes.duplicate() ), columnNameBytes, compare );
}
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java
index 635ca97..aca9852 100644
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java
@@ -133,7 +133,7 @@ public class UnionIterator extends MultiIterator {
private final List<ScanColumn> list;
- private UUIDColumn min;
+// private UUIDColumn min;
public SortedColumnList( final int maxSize, final UUID minUuid ) {
@@ -141,9 +141,9 @@ public class UnionIterator extends MultiIterator {
this.list = new ArrayList<ScanColumn>( maxSize );
this.maxSize = maxSize;
- if ( minUuid != null ) {
- min = new UUIDColumn( minUuid, 1 ) ;
- }
+// if ( minUuid != null ) {
+// min = new UUIDColumn( minUuid, 1 ) ;
+// }
}
@@ -152,9 +152,9 @@ public class UnionIterator extends MultiIterator {
*/
public void add( ScanColumn col ) {
//less than our min, don't add
- if ( min != null && min.compareTo( col ) >= 0 ) {
- return;
- }
+// if ( min != null && min.compareTo( col ) >= 0 ) {
+// return;
+// }
int index = Collections.binarySearch( this.list, col );
@@ -215,7 +215,7 @@ public class UnionIterator extends MultiIterator {
}
final UUID oldMin = this.list.get( size - 1 ).getUUID();
- min = new UUIDColumn( oldMin, 1 );
+// min = new UUIDColumn( oldMin, 1 );
}
@@ -228,7 +228,7 @@ public class UnionIterator extends MultiIterator {
public void reset(){
clear();
- this.min = null;
+// this.min = null;
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/68c7eae1/stack/core/src/test/java/org/apache/usergrid/persistence/CollectionIT.java
----------------------------------------------------------------------
diff --git a/stack/core/src/test/java/org/apache/usergrid/persistence/CollectionIT.java b/stack/core/src/test/java/org/apache/usergrid/persistence/CollectionIT.java
index ac58bd7..99fed21 100644
--- a/stack/core/src/test/java/org/apache/usergrid/persistence/CollectionIT.java
+++ b/stack/core/src/test/java/org/apache/usergrid/persistence/CollectionIT.java
@@ -1444,7 +1444,7 @@ public class CollectionIT extends AbstractCoreIT {
Query query = Query.fromQL( s );
Results r = em.searchCollection( em.getApplicationRef(), "loveobjects", query );
- assertTrue( r.size() == 1 );
+ assertEquals(1, r.size() );
String username = ( String ) ( ( Map ) r.getEntities().get( 0 ).getProperty( "Recipient" ) ).get( "Username" );
// selection results should be a list of lists