From 444219bb175602264dd7e74760cee629f60ee654 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 29 Nov 2011 10:02:26 -0500 Subject: [PATCH] Optimize no-op object merges by throwing away the new HashMap and using the old one One side effect of this is that if an object merge does nothing, the ConfigOrigin for the fallback is discarded instead of merged in, but I think that's OK. --- .../config/impl/AbstractConfigObject.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java b/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java index 3f7cc0ed..7a5868da 100644 --- a/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java +++ b/config/src/main/java/com/typesafe/config/impl/AbstractConfigObject.java @@ -135,6 +135,7 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements if (ignoresFallbacks()) throw new ConfigException.BugOrBroken("should not be reached"); + boolean changed = false; boolean allResolved = true; Map merged = new HashMap(); Set allKeys = new HashSet(); @@ -150,12 +151,26 @@ abstract class AbstractConfigObject extends AbstractConfigValue implements kept = first; else kept = first.withFallback(second); + merged.put(key, kept); + + if (first != kept) + changed = true; + if (kept.resolveStatus() == ResolveStatus.UNRESOLVED) allResolved = false; } - return new SimpleConfigObject(mergeOrigins(this, fallback), merged, - ResolveStatus.fromBoolean(allResolved), fallback.ignoresFallbacks()); + + ResolveStatus newResolveStatus = ResolveStatus.fromBoolean(allResolved); + boolean newIgnoresFallbacks = fallback.ignoresFallbacks(); + + if (changed) + return new SimpleConfigObject(mergeOrigins(this, fallback), merged, newResolveStatus, + newIgnoresFallbacks); + else if (newResolveStatus != resolveStatus() || newIgnoresFallbacks != ignoresFallbacks()) + return newCopy(newResolveStatus, newIgnoresFallbacks); + else + return this; } @Override