Getting rid of createConcurrentCollection in favor of lazy values

This commit is contained in:
Andrey Breslav
2013-02-08 19:14:18 +04:00
parent 6f851845c6
commit fd8da79b88
5 changed files with 92 additions and 109 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve.lazy; package org.jetbrains.jet.lang.resolve.lazy;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.util.Computable;
import com.intellij.util.Function; import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -46,8 +47,12 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
private final Function<Name, Set<FunctionDescriptor>> functionDescriptors; private final Function<Name, Set<FunctionDescriptor>> functionDescriptors;
private final Function<Name, Set<VariableDescriptor>> propertyDescriptors; private final Function<Name, Set<VariableDescriptor>> propertyDescriptors;
private final Collection<DeclarationDescriptor> allDescriptors; private static class AllDescriptors {
protected volatile boolean allDescriptorsComputed = false; private final Collection<DeclarationDescriptor> all = Sets.newLinkedHashSet();
private final Collection<ClassDescriptor> objects = Sets.newLinkedHashSet();
}
private final LazyValue<AllDescriptors> allDescriptors;
protected AbstractLazyMemberScope( protected AbstractLazyMemberScope(
@NotNull ResolveSession resolveSession, @NotNull ResolveSession resolveSession,
@@ -85,7 +90,12 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
} }
}, STRONG); }, STRONG);
this.allDescriptors = storageManager.createConcurrentCollection(); this.allDescriptors = storageManager.createLazyValue(new Computable<AllDescriptors>() {
@Override
public AllDescriptors compute() {
return computeAllDescriptors();
}
});
} }
@Nullable @Nullable
@@ -95,14 +105,8 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
for (JetClassOrObject classOrObjectDeclaration : classOrObjectDeclarations) { for (JetClassOrObject classOrObjectDeclaration : classOrObjectDeclarations) {
if (object != declaresObjectOrEnumConstant(classOrObjectDeclaration)) continue; if (object != declaresObjectOrEnumConstant(classOrObjectDeclaration)) continue;
ClassDescriptor classDescriptor = new LazyClassDescriptor(resolveSession, thisDescriptor, name, return new LazyClassDescriptor(resolveSession, thisDescriptor, name,
JetClassInfoUtil.createClassLikeInfo(classOrObjectDeclaration)); JetClassInfoUtil.createClassLikeInfo(classOrObjectDeclaration));
if (!object) {
registerDescriptor(classDescriptor);
}
return classDescriptor;
} }
return null; return null;
} }
@@ -141,9 +145,6 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
getNonDeclaredFunctions(name, result); getNonDeclaredFunctions(name, result);
if (!result.isEmpty()) {
registerDescriptors(result);
}
return result; return result;
} }
@@ -186,8 +187,6 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
getNonDeclaredProperties(name, result); getNonDeclaredProperties(name, result);
registerDescriptors(result);
return result; return result;
} }
@@ -196,8 +195,7 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
@NotNull @NotNull
@Override @Override
public Collection<ClassDescriptor> getObjectDescriptors() { public Collection<ClassDescriptor> getObjectDescriptors() {
getAllDescriptors(); return allDescriptors.get().objects;
return objectDescriptors.values();
} }
@Override @Override
@@ -223,72 +221,65 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
throw new UnsupportedOperationException(); // TODO throw new UnsupportedOperationException(); // TODO
} }
protected void registerDescriptor(@NotNull DeclarationDescriptor descriptor) {
assert !allDescriptorsComputed : "getAllDescriptors() has been called already";
allDescriptors.add(descriptor);
}
protected void registerDescriptors(@NotNull Collection<? extends DeclarationDescriptor> descriptors) {
assert !allDescriptorsComputed : "getAllDescriptors() has been called already";
allDescriptors.addAll(descriptors);
}
@NotNull @NotNull
@Override @Override
public Collection<DeclarationDescriptor> getAllDescriptors() { public Collection<DeclarationDescriptor> getAllDescriptors() {
if (!allDescriptorsComputed) { return allDescriptors.get().all;
for (JetDeclaration declaration : declarationProvider.getAllDeclarations()) {
if (declaration instanceof JetEnumEntry) {
JetEnumEntry jetEnumEntry = (JetEnumEntry) declaration;
Name name = safeNameForLazyResolve(jetEnumEntry);
if (name != null) {
getProperties(name);
getObjectDescriptor(name);
}
}
else if (declaration instanceof JetObjectDeclaration) {
JetObjectDeclaration objectDeclaration = (JetObjectDeclaration) declaration;
Name name = safeNameForLazyResolve(objectDeclaration.getNameAsDeclaration());
if (name != null) {
getProperties(name);
getObjectDescriptor(name);
}
}
else if (declaration instanceof JetClassOrObject) {
JetClassOrObject classOrObject = (JetClassOrObject) declaration;
Name name = safeNameForLazyResolve(classOrObject.getNameAsName());
if (name != null) {
getClassifier(name);
}
}
else if (declaration instanceof JetFunction) {
JetFunction function = (JetFunction) declaration;
getFunctions(safeNameForLazyResolve(function));
}
else if (declaration instanceof JetProperty) {
JetProperty property = (JetProperty) declaration;
getProperties(safeNameForLazyResolve(property));
}
else if (declaration instanceof JetParameter) {
JetParameter parameter = (JetParameter) declaration;
Name name = safeNameForLazyResolve(parameter);
getProperties(name);
}
else if (declaration instanceof JetTypedef || declaration instanceof JetMultiDeclaration) {
// Do nothing for typedefs as they are not supported.
// MultiDeclarations are not supported on global level too.
}
else {
throw new IllegalArgumentException("Unsupported declaration kind: " + declaration);
}
}
addExtraDescriptors();
allDescriptorsComputed = true;
}
return allDescriptors;
} }
protected abstract void addExtraDescriptors(); @NotNull
private AllDescriptors computeAllDescriptors() {
AllDescriptors result = new AllDescriptors();
for (JetDeclaration declaration : declarationProvider.getAllDeclarations()) {
if (declaration instanceof JetEnumEntry) {
JetEnumEntry jetEnumEntry = (JetEnumEntry) declaration;
Name name = safeNameForLazyResolve(jetEnumEntry);
if (name != null) {
result.all.addAll(getProperties(name));
result.objects.add(getObjectDescriptor(name));
}
}
else if (declaration instanceof JetObjectDeclaration) {
JetObjectDeclaration objectDeclaration = (JetObjectDeclaration) declaration;
Name name = safeNameForLazyResolve(objectDeclaration.getNameAsDeclaration());
if (name != null) {
result.all.addAll(getProperties(name));
result.objects.add(getObjectDescriptor(name));
}
}
else if (declaration instanceof JetClassOrObject) {
JetClassOrObject classOrObject = (JetClassOrObject) declaration;
Name name = safeNameForLazyResolve(classOrObject.getNameAsName());
if (name != null) {
result.all.add(getClassifier(name));
}
}
else if (declaration instanceof JetFunction) {
JetFunction function = (JetFunction) declaration;
result.all.addAll(getFunctions(safeNameForLazyResolve(function)));
}
else if (declaration instanceof JetProperty) {
JetProperty property = (JetProperty) declaration;
result.all.addAll(getProperties(safeNameForLazyResolve(property)));
}
else if (declaration instanceof JetParameter) {
JetParameter parameter = (JetParameter) declaration;
Name name = safeNameForLazyResolve(parameter);
result.all.addAll(getProperties(name));
}
else if (declaration instanceof JetTypedef || declaration instanceof JetMultiDeclaration) {
// Do nothing for typedefs as they are not supported.
// MultiDeclarations are not supported on global level too.
}
else {
throw new IllegalArgumentException("Unsupported declaration kind: " + declaration);
}
}
addExtraDescriptors(result.all);
return result;
}
protected abstract void addExtraDescriptors(@NotNull Collection<DeclarationDescriptor> result);
@NotNull @NotNull
@Override @Override
@@ -282,26 +282,26 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
} }
@Override @Override
protected void addExtraDescriptors() { protected void addExtraDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) { for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) { for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
if (descriptor instanceof FunctionDescriptor) { if (descriptor instanceof FunctionDescriptor) {
getFunctions(descriptor.getName()); result.addAll(getFunctions(descriptor.getName()));
} }
else if (descriptor instanceof PropertyDescriptor) { else if (descriptor instanceof PropertyDescriptor) {
getProperties(descriptor.getName()); result.addAll(getProperties(descriptor.getName()));
} }
// Nothing else is inherited // Nothing else is inherited
} }
} }
getFunctions(DescriptorResolver.VALUES_METHOD_NAME); result.addAll(getFunctions(DescriptorResolver.VALUES_METHOD_NAME));
getFunctions(DescriptorResolver.VALUE_OF_METHOD_NAME); result.addAll(getFunctions(DescriptorResolver.VALUE_OF_METHOD_NAME));
addDataClassMethods(); addDataClassMethods(result);
} }
private void addDataClassMethods() { private void addDataClassMethods(@NotNull Collection<DeclarationDescriptor> result) {
if (!KotlinBuiltIns.getInstance().isData(thisDescriptor)) return; if (!KotlinBuiltIns.getInstance().isData(thisDescriptor)) return;
ConstructorDescriptor constructor = getPrimaryConstructor(); ConstructorDescriptor constructor = getPrimaryConstructor();
@@ -313,9 +313,12 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
Name componentName = Name.identifier(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX + n); Name componentName = Name.identifier(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX + n);
Set<FunctionDescriptor> functions = getFunctions(componentName); Set<FunctionDescriptor> functions = getFunctions(componentName);
if (functions.isEmpty()) break; if (functions.isEmpty()) break;
result.addAll(functions);
n++; n++;
} }
getFunctions(Name.identifier("copy")); result.addAll(getFunctions(Name.identifier("copy")));
} }
@Override @Override
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import java.util.Collection;
import java.util.Set; import java.util.Set;
public class LazyPackageMemberScope extends AbstractLazyMemberScope<NamespaceDescriptor, PackageMemberDeclarationProvider> { public class LazyPackageMemberScope extends AbstractLazyMemberScope<NamespaceDescriptor, PackageMemberDeclarationProvider> {
@@ -38,12 +39,13 @@ public class LazyPackageMemberScope extends AbstractLazyMemberScope<NamespaceDes
@NotNull NamespaceDescriptor thisPackage) { @NotNull NamespaceDescriptor thisPackage) {
super(resolveSession, declarationProvider, thisPackage); super(resolveSession, declarationProvider, thisPackage);
this.packageDescriptors = resolveSession.getStorageManager().createMemoizedFunctionWithNullableValues(new Function<Name, NamespaceDescriptor>() { this.packageDescriptors = resolveSession.getStorageManager().createMemoizedFunctionWithNullableValues(
@Override new Function<Name, NamespaceDescriptor>() {
public NamespaceDescriptor fun(Name name) { @Override
return createPackageDescriptor(name); public NamespaceDescriptor fun(Name name) {
} return createPackageDescriptor(name);
}, StorageManager.MemoizationMode.STRONG); }
}, StorageManager.MemoizationMode.STRONG);
} }
@Override @Override
@@ -58,11 +60,8 @@ public class LazyPackageMemberScope extends AbstractLazyMemberScope<NamespaceDes
PackageMemberDeclarationProvider packageMemberDeclarationProvider = resolveSession.getDeclarationProviderFactory().getPackageMemberDeclarationProvider( PackageMemberDeclarationProvider packageMemberDeclarationProvider = resolveSession.getDeclarationProviderFactory().getPackageMemberDeclarationProvider(
DescriptorUtils.getFQName(thisDescriptor).child(name).toSafe()); DescriptorUtils.getFQName(thisDescriptor).child(name).toSafe());
assert packageMemberDeclarationProvider != null : "Package is declared, but declaration provider is not found: " + name; assert packageMemberDeclarationProvider != null : "Package is declared, but declaration provider is not found: " + name;
NamespaceDescriptor namespaceDescriptor = new LazyPackageDescriptor(thisDescriptor, name, resolveSession, packageMemberDeclarationProvider);
registerDescriptor(namespaceDescriptor); return new LazyPackageDescriptor(thisDescriptor, name, resolveSession, packageMemberDeclarationProvider);
return namespaceDescriptor;
} }
@Override @Override
@@ -94,9 +93,9 @@ public class LazyPackageMemberScope extends AbstractLazyMemberScope<NamespaceDes
} }
@Override @Override
protected void addExtraDescriptors() { protected void addExtraDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
for (FqName packageFqName : declarationProvider.getAllDeclaredPackages()) { for (FqName packageFqName : declarationProvider.getAllDeclaredPackages()) {
getNamespace(packageFqName.shortName()); result.add(getNamespace(packageFqName.shortName()));
} }
} }
@@ -29,7 +29,6 @@ import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import static org.jetbrains.jet.lang.resolve.lazy.StorageManager.MemoizationMode.WEAK; import static org.jetbrains.jet.lang.resolve.lazy.StorageManager.MemoizationMode.WEAK;
@@ -86,11 +85,6 @@ public class LockBasedStorageManager implements StorageManager {
}; };
} }
@Override
public <E> Collection<E> createConcurrentCollection() {
return new ConcurrentLinkedQueue<E>();
}
@NotNull @NotNull
@Override @Override
public <T> LazyValue<T> createLazyValue(@NotNull Computable<T> computable) { public <T> LazyValue<T> createLazyValue(@NotNull Computable<T> computable) {
@@ -21,8 +21,6 @@ import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import java.util.Collection;
public interface StorageManager { public interface StorageManager {
/** /**
* Given a function compute: K -> V create a memoized version of it that computes a value only once for each key * Given a function compute: K -> V create a memoized version of it that computes a value only once for each key
@@ -34,8 +32,6 @@ public interface StorageManager {
@NotNull @NotNull
<K, V> Function<K, V> createMemoizedFunctionWithNullableValues(@NotNull Function<K, V> compute, @NotNull MemoizationMode modeForValues); <K, V> Function<K, V> createMemoizedFunctionWithNullableValues(@NotNull Function<K, V> compute, @NotNull MemoizationMode modeForValues);
<E> Collection<E> createConcurrentCollection();
@NotNull @NotNull
<T> LazyValue<T> createLazyValue(@NotNull Computable<T> computable); <T> LazyValue<T> createLazyValue(@NotNull Computable<T> computable);