blob: 683f00d2fd1bbd7d5516b747d78507b61d335f68 [file] [log] [blame]
/*******************************************************************************
* Copyright 2012 Apigee Corporation
*
* Licensed 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.usergrid.persistence.query.ir.result;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.junit.Test;
import org.usergrid.utils.UUIDUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.usergrid.persistence.query.ir.result.IteratorHelper.uuidColumn;
/**
* @author tnine
*/
public class UnionIteratorTest {
@Test
public void testMutipleIterators() {
UUID id1 = UUIDUtils.minTimeUUID( 1 );
UUID id2 = UUIDUtils.minTimeUUID( 2 );
UUID id3 = UUIDUtils.minTimeUUID( 3 );
UUID id4 = UUIDUtils.minTimeUUID( 4 );
UUID id5 = UUIDUtils.minTimeUUID( 5 );
UUID id6 = UUIDUtils.minTimeUUID( 6 );
UUID id7 = UUIDUtils.minTimeUUID( 7 );
UUID id8 = UUIDUtils.minTimeUUID( 8 );
UUID id9 = UUIDUtils.minTimeUUID( 9 );
UUID id10 = UUIDUtils.minTimeUUID( 10 );
// we should get intersection on 1, 3, and 8
InOrderIterator first = new InOrderIterator( 100 );
first.add( id1 );
first.add( id2 );
first.add( id3 );
first.add( id8 );
first.add( id9 );
InOrderIterator second = new InOrderIterator( 100 );
second.add( id1 );
second.add( id2 );
second.add( id3 );
second.add( id4 );
second.add( id8 );
second.add( id10 );
InOrderIterator third = new InOrderIterator( 100 );
third.add( id6 );
third.add( id7 );
third.add( id1 );
third.add( id3 );
third.add( id5 );
third.add( id8 );
InOrderIterator fourth = new InOrderIterator( 100 );
fourth.add( id1 );
fourth.add( id6 );
fourth.add( id2 );
fourth.add( id3 );
fourth.add( id8 );
fourth.add( id9 );
UnionIterator iter = new UnionIterator( 100, 0, null );
iter.addIterator( first );
iter.addIterator( second );
iter.addIterator( third );
iter.addIterator( fourth );
Set<ScanColumn> union = iter.next();
// now make sure it's right, only 1, 3 and 8 intersect
assertTrue( union.contains( uuidColumn( id1 ) ) );
assertTrue( union.contains( uuidColumn( id2 ) ) );
assertTrue( union.contains( uuidColumn( id3 ) ) );
assertTrue( union.contains( uuidColumn( id4 ) ) );
assertTrue( union.contains( uuidColumn( id5 ) ) );
assertTrue( union.contains( uuidColumn( id6 ) ) );
assertTrue( union.contains( uuidColumn( id7 ) ) );
assertTrue( union.contains( uuidColumn( id8 ) ) );
assertTrue( union.contains( uuidColumn( id9 ) ) );
assertTrue( union.contains( uuidColumn( id10 ) ) );
}
@Test
public void testOneIterator() {
UUID id1 = UUIDUtils.minTimeUUID( 1 );
UUID id2 = UUIDUtils.minTimeUUID( 2 );
UUID id3 = UUIDUtils.minTimeUUID( 3 );
UUID id4 = UUIDUtils.minTimeUUID( 4 );
// we should get intersection on 1, 3, and 8
InOrderIterator first = new InOrderIterator( 100 );
first.add( id1 );
first.add( id2 );
first.add( id3 );
first.add( id4 );
UnionIterator union = new UnionIterator( 100, 0, null );
union.addIterator( first );
Set<ScanColumn> ids = union.next();
// now make sure it's right, only 1, 3 and 8 intersect
assertTrue( ids.contains( uuidColumn( id1 ) ) );
assertTrue( ids.contains( uuidColumn( id2 ) ) );
assertTrue( ids.contains( uuidColumn( id3 ) ) );
assertTrue( ids.contains( uuidColumn( id4 ) ) );
assertFalse( union.hasNext() );
}
@Test
public void testEmptyFirstIterator() {
UUID id1 = UUIDUtils.minTimeUUID( 1 );
UUID id2 = UUIDUtils.minTimeUUID( 2 );
UUID id3 = UUIDUtils.minTimeUUID( 3 );
UUID id4 = UUIDUtils.minTimeUUID( 4 );
// we should get intersection on 1, 3, and 8
InOrderIterator first = new InOrderIterator( 100 );
InOrderIterator second = new InOrderIterator( 100 );
second.add( id1 );
second.add( id2 );
second.add( id3 );
second.add( id4 );
UnionIterator union = new UnionIterator( 100, 0, null );
union.addIterator( first );
union.addIterator( second );
Set<ScanColumn> ids = union.next();
// now make sure it's right, only 1, 3 and 8 intersect
assertTrue( ids.contains( uuidColumn( id1 ) ) );
assertTrue( ids.contains( uuidColumn( id2 ) ) );
assertTrue( ids.contains( uuidColumn( id3 ) ) );
assertTrue( ids.contains( uuidColumn( id4 ) ) );
assertFalse( union.hasNext() );
}
@Test
public void testNoIterator() {
UnionIterator union = new UnionIterator( 100, 0, null );
// now make sure it's right, only 1, 3 and 8 intersect
assertFalse( union.hasNext() );
}
@Test
public void largeUnionTest() {
int size = 10000;
int firstIntersection = 100;
int secondIntersection = 200;
int pageSize = 20;
UUID[] firstSet = new UUID[size];
UUID[] secondSet = new UUID[size];
UUID[] thirdSet = new UUID[size];
InOrderIterator first = new InOrderIterator( pageSize / 2 );
InOrderIterator second = new InOrderIterator( pageSize / 2 );
InOrderIterator third = new InOrderIterator( pageSize / 2 );
Set<UUID> results = new HashSet<UUID>( size );
for ( int i = 0; i < size; i++ ) {
firstSet[i] = UUIDUtils.newTimeUUID();
// every 100 elements, set the element equal to the first set. This way we
// have intersection
results.add( firstSet[i] );
if ( i % firstIntersection == 0 ) {
secondSet[i] = firstSet[i];
}
else {
secondSet[i] = UUIDUtils.newTimeUUID();
results.add( secondSet[i] );
}
if ( i % secondIntersection == 0 ) {
thirdSet[i] = firstSet[i];
}
else {
thirdSet[i] = UUIDUtils.newTimeUUID();
results.add( thirdSet[i] );
}
}
first.add( firstSet );
reverse( secondSet );
// reverse the second
second.add( secondSet );
third.add( thirdSet );
// now intersect them and make sure we get all results in a small set
UnionIterator union = new UnionIterator( pageSize, 0, null );
union.addIterator( first );
union.addIterator( second );
union.addIterator( third );
while ( union.hasNext() ) {
// now get the 2nd page
Set<ScanColumn> resultSet = union.next();
for ( ScanColumn col : resultSet ) {
boolean existed = results.remove( col.getUUID() );
assertTrue( "Duplicate element was detected", existed );
}
}
assertEquals( 0, results.size() );
assertFalse( union.hasNext() );
}
@Test
public void iterationCompleted() {
UUID id1 = UUIDUtils.minTimeUUID( 1 );
UUID id2 = UUIDUtils.minTimeUUID( 2 );
UUID id3 = UUIDUtils.minTimeUUID( 3 );
UUID id4 = UUIDUtils.minTimeUUID( 4 );
UUID id5 = UUIDUtils.minTimeUUID( 5 );
UnionIterator union = new UnionIterator( 5, 0, null );
InOrderIterator first = new InOrderIterator( 100 );
InOrderIterator second = new InOrderIterator( 100 );
second.add( id1 );
second.add( id2 );
second.add( id3 );
second.add( id4 );
second.add( id5 );
union.addIterator( first );
union.addIterator( second );
// now make sure it's right, only 1, 3 and 8 intersect
assertTrue( union.hasNext() );
Set<ScanColumn> ids = union.next();
// now make sure it's right, only 1, 3 and 8 intersect
assertTrue( ids.contains( uuidColumn( id1 ) ) );
assertTrue( ids.contains( uuidColumn( id2 ) ) );
assertTrue( ids.contains( uuidColumn( id3 ) ) );
assertTrue( ids.contains( uuidColumn( id4 ) ) );
assertTrue( ids.contains( uuidColumn( id5 ) ) );
//now try to get the next page
ids = union.next();
assertNull( ids );
}
private void reverse( UUID[] array ) {
UUID temp = null;
for ( int i = 0; i < array.length / 2; i++ ) {
temp = array[i];
array[i] = array[array.length - i - 1];
array[array.length - i - 1] = temp;
}
}
}