All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.relation.rule.eval.QueryTask Maven / Gradle / Ivy

Go to download

Blazegraph(TM) DB Core Platform. It contains all Blazegraph DB dependencies other than Blueprints.

There is a newer version: 2.1.4
Show newest version
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;

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy