package edu.washington.escience.myria.parallel; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import javax.annotation.Nullable; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; /** * The future for a query. */ public final class QueryFuture implements ListenableFuture<Query> { /** The id of the query this future represents. */ private final long queryId; /** The wrapped future, which actually implements all the future behavior. */ private final ListenableFuture<Query> future; /** * Create a future for the specified query. * * @param queryId the id of the query * @return a future for the specified query */ public static QueryFuture create(final long queryId) { return new QueryFuture(queryId); } /** * The future for a submitted query. * * @param queryId the id of the submitted query. */ private QueryFuture(final long queryId) { this(queryId, SettableFuture.<Query>create()); } /** * The future for a submitted query. * * @param queryId the id of the submitted query. * @param future the future to be wrapped. */ private QueryFuture(final long queryId, final ListenableFuture<Query> future) { this.queryId = queryId; this.future = future; } /** * @return the id of this query */ public long getQueryId() { return queryId; } @Override public boolean cancel(final boolean mayInterruptIfRunning) { return future.cancel(mayInterruptIfRunning); } @Override public boolean isCancelled() { return future.isCancelled(); } @Override public boolean isDone() { return future.isDone(); } @Override public Query get() throws InterruptedException, ExecutionException { return future.get(); } @Override public Query get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return future.get(timeout, unit); } @Override public void addListener(final Runnable listener, final Executor executor) { future.addListener(listener, executor); } /** * Sets the value of this future. This method will return {@code true} if the value was successfully set, or * {@code false} if the future has already been set or cancelled. * * @param value the value the future should hold. * @return true if the value was successfully set. */ public boolean set(@Nullable final Query value) { if (future instanceof SettableFuture) { return ((SettableFuture<Query>) future).set(value); } return false; } /** * Sets the future to having failed with the given exception. This exception will be wrapped in an * {@code ExecutionException} and thrown from the {@code get} methods. This method will return {@code true} if the * exception was successfully set, or {@code false} if the future has already been set or cancelled. * * @param throwable the exception the future should hold. * @return true if the exception was successfully set. */ public boolean setException(final Throwable throwable) { if (future instanceof SettableFuture) { return ((SettableFuture<Query>) future).setException(throwable); } return false; } }