diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2017-10-16 13:08:19 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2017-12-06 12:44:06 -0800 |
commit | 5b17173847fe3e6d2a976fecad065952c801522e (patch) | |
tree | 4aebe6f3151a1d6519b92e1d150c2cc6b2e7086e /lib/chef/node | |
parent | 0c29acc106ca774e230c8ef45694c8bffd166b69 (diff) | |
download | chef-5b17173847fe3e6d2a976fecad065952c801522e.tar.gz |
turbo attribute merging
Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
Diffstat (limited to 'lib/chef/node')
-rw-r--r-- | lib/chef/node/immutable_collections.rb | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/lib/chef/node/immutable_collections.rb b/lib/chef/node/immutable_collections.rb index 13cb321890..3378bee2b5 100644 --- a/lib/chef/node/immutable_collections.rb +++ b/lib/chef/node/immutable_collections.rb @@ -198,6 +198,7 @@ class Chef class ImmutableMash < Mash alias_method :internal_clear, :clear alias_method :internal_key?, :key? # FIXME: could bypass convert_key in Mash for perf + alias_method :internal_each, :each include Immutablize include CommonAPI @@ -264,6 +265,7 @@ class Chef def reset @generated_cache = false + @short_circuit_attr_level = nil internal_clear # redundant? end @@ -273,13 +275,20 @@ class Chef @generated_cache = true end + # @api private + attr_accessor :short_circuit_attr_levels + private def generate_cache internal_clear - Attribute::COMPONENTS.reverse.each do |component| + components = short_circuit_attr_levels ? short_circuit_attr_levels : Attribute::COMPONENTS.reverse + # merged_components is not entirely accurate due to the short-circuit + merged_components = [] + components.each do |component| subhash = __node__.attributes.instance_variable_get(component).read(*__path__) unless subhash.nil? # FIXME: nil is used for not present + merged_components << component if subhash.kind_of?(Hash) subhash.keys.each do |key| next if internal_key?(key) @@ -290,6 +299,12 @@ class Chef end end end + if merged_components.size == 1 + # merged_components is accurate enough to tell us if we're not really merging + internal_each do |key, value| + value.short_circuit_attr_levels = merged_components if value.respond_to?(:short_circuit_attr_levels) + end + end end prepend Chef::Node::Mixin::StateTracking |