Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.Set;
Expand All @@ -26,7 +27,6 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -116,7 +116,7 @@ public ArcContainerImpl(CurrentContextFactory currentContextFactory, boolean str
id = String.valueOf(ID_GENERATOR.incrementAndGet());
running = new AtomicBoolean(true);
List<InjectableBean<?>> beans = new ArrayList<>();
Map<String, List<InjectableBean<?>>> beansByRawType = new HashMap<>();
Map<String, Set<InjectableBean<?>>> beansByRawType = new HashMap<>();
List<Supplier<Collection<RemovedBean>>> removedBeans = new ArrayList<>();
List<InjectableInterceptor<?>> interceptors = new ArrayList<>();
List<InjectableDecorator<?>> decorators = new ArrayList<>();
Expand Down Expand Up @@ -179,16 +179,8 @@ public ArcContainerImpl(CurrentContextFactory currentContextFactory, boolean str
instance = InstanceImpl.forGlobalEntrypoint(Object.class, Collections.emptySet());

this.beans = List.copyOf(beans);
this.beansByRawType = Map.copyOf(beansByRawType);
// Trim the size of the non-singleton lists
this.beansByRawType.forEach(new BiConsumer<String, List<InjectableBean<?>>>() {
@Override
public void accept(String key, List<InjectableBean<?>> val) {
if (val.size() > 1) {
((ArrayList<InjectableBean<?>>) val).trimToSize();
}
}
});
this.beansByRawType = beansByRawType.entrySet().stream()
.collect(Collectors.toUnmodifiableMap(Entry::getKey, e -> List.copyOf(e.getValue())));

this.interceptors = List.copyOf(interceptors);
this.decorators = List.copyOf(decorators);
Expand Down Expand Up @@ -245,7 +237,7 @@ public List<RemovedBean> get() {
this.contexts = contextsBuilder.build();
}

static void precomputeBeanRawTypes(Map<String, List<InjectableBean<?>>> map, InjectableBean<?> bean) {
static void precomputeBeanRawTypes(Map<String, Set<InjectableBean<?>>> map, InjectableBean<?> bean) {
for (Type type : bean.getTypes()) {
if (Object.class.equals(type)) {
continue;
Expand All @@ -256,18 +248,19 @@ static void precomputeBeanRawTypes(Map<String, List<InjectableBean<?>>> map, Inj
}
rawType = Types.boxedClass(rawType);
String key = rawType.getName();
List<InjectableBean<?>> match = map.get(key);
Set<InjectableBean<?>> match = map.get(key);
if (match == null) {
// very often a singleton list will be used
map.put(key, List.of(bean));
map.put(key, Set.of(bean));
} else {
// we don't expect large lists so this should be fine performance wise
if (match.contains(bean)) {
continue;
}
if (match.size() == 1) {
List<InjectableBean<?>> newMatch = new ArrayList<>();
newMatch.add(match.get(0));
// a set of 2 elements is also a relatively common case
map.put(key, Set.of(match.iterator().next(), bean));
} else if (match.size() == 2) {
Set<InjectableBean<?>> newMatch = new HashSet<>(match);
newMatch.add(bean);
map.put(key, newMatch);
} else {
Expand Down Expand Up @@ -536,7 +529,7 @@ private Notifier<Object> notifierOrNull(Set<Annotation> qualifiers) {
return notifier.isEmpty() ? null : notifier;
}

private static void addBuiltInBeans(List<InjectableBean<?>> beans, Map<String, List<InjectableBean<?>>> beansByRawType) {
private static void addBuiltInBeans(List<InjectableBean<?>> beans, Map<String, Set<InjectableBean<?>>> beansByRawType) {
// BeanManager, Event<?>, Instance<?>, InjectionPoint
BeanManagerBean beanManagerBean = new BeanManagerBean();
beans.add(beanManagerBean);
Expand Down
Loading