Skip to content

Commit

Permalink
Fix removal of bindings in ProvisionListenerCallbackStore and simplify
Browse files Browse the repository at this point in the history
Bindings have never been removed from the cache in
ProvisionListenerCallbackStore.remove() because the key of the cache
were KeyBinding objects, while it was attempted to remove Binding
objects.

Additionally use a standard Java ConcurrentHashMap instead of a simple
Guava Cache, which also allows to remove the now unnecessary KeyBinding
helper class. Instead of a new KeyBinding object a new new lambda object
is created for each cache lookup.
  • Loading branch information
HannesWell committed Dec 30, 2023
1 parent e23d3b4 commit a54a6c6
Showing 1 changed file with 8 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@

package com.google.inject.internal;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
Expand All @@ -29,6 +26,8 @@
import com.google.inject.spi.ProvisionListener;
import com.google.inject.spi.ProvisionListenerBinding;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;

/**
Expand All @@ -45,15 +44,7 @@ final class ProvisionListenerCallbackStore {

private final ImmutableList<ProvisionListenerBinding> listenerBindings;

private final LoadingCache<KeyBinding, ProvisionListenerStackCallback<?>> cache =
CacheBuilder.newBuilder()
.build(
new CacheLoader<KeyBinding, ProvisionListenerStackCallback<?>>() {
@Override
public ProvisionListenerStackCallback<?> load(KeyBinding key) {
return create(key.binding);
}
});
private final Map<Key<?>, ProvisionListenerStackCallback<?>> cache = new ConcurrentHashMap<>();

ProvisionListenerCallbackStore(List<ProvisionListenerBinding> listenerBindings) {
this.listenerBindings = ImmutableList.copyOf(listenerBindings);
Expand All @@ -63,14 +54,12 @@ public ProvisionListenerStackCallback<?> load(KeyBinding key) {
* Returns a new {@link ProvisionListenerStackCallback} for the key or {@code null} if there are
* no listeners
*/
@SuppressWarnings(
"unchecked") // the ProvisionListenerStackCallback type always agrees with the passed type
@SuppressWarnings("unchecked") // the ProvisionListenerStackCallback type always agrees with the passed type
public <T> ProvisionListenerStackCallback<T> get(Binding<T> binding) {
// Never notify any listeners for internal bindings.
if (!INTERNAL_BINDINGS.contains(binding.getKey())) {
ProvisionListenerStackCallback<T> callback =
(ProvisionListenerStackCallback<T>)
cache.getUnchecked(new KeyBinding(binding.getKey(), binding));
ProvisionListenerStackCallback<T> callback = (ProvisionListenerStackCallback<T>) cache
.computeIfAbsent(binding.getKey(), k -> create(binding));
return callback.hasListeners() ? callback : null;
}
return null;
Expand All @@ -86,7 +75,7 @@ public <T> ProvisionListenerStackCallback<T> get(Binding<T> binding) {
* <p>Returns true if the type was stored in the cache, false otherwise.
*/
boolean remove(Binding<?> type) {
return cache.asMap().remove(type) != null;
return cache.remove(type.getKey()) != null;
}

/**
Expand All @@ -107,27 +96,7 @@ private <T> ProvisionListenerStackCallback<T> create(Binding<T> binding) {
// no listeners.
return ProvisionListenerStackCallback.emptyListener();
}
return new ProvisionListenerStackCallback<T>(binding, listeners);
return new ProvisionListenerStackCallback<>(binding, listeners);
}

/** A struct that holds key and binding but uses just key for equality/hashcode. */
private static class KeyBinding {
final Key<?> key;
final Binding<?> binding;

KeyBinding(Key<?> key, Binding<?> binding) {
this.key = key;
this.binding = binding;
}

@Override
public boolean equals(Object obj) {
return obj instanceof KeyBinding && key.equals(((KeyBinding) obj).key);
}

@Override
public int hashCode() {
return key.hashCode();
}
}
}

0 comments on commit a54a6c6

Please sign in to comment.