/*
 * Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
 * and the EPL 1.0 (http://h2database.com/html/license.html).
 * Initial Developer: H2 Group
 */
package org.h2.util;

import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.h2.message.DbException;

Single threaded lazy future.
Author:Sergi Vladykin
Type parameters:
  • <T> – the result type
/** * Single threaded lazy future. * * @author Sergi Vladykin * * @param <T> the result type */
public abstract class LazyFuture<T> implements Future<T> { private static final int S_READY = 0; private static final int S_DONE = 1; private static final int S_ERROR = 2; private static final int S_CANCELED = 3; private int state = S_READY; private T result; private Exception error;
Reset this future to the initial state.
Returns:false if it was already in initial state
/** * Reset this future to the initial state. * * @return {@code false} if it was already in initial state */
public boolean reset() { if (state == S_READY) { return false; } state = S_READY; result = null; error = null; return true; }
Run computation and produce the result.
Returns:the result of computation
/** * Run computation and produce the result. * * @return the result of computation */
protected abstract T run() throws Exception; @Override public boolean cancel(boolean mayInterruptIfRunning) { if (state != S_READY) { return false; } state = S_CANCELED; return true; } @Override public T get() throws InterruptedException, ExecutionException { switch (state) { case S_READY: try { result = run(); state = S_DONE; } catch (Exception e) { error = e; if (e instanceof InterruptedException) { throw (InterruptedException) e; } throw new ExecutionException(e); } finally { if (state != S_DONE) { state = S_ERROR; } } return result; case S_DONE: return result; case S_ERROR: throw new ExecutionException(error); case S_CANCELED: throw new CancellationException(); default: throw DbException.throwInternalError(Integer.toString(state)); } } @Override public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException { return get(); } @Override public boolean isCancelled() { return state == S_CANCELED; } @Override public boolean isDone() { return state != S_READY; } }