All storage-related code moved to util.runtime
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.utils.ExceptionUtils;
|
||||
import org.jetbrains.jet.utils.WrappedValues;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class LockBasedStorageManager implements StorageManager {
|
||||
|
||||
protected final Object lock = new Object() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LockBasedStorageManager centralized lock";
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <K, V> MemoizedFunctionToNotNull<K, V> createMemoizedFunction(
|
||||
@NotNull Function<K, V> compute, @NotNull ReferenceKind valuesReferenceKind
|
||||
) {
|
||||
ConcurrentMap<K, Object> map = createConcurrentMap(valuesReferenceKind);
|
||||
return new MapBasedMemoizedFunctionToNotNull<K, V>(lock, map, compute);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <K, V> MemoizedFunctionToNullable<K, V> createMemoizedFunctionWithNullableValues(
|
||||
@NotNull Function<K, V> compute, @NotNull ReferenceKind valuesReferenceKind
|
||||
) {
|
||||
ConcurrentMap<K, Object> map = createConcurrentMap(valuesReferenceKind);
|
||||
return new MapBasedMemoizedFunction<K, V>(lock, map, compute);
|
||||
}
|
||||
|
||||
private static <K, V> ConcurrentMap<K, V> createConcurrentMap(ReferenceKind referenceKind) {
|
||||
return (referenceKind == ReferenceKind.WEAK) ? new ConcurrentWeakValueHashMap<K, V>() : new ConcurrentHashMap<K, V>();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> NotNullLazyValue<T> createLazyValue(@NotNull Computable<T> computable) {
|
||||
return new LockBasedNotNullLazyValue<T>(lock, computable);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> NotNullLazyValue<T> createRecursionTolerantLazyValue(
|
||||
@NotNull Computable<T> computable, @NotNull final T onRecursiveCall
|
||||
) {
|
||||
return new LockBasedNotNullLazyValue<T>(lock, computable) {
|
||||
@Override
|
||||
protected Object recursionDetected() {
|
||||
return onRecursiveCall;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> NotNullLazyValue<T> createLazyValueWithPostCompute(
|
||||
@NotNull Computable<T> computable,
|
||||
final Computable<Object> onRecursiveCall,
|
||||
@NotNull final Consumer<T> postCompute
|
||||
) {
|
||||
return new LockBasedNotNullLazyValue<T>(lock, computable) {
|
||||
@Nullable
|
||||
@Override
|
||||
protected Object recursionDetected() {
|
||||
if (onRecursiveCall == null) {
|
||||
return super.recursionDetected();
|
||||
}
|
||||
return onRecursiveCall.compute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postCompute(@NotNull T value) {
|
||||
postCompute.consume(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> NullableLazyValue<T> createNullableLazyValue(@NotNull Computable<T> computable) {
|
||||
return new LockBasedLazyValue<T>(lock, computable);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(@NotNull Computable<T> computable, final T onRecursiveCall) {
|
||||
return new LockBasedLazyValue<T>(lock, computable) {
|
||||
@Override
|
||||
protected Object recursionDetected() {
|
||||
return onRecursiveCall;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> NullableLazyValue<T> createNullableLazyValueWithPostCompute(
|
||||
@NotNull Computable<T> computable, @NotNull final Consumer<T> postCompute
|
||||
) {
|
||||
return new LockBasedLazyValue<T>(lock, computable) {
|
||||
@Override
|
||||
protected void postCompute(@Nullable T value) {
|
||||
postCompute.consume(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T compute(@NotNull Computable<T> computable) {
|
||||
synchronized (lock) {
|
||||
return computable.compute();
|
||||
}
|
||||
}
|
||||
|
||||
private static class LockBasedLazyValue<T> implements NullableLazyValue<T> {
|
||||
|
||||
private static final Object NOT_COMPUTED = new Object();
|
||||
private static final Object COMPUTING = new Object();
|
||||
|
||||
private final Object lock;
|
||||
private final Computable<T> computable;
|
||||
|
||||
@Nullable
|
||||
private volatile Object value = NOT_COMPUTED;
|
||||
|
||||
public LockBasedLazyValue(@NotNull Object lock, @NotNull Computable<T> computable) {
|
||||
this.lock = lock;
|
||||
this.computable = computable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T compute() {
|
||||
Object _value = value;
|
||||
if (_value != NOT_COMPUTED && _value != COMPUTING) return WrappedValues.unescapeThrowable(_value);
|
||||
|
||||
synchronized (lock) {
|
||||
_value = value;
|
||||
if (_value == COMPUTING) {
|
||||
Object result = recursionDetected();
|
||||
if (result != NOT_COMPUTED) {
|
||||
return WrappedValues.unescapeThrowable(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (_value != NOT_COMPUTED) return WrappedValues.unescapeThrowable(_value);
|
||||
|
||||
value = COMPUTING;
|
||||
try {
|
||||
T typedValue = computable.compute();
|
||||
value = typedValue;
|
||||
postCompute(typedValue);
|
||||
return typedValue;
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
value = WrappedValues.escapeThrowable(throwable);
|
||||
throw ExceptionUtils.rethrow(throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code NOT_COMPUTED} to proceed, a value or wrapped exception otherwise, see WrappedValues
|
||||
* @throws DO NOT throw exceptions from implementations of this method, instead return WrappedValues.escapeThrowable(exception)
|
||||
*/
|
||||
@Nullable
|
||||
protected Object recursionDetected() {
|
||||
return WrappedValues.escapeThrowable(new IllegalStateException("Recursive call in a lazy value"));
|
||||
}
|
||||
|
||||
protected void postCompute(T value) {
|
||||
// Doing something in post-compute helps prevent infinite recursion
|
||||
}
|
||||
}
|
||||
|
||||
private static class LockBasedNotNullLazyValue<T> extends LockBasedLazyValue<T> implements NotNullLazyValue<T> {
|
||||
|
||||
public LockBasedNotNullLazyValue(@NotNull Object lock, @NotNull Computable<T> computable) {
|
||||
super(lock, computable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public T compute() {
|
||||
T result = super.compute();
|
||||
assert result != null : "compute() returned null";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MapBasedMemoizedFunction<K, V> implements MemoizedFunctionToNullable<K, V> {
|
||||
private final Object lock;
|
||||
private final ConcurrentMap<K, Object> cache;
|
||||
private final Function<K, V> compute;
|
||||
|
||||
public MapBasedMemoizedFunction(@NotNull Object lock, @NotNull ConcurrentMap<K, Object> map, @NotNull Function<K, V> compute) {
|
||||
this.lock = lock;
|
||||
this.cache = map;
|
||||
this.compute = compute;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public V fun(@NotNull K input) {
|
||||
Object value = cache.get(input);
|
||||
if (value != null) return WrappedValues.unescapeExceptionOrNull(value);
|
||||
|
||||
synchronized (lock) {
|
||||
value = cache.get(input);
|
||||
if (value != null) return WrappedValues.unescapeExceptionOrNull(value);
|
||||
|
||||
try {
|
||||
V typedValue = compute.fun(input);
|
||||
Object oldValue = cache.put(input, WrappedValues.escapeNull(typedValue));
|
||||
assert oldValue == null : "Race condition detected";
|
||||
|
||||
return typedValue;
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
Object oldValue = cache.put(input, WrappedValues.escapeThrowable(throwable));
|
||||
assert oldValue == null : "Race condition detected";
|
||||
|
||||
throw ExceptionUtils.rethrow(throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MapBasedMemoizedFunctionToNotNull<K, V> extends MapBasedMemoizedFunction<K, V> implements MemoizedFunctionToNotNull<K, V> {
|
||||
|
||||
public MapBasedMemoizedFunctionToNotNull(
|
||||
@NotNull Object lock,
|
||||
@NotNull ConcurrentMap<K, Object> map,
|
||||
@NotNull Function<K, V> compute
|
||||
) {
|
||||
super(lock, map, compute);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public V fun(@NotNull K input) {
|
||||
V result = super.fun(input);
|
||||
assert result != null : "compute() returned null";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.storage;
|
||||
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface MemoizedFunctionToNotNull<P, R> extends Function<P, R> {
|
||||
@Override
|
||||
@NotNull
|
||||
R fun(P p);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.storage;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class MemoizedFunctionToNotNullImpl<K, V> extends MemoizedFunctionToNullableImpl<K, V> implements
|
||||
MemoizedFunctionToNotNull<K, V> {
|
||||
|
||||
public MemoizedFunctionToNotNullImpl() {
|
||||
}
|
||||
|
||||
public MemoizedFunctionToNotNullImpl(@NotNull Map<K, Object> map) {
|
||||
super(map);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public V fun(K input) {
|
||||
V result = super.fun(input);
|
||||
assert result != null : "compute() returned null";
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected abstract V doCompute(K input);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.storage;
|
||||
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface MemoizedFunctionToNullable<P, R> extends Function<P, R> {
|
||||
@Override
|
||||
@Nullable
|
||||
R fun(P p);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.storage;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.storage.MemoizedFunctionToNullable;
|
||||
import org.jetbrains.jet.utils.WrappedValues;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class MemoizedFunctionToNullableImpl<K, V> implements MemoizedFunctionToNullable<K, V> {
|
||||
private final Map<K, Object> cache;
|
||||
|
||||
public MemoizedFunctionToNullableImpl() {
|
||||
this(new HashMap<K, Object>());
|
||||
}
|
||||
|
||||
public MemoizedFunctionToNullableImpl(@NotNull Map<K, Object> map) {
|
||||
this.cache = map;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public V fun(K input) {
|
||||
Object value = cache.get(input);
|
||||
if (value != null) return WrappedValues.unescapeNull(value);
|
||||
|
||||
V typedValue = doCompute(input);
|
||||
|
||||
Object oldValue = cache.put(input, WrappedValues.escapeNull(typedValue));
|
||||
assert oldValue == null : "Race condition detected";
|
||||
|
||||
return typedValue;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract V doCompute(K input);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.storage;
|
||||
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface NotNullLazyValue<T> extends Computable<T> {
|
||||
@Override
|
||||
@NotNull
|
||||
T compute();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.storage;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class NotNullLazyValueImpl<T> extends NullableLazyValueImpl<T> implements NotNullLazyValue<T> {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public T compute() {
|
||||
T result = super.compute();
|
||||
assert result != null : "compute() returned null";
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected abstract T doCompute();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.storage;
|
||||
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface NullableLazyValue<T> extends Computable<T> {
|
||||
@Override
|
||||
@Nullable
|
||||
T compute();
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.storage;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.storage.NullableLazyValue;
|
||||
import org.jetbrains.jet.utils.WrappedValues;
|
||||
|
||||
public abstract class NullableLazyValueImpl<T> implements NullableLazyValue<T> {
|
||||
@Nullable
|
||||
private Object value = null;
|
||||
|
||||
@Override
|
||||
public T compute() {
|
||||
Object _value = value;
|
||||
if (_value != null) return WrappedValues.unescapeNull(_value);
|
||||
|
||||
T typedValue = doCompute();
|
||||
value = WrappedValues.escapeNull(typedValue);
|
||||
|
||||
postCompute(typedValue);
|
||||
|
||||
return typedValue;
|
||||
}
|
||||
|
||||
protected abstract T doCompute();
|
||||
|
||||
protected void postCompute(T value) {
|
||||
// Doing something in post-compute helps prevent infinite recursion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.storage;
|
||||
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface StorageManager {
|
||||
/**
|
||||
* Given a function compute: K -> V create a memoized version of it that computes a value only once for each key
|
||||
* @param compute the function to be memoized
|
||||
* @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);
|
||||
@NotNull
|
||||
<K, V> MemoizedFunctionToNullable<K, V> createMemoizedFunctionWithNullableValues(@NotNull Function<K, V> compute, @NotNull ReferenceKind valuesReferenceKind);
|
||||
|
||||
@NotNull
|
||||
<T> NotNullLazyValue<T> createLazyValue(@NotNull Computable<T> computable);
|
||||
|
||||
@NotNull
|
||||
<T> NotNullLazyValue<T> createRecursionTolerantLazyValue(@NotNull Computable<T> computable, @NotNull T onRecursiveCall);
|
||||
|
||||
/**
|
||||
* @param onRecursiveCall is called if the computation calls itself recursively.
|
||||
* If this parameter is null, an exception will be thrown on a recursive call,
|
||||
* otherwise it should return a result of WrappedValues.escapeThrowable() method
|
||||
* @param 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> NotNullLazyValue<T> createLazyValueWithPostCompute(
|
||||
@NotNull Computable<T> computable,
|
||||
@Nullable Computable<Object> onRecursiveCall,
|
||||
@NotNull Consumer<T> postCompute
|
||||
);
|
||||
|
||||
@NotNull
|
||||
<T> NullableLazyValue<T> createNullableLazyValue(@NotNull Computable<T> computable);
|
||||
|
||||
@NotNull
|
||||
<T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(@NotNull Computable<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> T compute(@NotNull Computable<T> computable);
|
||||
|
||||
enum ReferenceKind {
|
||||
STRONG,
|
||||
WEAK
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user