diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2017-10-16 13:08:19 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2017-10-16 14:09:12 -0700 |
commit | 03c8ac0de9ad9c9b09d118652ce1d1c65be7d83c (patch) | |
tree | 2a4d84f57e79f9b9d4952dd1af8b170e5073d3e4 | |
parent | 47cc10f46c518b99062527a7e929c8eb2c1ea5be (diff) | |
download | chef-03c8ac0de9ad9c9b09d118652ce1d1c65be7d83c.tar.gz |
turbo attribute merging
Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
-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 0320e0fb8b..5bb32008d6 100644 --- a/lib/chef/node/immutable_collections.rb +++ b/lib/chef/node/immutable_collections.rb @@ -195,6 +195,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 @@ -284,6 +285,7 @@ class Chef def reset @generated_cache = false + @short_circuit_attr_level = nil internal_clear # redundant? end @@ -293,13 +295,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) @@ -310,6 +319,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 |