com.intellij.openapi.util.AsyncValueLoaderManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core-api Show documentation
Show all versions of core-api Show documentation
A packaging of the IntelliJ Community Edition core-api library.
This is release number 1 of trunk branch 142.
The newest version!
package com.intellij.openapi.util;
import com.intellij.util.concurrency.AtomicFieldUpdater;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class AsyncValueLoaderManager {
private final AtomicFieldUpdater> fieldUpdater;
@SuppressWarnings("UnusedDeclaration")
public AsyncValueLoaderManager(@NotNull AtomicFieldUpdater> fieldUpdater) {
this.fieldUpdater = fieldUpdater;
}
public AsyncValueLoaderManager(@NotNull Class ownerClass) {
//noinspection unchecked
fieldUpdater = ((AtomicFieldUpdater)AtomicFieldUpdater.forFieldOfType(ownerClass, AsyncResult.class));
}
public boolean isUpToDate(@NotNull HOST host, @NotNull VALUE value) {
return true;
}
public abstract void load(@NotNull HOST host, @NotNull AsyncResult result);
public final void reset(HOST host) {
fieldUpdater.set(host, null);
}
public final void set(HOST host, @Nullable VALUE value) {
if (value == null) {
reset(host);
}
else {
getOrCreateAsyncResult(host, false, false).setDone(value);
}
}
public final boolean has(HOST host) {
AsyncResult result = fieldUpdater.get(host);
return result != null && result.isDone() && result.getResult() != null;
}
@NotNull
public final AsyncResult get(HOST host) {
return get(host, true);
}
public final AsyncResult get(HOST host, boolean checkFreshness) {
return getOrCreateAsyncResult(host, checkFreshness, true);
}
private AsyncResult getOrCreateAsyncResult(HOST host, boolean checkFreshness, boolean load) {
AsyncResult asyncResult = fieldUpdater.get(host);
if (asyncResult == null) {
if (!fieldUpdater.compareAndSet(host, null, asyncResult = new AsyncResult())) {
return fieldUpdater.get(host);
}
}
else if (!asyncResult.isProcessed()) {
// if current asyncResult is not processed, so, we don't need to check cache state
return asyncResult;
}
else if (asyncResult.isDone()) {
if (!checkFreshness || isUpToDate(host, asyncResult.getResult())) {
return asyncResult;
}
if (!fieldUpdater.compareAndSet(host, asyncResult, asyncResult = new AsyncResult())) {
AsyncResult valueFromAnotherThread = fieldUpdater.get(host);
while (valueFromAnotherThread == null) {
if (fieldUpdater.compareAndSet(host, null, asyncResult)) {
if (load) {
load(host, asyncResult);
}
return asyncResult;
}
else {
valueFromAnotherThread = fieldUpdater.get(host);
}
}
return valueFromAnotherThread;
}
}
if (load) {
load(host, asyncResult);
}
return asyncResult;
}
}