/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Nov 8, 2011
*/
package com.bigdata.bop.solutions;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import junit.framework.TestCase2;
import org.openrdf.model.Value;
import org.openrdf.model.impl.LiteralImpl;
import com.bigdata.bop.BOp;
import com.bigdata.bop.BOpContext;
import com.bigdata.bop.BOpEvaluationContext;
import com.bigdata.bop.Constant;
import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.IConstant;
import com.bigdata.bop.IPredicate;
import com.bigdata.bop.IVariable;
import com.bigdata.bop.NV;
import com.bigdata.bop.NamedSolutionSetRefUtility;
import com.bigdata.bop.PipelineOp;
import com.bigdata.bop.Var;
import com.bigdata.bop.bindingSet.HashBindingSet;
import com.bigdata.bop.bindingSet.ListBindingSet;
import com.bigdata.bop.engine.AbstractQueryEngineTestCase;
import com.bigdata.bop.engine.BOpStats;
import com.bigdata.bop.engine.BlockingBufferWithStats;
import com.bigdata.bop.engine.MockRunningQuery;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.VTE;
import com.bigdata.rdf.internal.impl.TermId;
import com.bigdata.rdf.model.BigdataValue;
import com.bigdata.rdf.model.BigdataValueFactory;
import com.bigdata.rdf.model.BigdataValueFactoryImpl;
import com.bigdata.relation.accesspath.IAsynchronousIterator;
import com.bigdata.relation.accesspath.IBlockingBuffer;
import com.bigdata.relation.accesspath.ThickAsynchronousIterator;
/**
* Abstract base class for DISTINCT SOLUTIONS test suites.
*
* TODO Write a unit test in which some variables are unbound.
*
* TODO Write unit test to verify that only the variables which are being made
* DISTINCT are projected.
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
* @version $Id$
*/
abstract public class AbstractDistinctSolutionsTestCase extends TestCase2 {
/**
*
*/
public AbstractDistinctSolutionsTestCase() {
}
/**
* @param name
*/
public AbstractDistinctSolutionsTestCase(String name) {
super(name);
}
protected Setup setup;
public void setUp() throws Exception {
// jnl = new Journal(getProperties());
setup = new Setup(getName());
}
public void tearDown() throws Exception {
// if (jnl != null) {
// jnl.destroy();
// jnl = null;
// }
//
// clear reference.
if (setup != null) {
setup.destroy();
setup = null;
}
}
/**
* Setup for a problem used by many of the join test suites.
*/
static protected class Setup {
protected final String namespace;
protected final IV<?, ?> brad, john, fred, jane, mary, paul, leon;
protected final List<IBindingSet> data;
@SuppressWarnings("rawtypes")
public Setup(final String namespace) {
if (namespace == null)
throw new IllegalArgumentException();
this.namespace = namespace;
brad = makeIV(new LiteralImpl("Brad"));
john = makeIV(new LiteralImpl("John"));
fred = makeIV(new LiteralImpl("Fred"));
jane = makeIV(new LiteralImpl("Jane "));
mary = makeIV(new LiteralImpl("Mary"));
paul = makeIV(new LiteralImpl("Paul"));
leon = makeIV(new LiteralImpl("Leon"));
final Var<?> x = Var.var("x");
final Var<?> y = Var.var("y");
data = new LinkedList<IBindingSet>();
IBindingSet bset = null;
{
bset = new HashBindingSet();
bset.set(x, new Constant<IV>(john));
bset.set(y, new Constant<IV>(mary));
data.add(bset);
}
{
bset = new HashBindingSet();
bset.set(x, new Constant<IV>(mary));
bset.set(y, new Constant<IV>(paul));
data.add(bset);
}
{
bset = new HashBindingSet();
bset.set(x, new Constant<IV>(mary));
bset.set(y, new Constant<IV>(jane));
data.add(bset);
}
{
bset = new HashBindingSet();
bset.set(x, new Constant<IV>(paul));
bset.set(y, new Constant<IV>(leon));
data.add(bset);
}
{
bset = new HashBindingSet();
bset.set(x, new Constant<IV>(paul));
bset.set(y, new Constant<IV>(john));
data.add(bset);
}
{
bset = new HashBindingSet();
bset.set(x, new Constant<IV>(leon));
bset.set(y, new Constant<IV>(paul));
data.add(bset);
}
}
/**
* Return a (Mock) IV for a Value.
*
* @param v
* The value.
*
* @return The Mock IV.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private IV makeIV(final Value v) {
final BigdataValueFactory valueFactory = BigdataValueFactoryImpl
.getInstance(namespace);
final BigdataValue bv = valueFactory.asValue(v);
final IV iv = new TermId(VTE.valueOf(v), nextId++);
iv.setValue(bv);
return iv;
}
private long nextId = 1L; // Note: First id MUST NOT be 0L !!!
protected void destroy() {
// NOP.
}
}
/**
* Factory for a DISTINCT SOLUTIONS operator.
* @param args
* @param anns
* @return
*/
abstract protected PipelineOp newDistinctBindingSetsOp(final BOp[] args,
final NV... anns);
/**
* Unit test for distinct.
*
* @throws ExecutionException
* @throws InterruptedException
*/
@SuppressWarnings("rawtypes")
public void test_distinctBindingSets() throws InterruptedException,
ExecutionException {
final UUID queryId = UUID.randomUUID();
final Var<?> x = Var.var("x");
// final Var<?> y = Var.var("y");
final IVariable<?>[] vars = new IVariable[]{x};
final int distinctId = 1;
final PipelineOp query = newDistinctBindingSetsOp(new BOp[]{},
new NV(HTreeDistinctBindingSetsOp.Annotations.BOP_ID,distinctId),//
new NV(HTreeDistinctBindingSetsOp.Annotations.VARIABLES,vars),//
new NV(HTreeDistinctBindingSetsOp.Annotations.NAMED_SET_REF,
NamedSolutionSetRefUtility.newInstance(queryId, getName(), vars)),//
new NV(PipelineOp.Annotations.EVALUATION_CONTEXT,
BOpEvaluationContext.CONTROLLER),//
new NV(PipelineOp.Annotations.SHARED_STATE, true),//
new NV(PipelineOp.Annotations.MAX_PARALLEL, 1),//
new NV(IPredicate.Annotations.RELATION_NAME, new String[]{"dummy"})
);
// the expected solutions
final IBindingSet[] expected = new IBindingSet[] {//
new ListBindingSet(//
new IVariable[] { x },//
new IConstant[] { new Constant<IV>(setup.john) }//
),//
new ListBindingSet(//
new IVariable[] { x },//
new IConstant[] { new Constant<IV>(setup.mary) }//
), new ListBindingSet(//
new IVariable[] { x },//
new IConstant[] { new Constant<IV>(setup.paul) }//
), new ListBindingSet(//
new IVariable[] { x },//
new IConstant[] { new Constant<IV>(setup.leon) }//
), };
final MockQueryContext queryContext = new MockQueryContext(queryId);
try {
final BOpStats stats = query.newStats();
final IAsynchronousIterator<IBindingSet[]> source = new ThickAsynchronousIterator<IBindingSet[]>(
new IBindingSet[][] { setup.data.toArray(new IBindingSet[0]) });
final IBlockingBuffer<IBindingSet[]> sink = new BlockingBufferWithStats<IBindingSet[]>(
query, stats);
final BOpContext<IBindingSet> context = new BOpContext<IBindingSet>(
new MockRunningQuery(null/* fed */, null/* indexManager */,
queryContext), -1/* partitionId */, stats,
query/* op */, false/* lastInvocation */, source, sink,
null/* sink2 */);
// get task.
final FutureTask<Void> ft = query.eval(context);
// execute task.
// jnl.getExecutorService().execute(ft);
ft.run();
AbstractQueryEngineTestCase.assertSameSolutionsAnyOrder("", expected,
sink.iterator(), ft);
// assertTrue(ft.isDone());
// assertFalse(ft.isCancelled());
// ft.get(); // verify nothing thrown.
assertEquals(1L, stats.chunksIn.get());
assertEquals(6L, stats.unitsIn.get());
assertEquals(4L, stats.unitsOut.get());
assertEquals(1L, stats.chunksOut.get());
} finally {
queryContext.close();
}
}
}