StorageManager API does not use Computable and Function and more

This commit is contained in:
Andrey Breslav
2013-10-04 19:52:17 +04:00
committed by Alexander Udalov
parent 7d1c46ed2c
commit 239ca9728d
29 changed files with 284 additions and 269 deletions
@@ -16,10 +16,9 @@
package org.jetbrains.jet.storage;
import com.intellij.openapi.util.Computable;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.containers.ConcurrentWeakValueHashMap;
import jet.Function0;
import jet.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.utils.ExceptionUtils;
@@ -52,7 +51,7 @@ public class LockBasedStorageManager implements StorageManager {
@NotNull
@Override
public <K, V> MemoizedFunctionToNotNull<K, V> createMemoizedFunction(
@NotNull Function<K, V> compute, @NotNull ReferenceKind valuesReferenceKind
@NotNull Function1<K, V> compute, @NotNull ReferenceKind valuesReferenceKind
) {
ConcurrentMap<K, Object> map = createConcurrentMap(valuesReferenceKind);
return new MapBasedMemoizedFunctionToNotNull<K, V>(lock, map, compute);
@@ -61,7 +60,7 @@ public class LockBasedStorageManager implements StorageManager {
@NotNull
@Override
public <K, V> MemoizedFunctionToNullable<K, V> createMemoizedFunctionWithNullableValues(
@NotNull Function<K, V> compute, @NotNull ReferenceKind valuesReferenceKind
@NotNull Function1<K, V> compute, @NotNull ReferenceKind valuesReferenceKind
) {
ConcurrentMap<K, Object> map = createConcurrentMap(valuesReferenceKind);
return new MapBasedMemoizedFunction<K, V>(lock, map, compute);
@@ -73,14 +72,14 @@ public class LockBasedStorageManager implements StorageManager {
@NotNull
@Override
public <T> NotNullLazyValue<T> createLazyValue(@NotNull Computable<T> computable) {
public <T> NotNullLazyValue<T> createLazyValue(@NotNull Function0<T> computable) {
return new LockBasedNotNullLazyValue<T>(lock, computable);
}
@NotNull
@Override
public <T> NotNullLazyValue<T> createRecursionTolerantLazyValue(
@NotNull Computable<T> computable, @NotNull final T onRecursiveCall
@NotNull Function0<T> computable, @NotNull final T onRecursiveCall
) {
return new LockBasedNotNullLazyValue<T>(lock, computable) {
@Override
@@ -93,9 +92,9 @@ public class LockBasedStorageManager implements StorageManager {
@NotNull
@Override
public <T> NotNullLazyValue<T> createLazyValueWithPostCompute(
@NotNull Computable<T> computable,
final Function<Boolean, T> onRecursiveCall,
@NotNull final Consumer<T> postCompute
@NotNull Function0<T> computable,
final Function1<Boolean, T> onRecursiveCall,
@NotNull final Function1<T, Void> postCompute
) {
return new LockBasedNotNullLazyValue<T>(lock, computable) {
@Nullable
@@ -104,25 +103,25 @@ public class LockBasedStorageManager implements StorageManager {
if (onRecursiveCall == null) {
return super.recursionDetected(firstTime);
}
return onRecursiveCall.fun(firstTime);
return onRecursiveCall.invoke(firstTime);
}
@Override
protected void postCompute(@NotNull T value) {
postCompute.consume(value);
postCompute.invoke(value);
}
};
}
@NotNull
@Override
public <T> NullableLazyValue<T> createNullableLazyValue(@NotNull Computable<T> computable) {
public <T> NullableLazyValue<T> createNullableLazyValue(@NotNull Function0<T> computable) {
return new LockBasedLazyValue<T>(lock, computable);
}
@NotNull
@Override
public <T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(@NotNull Computable<T> computable, final T onRecursiveCall) {
public <T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(@NotNull Function0<T> computable, final T onRecursiveCall) {
return new LockBasedLazyValue<T>(lock, computable) {
@Override
protected T recursionDetected(boolean firstTime) {
@@ -134,21 +133,21 @@ public class LockBasedStorageManager implements StorageManager {
@NotNull
@Override
public <T> NullableLazyValue<T> createNullableLazyValueWithPostCompute(
@NotNull Computable<T> computable, @NotNull final Consumer<T> postCompute
@NotNull Function0<T> computable, @NotNull final Function1<T, Void> postCompute
) {
return new LockBasedLazyValue<T>(lock, computable) {
@Override
protected void postCompute(@Nullable T value) {
postCompute.consume(value);
postCompute.invoke(value);
}
};
}
@Override
public <T> T compute(@NotNull Computable<T> computable) {
public <T> T compute(@NotNull Function0<T> computable) {
lock.lock();
try {
return computable.compute();
return computable.invoke();
}
finally {
lock.unlock();
@@ -164,12 +163,12 @@ public class LockBasedStorageManager implements StorageManager {
}
private final Lock lock;
private final Computable<T> computable;
private final Function0<T> computable;
@Nullable
private volatile Object value = NotValue.NOT_COMPUTED;
public LockBasedLazyValue(@NotNull Lock lock, @NotNull Computable<T> computable) {
public LockBasedLazyValue(@NotNull Lock lock, @NotNull Function0<T> computable) {
this.lock = lock;
this.computable = computable;
}
@@ -200,7 +199,7 @@ public class LockBasedStorageManager implements StorageManager {
value = NotValue.COMPUTING;
try {
T typedValue = computable.compute();
T typedValue = computable.invoke();
value = typedValue;
postCompute(typedValue);
return typedValue;
@@ -234,7 +233,7 @@ public class LockBasedStorageManager implements StorageManager {
private static class LockBasedNotNullLazyValue<T> extends LockBasedLazyValue<T> implements NotNullLazyValue<T> {
public LockBasedNotNullLazyValue(@NotNull Lock lock, @NotNull Computable<T> computable) {
public LockBasedNotNullLazyValue(@NotNull Lock lock, @NotNull Function0<T> computable) {
super(lock, computable);
}
@@ -250,9 +249,9 @@ public class LockBasedStorageManager implements StorageManager {
private static class MapBasedMemoizedFunction<K, V> implements MemoizedFunctionToNullable<K, V> {
private final Lock lock;
private final ConcurrentMap<K, Object> cache;
private final Function<K, V> compute;
private final Function1<K, V> compute;
public MapBasedMemoizedFunction(@NotNull Lock lock, @NotNull ConcurrentMap<K, Object> map, @NotNull Function<K, V> compute) {
public MapBasedMemoizedFunction(@NotNull Lock lock, @NotNull ConcurrentMap<K, Object> map, @NotNull Function1<K, V> compute) {
this.lock = lock;
this.cache = map;
this.compute = compute;
@@ -270,7 +269,7 @@ public class LockBasedStorageManager implements StorageManager {
if (value != null) return WrappedValues.unescapeExceptionOrNull(value);
try {
V typedValue = compute.fun(input);
V typedValue = compute.invoke(input);
Object oldValue = cache.put(input, WrappedValues.escapeNull(typedValue));
assert oldValue == null : "Race condition detected";
@@ -294,7 +293,7 @@ public class LockBasedStorageManager implements StorageManager {
public MapBasedMemoizedFunctionToNotNull(
@NotNull Lock lock,
@NotNull ConcurrentMap<K, Object> map,
@NotNull Function<K, V> compute
@NotNull Function1<K, V> compute
) {
super(lock, map, compute);
}
@@ -16,9 +16,8 @@
package org.jetbrains.jet.storage;
import com.intellij.openapi.util.Computable;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import jet.Function0;
import jet.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -29,20 +28,20 @@ public interface StorageManager {
* @param valuesReferenceKind how to store the memoized values
*
* NOTE: if compute() has side-effects the WEAK reference kind is dangerous: the side-effects will be repeated if
* the value gets collected and then re-computed
*/
@NotNull
<K, V> MemoizedFunctionToNotNull<K, V> createMemoizedFunction(@NotNull Function<K, V> compute, @NotNull ReferenceKind valuesReferenceKind);
<K, V> MemoizedFunctionToNotNull<K, V> createMemoizedFunction(@NotNull Function1<K, V> compute, @NotNull ReferenceKind valuesReferenceKind);
@NotNull
<K, V> MemoizedFunctionToNullable<K, V> createMemoizedFunctionWithNullableValues(@NotNull Function<K, V> compute, @NotNull ReferenceKind valuesReferenceKind);
<K, V> MemoizedFunctionToNullable<K, V> createMemoizedFunctionWithNullableValues(@NotNull Function1<K, V> compute, @NotNull ReferenceKind valuesReferenceKind);
@NotNull
<T> NotNullLazyValue<T> createLazyValue(@NotNull Computable<T> computable);
<T> NotNullLazyValue<T> createLazyValue(@NotNull Function0<T> computable);
@NotNull
<T> NotNullLazyValue<T> createRecursionTolerantLazyValue(@NotNull Computable<T> computable, @NotNull T onRecursiveCall);
<T> NotNullLazyValue<T> createRecursionTolerantLazyValue(@NotNull Function0<T> computable, @NotNull T onRecursiveCall);
/**
* @param computable
* @param onRecursiveCall is called if the computation calls itself recursively.
* The parameter to it is {@code true} for the first call, {@code false} otherwise.
* If {@code onRecursiveCall} is {@code null}, an exception will be thrown on a recursive call,
@@ -51,25 +50,25 @@ public interface StorageManager {
*/
@NotNull
<T> NotNullLazyValue<T> createLazyValueWithPostCompute(
@NotNull Computable<T> computable,
@Nullable Function<Boolean, T> onRecursiveCall,
@NotNull Consumer<T> postCompute
@NotNull Function0<T> computable,
@Nullable Function1<Boolean, T> onRecursiveCall,
@NotNull Function1<T, Void> postCompute
);
@NotNull
<T> NullableLazyValue<T> createNullableLazyValue(@NotNull Computable<T> computable);
<T> NullableLazyValue<T> createNullableLazyValue(@NotNull Function0<T> computable);
@NotNull
<T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(@NotNull Computable<T> computable, @Nullable T onRecursiveCall);
<T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(@NotNull Function0<T> computable, @Nullable T onRecursiveCall);
/**
* {@code postCompute} is called after the value is computed, but before any other thread sees it (the current thread may
* see it in between)
*/
@NotNull
<T> NullableLazyValue<T> createNullableLazyValueWithPostCompute(@NotNull Computable<T> computable, @NotNull Consumer<T> postCompute);
<T> NullableLazyValue<T> createNullableLazyValueWithPostCompute(@NotNull Function0<T> computable, @NotNull Function1<T, Void> postCompute);
<T> T compute(@NotNull Computable<T> computable);
<T> T compute(@NotNull Function0<T> computable);
enum ReferenceKind {
STRONG,
@@ -16,29 +16,36 @@
package org.jetbrains.jet.storage;
import com.intellij.openapi.util.Computable;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import jet.Function0;
import jet.Function1;
import org.jetbrains.annotations.NotNull;
import static org.jetbrains.jet.storage.LockBasedStorageManager.NO_LOCKS;
public class StorageUtil {
private static final Function1 EMPTY_CONSUMER = new Function1<Object, Void>() {
@Override
public Void invoke(Object t) {
return null;
}
};
public static <T> NotNullLazyValue<T> createRecursionIntolerantLazyValueWithDefault(
@NotNull final T defaultValue,
@NotNull Computable<T> compute
@NotNull Function0<T> compute
) {
//noinspection unchecked
return NO_LOCKS.createLazyValueWithPostCompute(
compute,
new Function<Boolean, T>() {
new Function1<Boolean, T>() {
@Override
public T fun(Boolean firstTime) {
public T invoke(Boolean firstTime) {
if (firstTime) throw new ReenteringLazyValueComputationException();
return defaultValue;
}
},
Consumer.EMPTY_CONSUMER
EMPTY_CONSUMER
);
}
}