com.clickhouse.data.ClickHouseDeferredValue Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of clickhouse-data Show documentation
Show all versions of clickhouse-data Show documentation
Data processing utilities for ClickHouse
The newest version!
package com.clickhouse.data;
import java.util.Optional;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
/**
* This class represents a deferred value. It holds a reference to a
* {@link Supplier} or {@link Future} to retrieve value only when {@link #get()}
* or {@link #getOptional()} was called.
*/
public final class ClickHouseDeferredValue implements Supplier {
/**
* Wraps a future object.
*
* @param type of the value
* @param future future object, could be null
* @return deferred value of a future object
*/
public static ClickHouseDeferredValue of(CompletableFuture future) {
return of(future, 0L);
}
/**
* Wraps a future object.
*
* @param type of the value
* @param future future object, could be null
* @param timeout timeout in milliseconds, zero or negative number means no
* timeout
* @return deferred vaue of a future object
*/
@SuppressWarnings("unchecked")
public static ClickHouseDeferredValue of(CompletableFuture future, long timeout) {
final CompletableFuture f = future != null ? future : (CompletableFuture) ClickHouseUtils.NULL_FUTURE;
final long t = timeout < 0L ? 0L : timeout;
final Supplier supplier = () -> {
try {
return t > 0L ? f.get(t, TimeUnit.MILLISECONDS) : f.get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
f.cancel(false);
throw new CompletionException(e);
} catch (CancellationException e) {
f.cancel(true);
throw new CompletionException(e);
} catch (ExecutionException | TimeoutException e) {
throw new CompletionException(e);
}
};
return new ClickHouseDeferredValue<>(supplier, null);
}
/**
* Wraps return value from a supplier function.
*
* @param type of the value
* @param supplier supplier function, could be null
* @return deferred value of return value from supplier function
*/
@SuppressWarnings("unchecked")
public static ClickHouseDeferredValue of(Supplier supplier) {
return new ClickHouseDeferredValue<>(supplier != null ? supplier : (Supplier) ClickHouseUtils.NULL_SUPPLIER,
null);
}
/**
* Wraps given value as a deferred value.
*
* @param type of the value
* @param value value to wrap
* @param clazz class of the value
* @return deferred value
*/
@SuppressWarnings("unchecked")
public static ClickHouseDeferredValue of(T value, Class clazz) { // NOSONAR
return new ClickHouseDeferredValue<>((Supplier) ClickHouseUtils.NULL_SUPPLIER, Optional.ofNullable(value));
}
private final Supplier supplier;
private final AtomicReference> value;
private ClickHouseDeferredValue(Supplier supplier, Optional value) {
this.supplier = supplier;
this.value = new AtomicReference<>(value);
}
@Override
public T get() {
return getOptional().orElse(null);
}
/**
* Gets optional value, which may or may not be null.
*
* @return optional value
*/
public Optional getOptional() {
Optional v = value.get();
if (v == null && !value.compareAndSet(null, v = Optional.ofNullable(supplier.get()))) { // NOSONAR
v = value.get();
}
return v != null ? v : Optional.empty(); // NOSONAR
}
}