summary |
shortlog |
log |
commit | commitdiff |
review |
tree
raw |
patch |
inline | side by side (from parent 1:
56674bd)
Address a FIXME around caching of mismatched augmentations, as it
seems openflowplugin is doing this on purpose.
The cache is expected to be needed infrequently in terms of associated
objects as well as modified infrequently, hence we use a space-efficient
ImmutableMap.
JIRA: MDSAL-388
Change-Id: Id86d8c713ee1014d9d4867558032ba3ccd51fc45
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit
c44477a41ca49f9fddf92b56a129f915741de5c7)
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.ImmutableSortedMap;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import com.google.common.collect.ImmutableSortedMap;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
new ConcurrentHashMap<>();
private final ConcurrentMap<Class<?>, DataContainerCodecPrototype<?>> byStreamAugmented = new ConcurrentHashMap<>();
new ConcurrentHashMap<>();
private final ConcurrentMap<Class<?>, DataContainerCodecPrototype<?>> byStreamAugmented = new ConcurrentHashMap<>();
+ private volatile ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> mismatchedAugmented = ImmutableMap.of();
+
DataObjectCodecContext(final DataContainerCodecPrototype<T> prototype) {
super(prototype);
DataObjectCodecContext(final DataContainerCodecPrototype<T> prototype) {
super(prototype);
- * It is potentially mismatched valid augmentation - we look up equivalent augmentation
- * using reflection and walk all stream child and compare augmenations classes if they are
- * equivalent.
- *
- * FIXME: Cache mapping of mismatched augmentation to real one, to speed up lookup.
+ * It is potentially mismatched valid augmentation - we look up equivalent augmentation using reflection
+ * and walk all stream child and compare augmentations classes if they are equivalent. When we find a match
+ * we'll cache it so we do not need to perform reflection operations again.
+ final DataContainerCodecPrototype<?> mismatched = mismatchedAugmented.get(childClass);
+ if (mismatched != null) {
+ return mismatched;
+ }
+
@SuppressWarnings("rawtypes")
final Class<?> augTarget = BindingReflections.findAugmentationTarget((Class) childClass);
if (getBindingClass().equals(augTarget)) {
for (final DataContainerCodecPrototype<?> realChild : byStreamAugmented.values()) {
if (Augmentation.class.isAssignableFrom(realChild.getBindingClass())
&& BindingReflections.isSubstitutionFor(childClass, realChild.getBindingClass())) {
@SuppressWarnings("rawtypes")
final Class<?> augTarget = BindingReflections.findAugmentationTarget((Class) childClass);
if (getBindingClass().equals(augTarget)) {
for (final DataContainerCodecPrototype<?> realChild : byStreamAugmented.values()) {
if (Augmentation.class.isAssignableFrom(realChild.getBindingClass())
&& BindingReflections.isSubstitutionFor(childClass, realChild.getBindingClass())) {
+ return cacheMismatched(childClass, realChild);
+ private synchronized DataContainerCodecPrototype<?> cacheMismatched(final Class<?> childClass,
+ final DataContainerCodecPrototype<?> prototype) {
+ // Original access was unsynchronized, we need to perform additional checking
+ final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> local = mismatchedAugmented;
+ final DataContainerCodecPrototype<?> existing = local.get(childClass);
+ if (existing != null) {
+ return existing;
+ }
+
+ final Builder<Class<?>, DataContainerCodecPrototype<?>> builder = ImmutableMap.builderWithExpectedSize(
+ local.size() + 1);
+ builder.putAll(local);
+ builder.put(childClass, prototype);
+
+ mismatchedAugmented = builder.build();
+ return prototype;
+ }
+
private DataContainerCodecPrototype<?> getAugmentationPrototype(final Type value) {
final ClassLoadingStrategy loader = factory().getRuntimeContext().getStrategy();
@SuppressWarnings("rawtypes")
private DataContainerCodecPrototype<?> getAugmentationPrototype(final Type value) {
final ClassLoadingStrategy loader = factory().getRuntimeContext().getStrategy();
@SuppressWarnings("rawtypes")