Rewrite to Kotlin: LockBasedLazyResolveStorageManager

This commit is contained in:
Nikolay Krasko
2014-11-19 19:38:15 +03:00
committed by Nikolay Krasko
parent 2800ab4a12
commit 92d6ac7e7c
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
* Copyright 2010-2014 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.
@@ -14,268 +14,59 @@
* limitations under the License.
*/
package org.jetbrains.jet.storage;
package org.jetbrains.jet.storage
import com.google.common.collect.ImmutableMap;
import com.intellij.util.containers.ConcurrentWeakValueHashMap;
import kotlin.Function0;
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.Diagnostics;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import com.intellij.util.containers.ConcurrentWeakValueHashMap
import org.jetbrains.annotations.TestOnly
import org.jetbrains.jet.lang.diagnostics.Diagnostic
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.resolve.BindingTrace
import org.jetbrains.jet.lang.resolve.Diagnostics
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice
import org.jetbrains.jet.util.slicedmap.WritableSlice
import java.util.Collection;
import java.util.concurrent.ConcurrentMap;
public class LockBasedLazyResolveStorageManager(private val storageManager: StorageManager): StorageManager by storageManager, LazyResolveStorageManager {
override fun <K, V> createWeaklyRetainedMemoizedFunction(compute: Function1<K, V>) =
storageManager.createMemoizedFunction<K, V>(compute, ConcurrentWeakValueHashMap<K, Any>())
// This class is kept under the same package as LockBasedStorageManager to get access to its protected members
// Otherwise wed have to expose the lock which is worse than have such a hackish class placement
public class LockBasedLazyResolveStorageManager implements LazyResolveStorageManager {
override fun <K, V> createWeaklyRetainedMemoizedFunctionWithNullableValues(compute: Function1<K, V>) =
storageManager.createMemoizedFunctionWithNullableValues<K, V>(compute, ConcurrentWeakValueHashMap<K, Any>())
private final StorageManager storageManager;
// It seems safe to have a separate lock for traces:
// no other locks will be acquired inside the trace operations
override fun createSafeTrace(originalTrace: BindingTrace) =
LockProtectedTrace(storageManager, originalTrace)
public LockBasedLazyResolveStorageManager(@NotNull StorageManager storageManager) {
this.storageManager = storageManager;
private class LockProtectedContext(private val storageManager: StorageManager, private val context: BindingContext) : BindingContext {
override fun getDiagnostics(): Diagnostics = storageManager.compute { context.getDiagnostics() }
override fun <K, V> get(slice: ReadOnlySlice<K, V>, key: K) = storageManager.compute { context.get<K, V>(slice, key) }
override fun <K, V> getKeys(slice: WritableSlice<K, V>) = storageManager.compute { context.getKeys<K, V>(slice) }
TestOnly
override fun <K, V> getSliceContents(slice: ReadOnlySlice<K, V>) = storageManager.compute { context.getSliceContents<K, V>(slice) }
}
@Override
@NotNull
public <K, V> MemoizedFunctionToNotNull<K, V> createWeaklyRetainedMemoizedFunction(
@NotNull Function1<K, V> compute
) {
return storageManager.createMemoizedFunction(compute, new ConcurrentWeakValueHashMap<K, Object>());
}
private class LockProtectedTrace(private val storageManager: StorageManager, private val trace: BindingTrace) : BindingTrace {
private val context: BindingContext = LockProtectedContext(storageManager, trace.getBindingContext())
@NotNull
@Override
public <K, V> MemoizedFunctionToNullable<K, V> createWeaklyRetainedMemoizedFunctionWithNullableValues(
@NotNull Function1<K, V> compute
) {
return storageManager.createMemoizedFunctionWithNullableValues(compute, new ConcurrentWeakValueHashMap<K, Object>());
}
override fun getBindingContext() = context
@NotNull
@Override
public BindingTrace createSafeTrace(@NotNull BindingTrace originalTrace) {
// It seems safe to have a separate lock for traces:
// no other locks will be acquired inside the trace operations
return new LockProtectedTrace(storageManager, originalTrace);
}
@NotNull
@Override
public <K, V> MemoizedFunctionToNullable<K, V> createMemoizedFunctionWithNullableValues(
@NotNull Function1<? super K, ? extends V> compute, @NotNull ConcurrentMap<K, Object> map
) {
return storageManager.createMemoizedFunctionWithNullableValues(compute, map);
}
@NotNull
@Override
public <K, V> MemoizedFunctionToNotNull<K, V> createMemoizedFunction(
@NotNull Function1<? super K, ? extends V> compute, @NotNull ConcurrentMap<K, Object> map
) {
return storageManager.createMemoizedFunction(compute, map);
}
@NotNull
@Override
public <K, V> MemoizedFunctionToNotNull<K, V> createMemoizedFunction(@NotNull Function1<? super K, ? extends V> compute) {
return storageManager.createMemoizedFunction(compute);
}
@NotNull
@Override
public <K, V> MemoizedFunctionToNullable<K, V> createMemoizedFunctionWithNullableValues(@NotNull Function1<? super K, ? extends V> compute) {
return storageManager.createMemoizedFunctionWithNullableValues(compute);
}
@NotNull
@Override
public <T> NotNullLazyValue<T> createLazyValue(@NotNull Function0<? extends T> computable) {
return storageManager.createLazyValue(computable);
}
@NotNull
@Override
public <T> NotNullLazyValue<T> createRecursionTolerantLazyValue(
@NotNull Function0<? extends T> computable,
@NotNull T onRecursiveCall
) {
return storageManager.createRecursionTolerantLazyValue(computable, onRecursiveCall);
}
@NotNull
@Override
public <T> NotNullLazyValue<T> createLazyValueWithPostCompute(
@NotNull Function0<? extends T> computable,
@Nullable Function1<? super Boolean, ? extends T> onRecursiveCall,
@NotNull Function1<? super T, ? extends Unit> postCompute
) {
return storageManager.createLazyValueWithPostCompute(computable, onRecursiveCall, postCompute);
}
@NotNull
@Override
public <T> NullableLazyValue<T> createNullableLazyValue(@NotNull Function0<? extends T> computable) {
return storageManager.createNullableLazyValue(computable);
}
@NotNull
@Override
public <T> NullableLazyValue<T> createRecursionTolerantNullableLazyValue(
@NotNull Function0<? extends T> computable,
T onRecursiveCall
) {
return storageManager.createRecursionTolerantNullableLazyValue(computable, onRecursiveCall);
}
@NotNull
@Override
public <T> NullableLazyValue<T> createNullableLazyValueWithPostCompute(
@NotNull Function0<? extends T> computable,
@NotNull Function1<? super T, ? extends Unit> postCompute
) {
return storageManager.createNullableLazyValueWithPostCompute(computable, postCompute);
}
@Override
public <T> T compute(@NotNull Function0<? extends T> computable) {
return storageManager.compute(computable);
}
private static class LockProtectedContext implements BindingContext {
private final StorageManager storageManager;
private final BindingContext context;
private LockProtectedContext(StorageManager storageManager, BindingContext context) {
this.storageManager = storageManager;
this.context = context;
override fun <K, V> record(slice: WritableSlice<K, V>, key: K, value: V) {
storageManager.compute { trace.record<K, V>(slice, key, value) }
}
@NotNull
@Override
public Diagnostics getDiagnostics() {
return storageManager.compute(new Function0<Diagnostics>() {
@Override
public Diagnostics invoke() {
return context.getDiagnostics();
}
});
override fun <K> record(slice: WritableSlice<K, Boolean>, key: K) {
storageManager.compute { trace.record<K>(slice, key) }
}
@Nullable
@Override
public <K, V> V get(final ReadOnlySlice<K, V> slice, final K key) {
return storageManager.compute(new Function0<V>() {
@Override
public V invoke() {
return context.get(slice, key);
}
});
}
override fun <K, V> get(slice: ReadOnlySlice<K, V>, key: K): V = storageManager.compute { trace.get<K, V>(slice, key) }
@NotNull
@Override
public <K, V> Collection<K> getKeys(final WritableSlice<K, V> slice) {
return storageManager.compute(new Function0<Collection<K>>() {
@Override
public Collection<K> invoke() {
return context.getKeys(slice);
}
});
}
override fun <K, V> getKeys(slice: WritableSlice<K, V>): Collection<K> = storageManager.compute { trace.getKeys<K, V>(slice) }
@NotNull
@Override
@TestOnly
public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull final ReadOnlySlice<K, V> slice) {
return storageManager.compute(new Function0<ImmutableMap<K, V>>() {
@Override
public ImmutableMap<K, V> invoke() {
return context.getSliceContents(slice);
}
});
}
}
private static class LockProtectedTrace implements BindingTrace {
private final BindingTrace trace;
private final BindingContext context;
private final StorageManager storageManager;
public LockProtectedTrace(@NotNull StorageManager storageManager, @NotNull BindingTrace trace) {
this.storageManager = storageManager;
this.trace = trace;
this.context = new LockProtectedContext(storageManager, trace.getBindingContext());
}
@NotNull
@Override
public BindingContext getBindingContext() {
return context;
}
@Override
public <K, V> void record(final WritableSlice<K, V> slice, final K key, final V value) {
storageManager.compute(new Function0<Unit>() {
@Override
public Unit invoke() {
trace.record(slice, key, value);
return Unit.INSTANCE$;
}
});
}
@Override
public <K> void record(final WritableSlice<K, Boolean> slice, final K key) {
storageManager.compute(new Function0<Unit>() {
@Override
public Unit invoke() {
trace.record(slice, key);
return Unit.INSTANCE$;
}
});
}
@Override
@Nullable
public <K, V> V get(final ReadOnlySlice<K, V> slice, final K key) {
return storageManager.compute(new Function0<V>() {
@Override
public V invoke() {
return trace.get(slice, key);
}
});
}
@Override
@NotNull
public <K, V> Collection<K> getKeys(final WritableSlice<K, V> slice) {
return storageManager.compute(new Function0<Collection<K>>() {
@Override
public Collection<K> invoke() {
return trace.getKeys(slice);
}
});
}
@Override
public void report(@NotNull final Diagnostic diagnostic) {
storageManager.compute(new Function0<Unit>() {
@Override
public Unit invoke() {
trace.report(diagnostic);
return Unit.INSTANCE$;
}
});
override fun report(diagnostic: Diagnostic) {
storageManager.compute { trace.report(diagnostic) }
}
}
}