Add ability to create memoized functions with custom maps
- Remove cast in ResolveSession class
This commit is contained in:
committed by
Nikolay Krasko
parent
edee61f2f5
commit
a456f9d22e
@@ -117,8 +117,9 @@ public class ResolveSession implements KotlinCodeAnalyzer {
|
|||||||
@NotNull DeclarationProviderFactory declarationProviderFactory,
|
@NotNull DeclarationProviderFactory declarationProviderFactory,
|
||||||
@NotNull BindingTrace delegationTrace
|
@NotNull BindingTrace delegationTrace
|
||||||
) {
|
) {
|
||||||
LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager = new LockBasedLazyResolveStorageManager(
|
LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager =
|
||||||
(LockBasedStorageManager) globalContext.getStorageManager());
|
new LockBasedLazyResolveStorageManager(globalContext.getStorageManager());
|
||||||
|
|
||||||
this.storageManager = lockBasedLazyResolveStorageManager;
|
this.storageManager = lockBasedLazyResolveStorageManager;
|
||||||
this.exceptionTracker = globalContext.getExceptionTracker();
|
this.exceptionTracker = globalContext.getExceptionTracker();
|
||||||
this.trace = lockBasedLazyResolveStorageManager.createSafeTrace(delegationTrace);
|
this.trace = lockBasedLazyResolveStorageManager.createSafeTrace(delegationTrace);
|
||||||
|
|||||||
+93
-82
@@ -32,15 +32,15 @@ import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
|
|||||||
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
// This class is kept under the same package as LockBasedStorageManager to get access to its protected members
|
// 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
|
// Otherwise wed have to expose the lock which is worse than have such a hackish class placement
|
||||||
public class LockBasedLazyResolveStorageManager implements LazyResolveStorageManager {
|
public class LockBasedLazyResolveStorageManager implements LazyResolveStorageManager {
|
||||||
|
|
||||||
private final LockBasedStorageManager storageManager;
|
private final StorageManager storageManager;
|
||||||
|
|
||||||
public LockBasedLazyResolveStorageManager(@NotNull LockBasedStorageManager storageManager) {
|
public LockBasedLazyResolveStorageManager(@NotNull StorageManager storageManager) {
|
||||||
this.storageManager = storageManager;
|
this.storageManager = storageManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,24 @@ public class LockBasedLazyResolveStorageManager implements LazyResolveStorageMan
|
|||||||
public BindingTrace createSafeTrace(@NotNull BindingTrace originalTrace) {
|
public BindingTrace createSafeTrace(@NotNull BindingTrace originalTrace) {
|
||||||
// It seems safe to have a separate lock for traces:
|
// It seems safe to have a separate lock for traces:
|
||||||
// no other locks will be acquired inside the trace operations
|
// no other locks will be acquired inside the trace operations
|
||||||
return new LockProtectedTrace(storageManager.lock, originalTrace);
|
|
||||||
|
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
|
@NotNull
|
||||||
@@ -135,73 +152,69 @@ public class LockBasedLazyResolveStorageManager implements LazyResolveStorageMan
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class LockProtectedContext implements BindingContext {
|
private static class LockProtectedContext implements BindingContext {
|
||||||
private final Lock lock;
|
private final StorageManager storageManager;
|
||||||
private final BindingContext context;
|
private final BindingContext context;
|
||||||
|
|
||||||
private LockProtectedContext(Lock lock, BindingContext context) {
|
private LockProtectedContext(StorageManager storageManager, BindingContext context) {
|
||||||
this.lock = lock;
|
this.storageManager = storageManager;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Diagnostics getDiagnostics() {
|
public Diagnostics getDiagnostics() {
|
||||||
lock.lock();
|
return storageManager.compute(new Function0<Diagnostics>() {
|
||||||
try {
|
@Override
|
||||||
return context.getDiagnostics();
|
public Diagnostics invoke() {
|
||||||
}
|
return context.getDiagnostics();
|
||||||
finally {
|
}
|
||||||
lock.unlock();
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
|
public <K, V> V get(final ReadOnlySlice<K, V> slice, final K key) {
|
||||||
lock.lock();
|
return storageManager.compute(new Function0<V>() {
|
||||||
try {
|
@Override
|
||||||
return context.get(slice, key);
|
public V invoke() {
|
||||||
}
|
return context.get(slice, key);
|
||||||
finally {
|
}
|
||||||
lock.unlock();
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
|
public <K, V> Collection<K> getKeys(final WritableSlice<K, V> slice) {
|
||||||
lock.lock();
|
return storageManager.compute(new Function0<Collection<K>>() {
|
||||||
try {
|
@Override
|
||||||
return context.getKeys(slice);
|
public Collection<K> invoke() {
|
||||||
}
|
return context.getKeys(slice);
|
||||||
finally {
|
}
|
||||||
lock.unlock();
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
@TestOnly
|
@TestOnly
|
||||||
public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull ReadOnlySlice<K, V> slice) {
|
public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull final ReadOnlySlice<K, V> slice) {
|
||||||
lock.lock();
|
return storageManager.compute(new Function0<ImmutableMap<K, V>>() {
|
||||||
try {
|
@Override
|
||||||
return context.getSliceContents(slice);
|
public ImmutableMap<K, V> invoke() {
|
||||||
}
|
return context.getSliceContents(slice);
|
||||||
finally {
|
}
|
||||||
lock.unlock();
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class LockProtectedTrace implements BindingTrace {
|
private static class LockProtectedTrace implements BindingTrace {
|
||||||
private final Lock lock;
|
|
||||||
private final BindingTrace trace;
|
private final BindingTrace trace;
|
||||||
private final BindingContext context;
|
private final BindingContext context;
|
||||||
|
private final StorageManager storageManager;
|
||||||
|
|
||||||
public LockProtectedTrace(@NotNull Lock lock, @NotNull BindingTrace trace) {
|
public LockProtectedTrace(@NotNull StorageManager storageManager, @NotNull BindingTrace trace) {
|
||||||
this.lock = lock;
|
this.storageManager = storageManager;
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
this.context = new LockProtectedContext(lock, trace.getBindingContext());
|
this.context = new LockProtectedContext(storageManager, trace.getBindingContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -211,60 +224,58 @@ public class LockBasedLazyResolveStorageManager implements LazyResolveStorageMan
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
|
public <K, V> void record(final WritableSlice<K, V> slice, final K key, final V value) {
|
||||||
lock.lock();
|
storageManager.compute(new Function0<Unit>() {
|
||||||
try {
|
@Override
|
||||||
trace.record(slice, key, value);
|
public Unit invoke() {
|
||||||
}
|
trace.record(slice, key, value);
|
||||||
finally {
|
return Unit.INSTANCE$;
|
||||||
lock.unlock();
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <K> void record(WritableSlice<K, Boolean> slice, K key) {
|
public <K> void record(final WritableSlice<K, Boolean> slice, final K key) {
|
||||||
lock.lock();
|
storageManager.compute(new Function0<Unit>() {
|
||||||
try {
|
@Override
|
||||||
trace.record(slice, key);
|
public Unit invoke() {
|
||||||
}
|
trace.record(slice, key);
|
||||||
finally {
|
return Unit.INSTANCE$;
|
||||||
lock.unlock();
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
|
public <K, V> V get(final ReadOnlySlice<K, V> slice, final K key) {
|
||||||
lock.lock();
|
return storageManager.compute(new Function0<V>() {
|
||||||
try {
|
@Override
|
||||||
return trace.get(slice, key);
|
public V invoke() {
|
||||||
}
|
return trace.get(slice, key);
|
||||||
finally {
|
}
|
||||||
lock.unlock();
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
|
public <K, V> Collection<K> getKeys(final WritableSlice<K, V> slice) {
|
||||||
lock.lock();
|
return storageManager.compute(new Function0<Collection<K>>() {
|
||||||
try {
|
@Override
|
||||||
return trace.getKeys(slice);
|
public Collection<K> invoke() {
|
||||||
}
|
return trace.getKeys(slice);
|
||||||
finally {
|
}
|
||||||
lock.unlock();
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void report(@NotNull Diagnostic diagnostic) {
|
public void report(@NotNull final Diagnostic diagnostic) {
|
||||||
lock.lock();
|
storageManager.compute(new Function0<Unit>() {
|
||||||
try {
|
@Override
|
||||||
trace.report(diagnostic);
|
public Unit invoke() {
|
||||||
}
|
trace.report(diagnostic);
|
||||||
finally {
|
return Unit.INSTANCE$;
|
||||||
lock.unlock();
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,7 @@ import org.jetbrains.jet.storage.MemoizedFunctionToNotNull
|
|||||||
import org.jetbrains.jet.storage.MemoizedFunctionToNullable
|
import org.jetbrains.jet.storage.MemoizedFunctionToNullable
|
||||||
import org.jetbrains.jet.storage.NotNullLazyValue
|
import org.jetbrains.jet.storage.NotNullLazyValue
|
||||||
import org.jetbrains.jet.storage.NullableLazyValue
|
import org.jetbrains.jet.storage.NullableLazyValue
|
||||||
|
import java.util.concurrent.ConcurrentMap
|
||||||
|
|
||||||
public class LoggingStorageManager(
|
public class LoggingStorageManager(
|
||||||
private val delegate: StorageManager,
|
private val delegate: StorageManager,
|
||||||
@@ -138,6 +139,14 @@ public class LoggingStorageManager(
|
|||||||
return delegate.createMemoizedFunctionWithNullableValues(compute.logged)
|
return delegate.createMemoizedFunctionWithNullableValues(compute.logged)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createMemoizedFunction<K, V: Any>(compute: (K) -> V, map: ConcurrentMap<K, Any>): MemoizedFunctionToNotNull<K, V> {
|
||||||
|
return delegate.createMemoizedFunction(compute.logged, map)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createMemoizedFunctionWithNullableValues<K, V: Any>(compute: (K) -> V, map: ConcurrentMap<K, Any>): MemoizedFunctionToNullable<K, V> {
|
||||||
|
return delegate.createMemoizedFunctionWithNullableValues(compute.logged, map)
|
||||||
|
}
|
||||||
|
|
||||||
override fun createLazyValue<T: Any>(computable: () -> T): NotNullLazyValue<T> {
|
override fun createLazyValue<T: Any>(computable: () -> T): NotNullLazyValue<T> {
|
||||||
return delegate.createLazyValue(computable.logged)
|
return delegate.createLazyValue(computable.logged)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import java.util.concurrent.locks.Lock;
|
|||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public class LockBasedStorageManager implements StorageManager {
|
public class LockBasedStorageManager implements StorageManager {
|
||||||
|
|
||||||
public interface ExceptionHandlingStrategy {
|
public interface ExceptionHandlingStrategy {
|
||||||
ExceptionHandlingStrategy THROW = new ExceptionHandlingStrategy() {
|
ExceptionHandlingStrategy THROW = new ExceptionHandlingStrategy() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -105,7 +104,8 @@ public class LockBasedStorageManager implements StorageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected <K, V> MemoizedFunctionToNotNull<K, V> createMemoizedFunction(
|
@Override
|
||||||
|
public <K, V> MemoizedFunctionToNotNull<K, V> createMemoizedFunction(
|
||||||
@NotNull Function1<? super K, ? extends V> compute,
|
@NotNull Function1<? super K, ? extends V> compute,
|
||||||
@NotNull ConcurrentMap<K, Object> map
|
@NotNull ConcurrentMap<K, Object> map
|
||||||
) {
|
) {
|
||||||
@@ -118,14 +118,9 @@ public class LockBasedStorageManager implements StorageManager {
|
|||||||
return createMemoizedFunctionWithNullableValues(compute, LockBasedStorageManager.<K>createConcurrentHashMap());
|
return createMemoizedFunctionWithNullableValues(compute, LockBasedStorageManager.<K>createConcurrentHashMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
private static <K> ConcurrentMap<K, Object> createConcurrentHashMap() {
|
public <K, V> MemoizedFunctionToNullable<K, V> createMemoizedFunctionWithNullableValues(
|
||||||
// memory optimization: fewer segments and entries stored
|
|
||||||
return new ConcurrentHashMap<K, Object>(3, 1, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
protected <K, V> MemoizedFunctionToNullable<K, V> createMemoizedFunctionWithNullableValues(
|
|
||||||
@NotNull Function1<? super K, ? extends V> compute,
|
@NotNull Function1<? super K, ? extends V> compute,
|
||||||
@NotNull ConcurrentMap<K, Object> map
|
@NotNull ConcurrentMap<K, Object> map
|
||||||
) {
|
) {
|
||||||
@@ -221,6 +216,12 @@ public class LockBasedStorageManager implements StorageManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static <K> ConcurrentMap<K, Object> createConcurrentHashMap() {
|
||||||
|
// memory optimization: fewer segments and entries stored
|
||||||
|
return new ConcurrentHashMap<K, Object>(3, 1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected <T> RecursionDetectedResult<T> recursionDetectedDefault() {
|
protected <T> RecursionDetectedResult<T> recursionDetectedDefault() {
|
||||||
throw new IllegalStateException("Recursive call in a lazy value under " + this);
|
throw new IllegalStateException("Recursive call in a lazy value under " + this);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.storage
|
package org.jetbrains.jet.storage
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentMap
|
||||||
|
|
||||||
public trait StorageManager {
|
public trait StorageManager {
|
||||||
/**
|
/**
|
||||||
@@ -30,6 +31,10 @@ public trait StorageManager {
|
|||||||
|
|
||||||
public fun createMemoizedFunctionWithNullableValues<K, V: Any>(compute: (K) -> V?): MemoizedFunctionToNullable<K, V>
|
public fun createMemoizedFunctionWithNullableValues<K, V: Any>(compute: (K) -> V?): MemoizedFunctionToNullable<K, V>
|
||||||
|
|
||||||
|
public fun createMemoizedFunction<K, V: Any>(compute: (K) -> V, map: ConcurrentMap<K, Any>): MemoizedFunctionToNotNull<K, V>
|
||||||
|
|
||||||
|
public fun createMemoizedFunctionWithNullableValues<K, V: Any>(compute: (K) -> V, map: ConcurrentMap<K, Any>): MemoizedFunctionToNullable<K, V>
|
||||||
|
|
||||||
public fun createLazyValue<T: Any>(computable: () -> T): NotNullLazyValue<T>
|
public fun createLazyValue<T: Any>(computable: () -> T): NotNullLazyValue<T>
|
||||||
|
|
||||||
public fun createRecursionTolerantLazyValue<T: Any>(computable: () -> T, onRecursiveCall: T): NotNullLazyValue<T>
|
public fun createRecursionTolerantLazyValue<T: Any>(computable: () -> T, onRecursiveCall: T): NotNullLazyValue<T>
|
||||||
|
|||||||
Reference in New Issue
Block a user