+ private static final int CACHE_MAX_ENTRIES = 1000;
+
+ /**
+ * Constant map of notification type to subscribed listeners.
+ */
+ private final Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> typeToListeners;
+
+ /**
+ * Dynamic cache of notification implementation to matching listeners. This cache loads entries based on
+ * the contents of the {@link #typeToListeners} map.
+ */
+ private final LoadingCache<Class<?>, Iterable<NotificationListenerRegistration<?>>> implementationToListeners =
+ CacheBuilder.newBuilder()
+ .weakKeys()
+ .maximumSize(CACHE_MAX_ENTRIES)
+ .build(new CacheLoader<Class<?>, Iterable<NotificationListenerRegistration<?>>>() {
+ @Override
+ public Iterable<NotificationListenerRegistration<?>> load(final Class<?> key) {
+ final Set<NotificationListenerRegistration<?>> regs = new HashSet<>();
+
+ for (final Class<?> type : getNotificationTypes(key)) {
+ @SuppressWarnings("unchecked")
+ final Collection<NotificationListenerRegistration<?>> l = typeToListeners.get((Class<? extends Notification>) type);
+ if (l != null) {
+ regs.addAll(l);
+ }
+ }
+
+ return ImmutableSet.copyOf(regs);
+ }
+ });