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

com.bigdata.rdf.sail.RunningQueryCloseableIterator Maven / Gradle / Ivy

package com.bigdata.rdf.sail;

import java.util.NoSuchElementException;

import com.bigdata.bop.engine.IRunningQuery;

import cutthecrap.utils.striterators.ICloseableIterator;

/**
 * Iteration construct wraps an {@link IRunningQuery} with logic to (a) verify
 * that the {@link IRunningQuery} has not encountered an error; and (b) to
 * cancel the {@link IRunningQuery} when the iterator draining the
 * {@link IRunningQuery} is {@link #close() closed}.
 */
public class RunningQueryCloseableIterator 
        implements ICloseableIterator {

    private final IRunningQuery runningQuery;
    private final ICloseableIterator src;
    private boolean checkedFuture = false;

    /**
     * The next element is buffered so we can always return it if the
     * {@link #runningQuery} was not aborted at the time that {@link #hasNext()}
     * return true.
     */
    private E current = null;

    private volatile boolean open = true;
    
    public RunningQueryCloseableIterator(final IRunningQuery runningQuery,
            final ICloseableIterator src) {

        this.runningQuery = runningQuery;
        this.src = src;

    }

    /**
     * Test for abnormal completion of the {@link IRunningQuery}.
     */
    private void checkFuture() {

//        if (!checkedFuture && runningQuery.isDone()) {
            try {
                runningQuery.get();
            } catch (InterruptedException e) {
                /*
                 * Interrupted while waiting on the Future (should not happen
                 * since the Future is already done).
                 */
                throw new RuntimeException(e);
            } catch (Throwable e) {
                /*
                 * Exception thrown by the runningQuery.
                 */
                if (runningQuery.getCause() != null) {
                    // abnormal termination - wrap and rethrow.
                    throw new RuntimeException(e);
                }
                // otherwise this is normal termination.
            }
            checkedFuture = true;
//        }

    }
    
    public void close() {
        if (open) {
            open = false;
            runningQuery.cancel(true/* mayInterruptIfRunning */);
            src.close();
            checkFuture();
        }
    }

    public boolean hasNext() {

        if(open && _hasNext())
            return true;
        
        close();
        
        return false;
        
    }
    
    private boolean _hasNext() {
        
        if (current != null) {
            // Already buffered.
            return true;
        }

        if (!src.hasNext()) {
            // Source is exhausted.
            return false;
        }

        // buffer the next element.
        current = src.next();

        if (!checkedFuture && runningQuery.isDone()) {

            checkFuture();
            
        }
        
        // the next element is now buffered.
        return true;

    }
    
    public E next() {

        if (!hasNext())
            throw new NoSuchElementException();
        
        final E tmp = current;
        
        current = null;
        
        return tmp;
        
    }

    /**
     * Operation is not supported.
     */
    public void remove() {

        // Not supported since we are buffering ahead.
        throw new UnsupportedOperationException();
        
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy