
com.bigdata.relation.rule.eval.QueryTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bigdata-core Show documentation
Show all versions of bigdata-core Show documentation
Blazegraph(TM) DB Core Platform. It contains all Blazegraph DB dependencies other than Blueprints.
package com.bigdata.relation.rule.eval;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import com.bigdata.journal.IIndexManager;
import com.bigdata.relation.accesspath.IBlockingBuffer;
import com.bigdata.relation.accesspath.IBuffer;
import com.bigdata.relation.accesspath.UnsynchronizedArrayBuffer;
import com.bigdata.relation.rule.IProgram;
import com.bigdata.relation.rule.IRule;
import com.bigdata.relation.rule.IStep;
import com.bigdata.service.DataService;
/**
* A task that executes a query operation.
*
* @author Bryan Thompson
* @version $Id$
*/
public class QueryTask extends AbstractStepTask {
/**
*
*/
private static final long serialVersionUID = -1795376592525891934L;
/**
* The {@link IBlockingBuffer} on which the {@link ISolution}s will be
* written.
*/
private final IBlockingBuffer buffer;
/**
*
* @param buffer
* The {@link IBlockingBuffer} on which the {@link ISolution}s
* will be written.
*/
public QueryTask(IStep step, IJoinNexusFactory joinNexusFactory,
IBlockingBuffer buffer, IIndexManager indexManager,
DataService dataService) {
super(ActionEnum.Query, joinNexusFactory, step, indexManager,
dataService);
if (buffer == null)
throw new IllegalArgumentException();
this.buffer = buffer;
}
/**
* Run the task (invoked once we are in the target execution context).
*/
public RuleStats call() throws Exception {
/*
* Create the IJoinNexus that will be used to evaluate the Query now
* that we are in the execution context and have the correct
* IIndexManager object.
*/
final IJoinNexus joinNexus = joinNexusFactory.newInstance(indexManager);
/*
* Create the individual tasks that we need to execute now that we are
* in the correct execution context.
*/
final List> tasks = newQueryTasks(step, joinNexus,
buffer);
try {
// run those tasks and wait for them to complete.
final RuleStats totals = runTasks(joinNexus, tasks);
/*
* Nothing more will be written on the buffer so we close it. The
* iterator will drain anything in the queue from the buffer and
* then hasNext() will report false.
*/
if (log.isDebugEnabled()) {
log.debug("done - closing the blocking buffer");
}
// producer is done : close the BlockingBuffer.
buffer.close();
RuleLog.log(totals);
return totals;
} catch (Throwable t) {
try {
log.error("Problem running query: " + t, t);
} catch (Throwable ignored) {
// ignored : logging system problem.
}
/*
* Note: This will close the buffer. It will also cause the iterator
* to throw the [cause] from hasNext() (or next(), which invokes
* hasNext()).
*/
buffer.abort(t/* cause */);
throw new RuntimeException(t);
}
}
/**
* Run the task(s) and wait for them to complete.
*
* @return The {@link RuleStats}
*
* @throws ExecutionException
* @throws InterruptedException
*/
protected RuleStats runTasks(final IJoinNexus joinNexus,
final List> tasks) throws InterruptedException,
ExecutionException {
assert tasks != null;
assert !tasks.isEmpty();
final RuleStats totals;
if (tasks.size() == 1) {
totals = runOne(joinNexus, step, tasks.get(0));
} else if (!joinNexus.forceSerialExecution() && !step.isRule()
&& ((IProgram) step).isParallel()) {
totals = runParallel(joinNexus, step, tasks);
} else {
totals = runSequential(joinNexus, step, tasks);
}
return totals;
}
/**
* Builds a set of tasks for the program. Each task is assigned its own
* {@link UnsynchronizedArrayBuffer}. Each task will flush that
* {@link UnsynchronizedArrayBuffer} onto the given {@link IBuffer} when it
* completes.
*
* @param step
* The {@link IStep}.
* @param joinNexus
* The {@link IJoinNexus}.
* @param buffer
* The thread-safe buffer onto which the individual tasks emit
* chunks.
*
* @return The list of tasks to run.
*/
protected List> newQueryTasks(IStep step,
IJoinNexus joinNexus, IBlockingBuffer buffer) {
if (log.isDebugEnabled())
log.debug("step=" + step.getName());
final List> tasks;
if (step.isRule()) {
tasks = new ArrayList>(1);
final IRule rule = (IRule) step;
final Callable task = joinNexus.getRuleTaskFactory(
false/* parallel */, rule).newTask(rule, joinNexus,
buffer);
tasks.add(task);
} else {
final IProgram program = (IProgram)step;
final boolean parallel = program.isParallel();
tasks = new ArrayList>(program.stepCount());
final Iterator itr = program.steps();
while (itr.hasNext()) {
// FIXME RULE_REFACTOR handle sub-programs.
final IRule rule = (IRule) itr.next();
final Callable task = joinNexus.getRuleTaskFactory(
parallel, rule).newTask(rule, joinNexus, buffer);
tasks.add(task);
}
}
if(log.isDebugEnabled()) {
log.debug("Created "+tasks.size()+" query tasks");
}
return tasks;
}
}