From 8bb52f929f36994fd5b42295d24b627f132fe318 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 18 Feb 2016 11:09:15 -0800 Subject: [PATCH] cache all subnodes in the digest cache this is for backwards compatibility. We should remove this after 5-0-stable is created because digest calculation should be amortized. Caching digests of subtrees will speed up digests for other trees that share the same children. However, this will also increase memory, and after the app warms up, then those subtrees will never be reused which means that memory is wasted. --- actionview/lib/action_view/digestor.rb | 18 ++++++++++-------- actionview/test/template/digestor_test.rb | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 07600f2092..518f0da16c 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -28,7 +28,7 @@ module ActionView # (Concurrent::Map's lookups have volatile semantics) finder.digest_cache[cache_key] || @@digest_mutex.synchronize do finder.digest_cache.fetch(cache_key) do # re-check under lock - finder.digest_cache[cache_key] = tree(name, finder, dependencies).digest + finder.digest_cache[cache_key] = tree(name, finder, dependencies).digest(finder) end end end @@ -83,17 +83,19 @@ module ActionView @children = children end - def digest(stack = []) - Digest::MD5.hexdigest("#{template.source}-#{dependency_digest(stack)}") + def digest(finder, stack = []) + Digest::MD5.hexdigest("#{template.source}-#{dependency_digest(finder, stack)}") end - def dependency_digest(stack) + def dependency_digest(finder, stack) children.map do |node| if stack.include?(node) false else - stack.push node - node.digest(stack).tap { stack.pop } + finder.digest_cache[node.name] ||= begin + stack.push node + node.digest(finder, stack).tap { stack.pop } + end end end.join("-") end @@ -106,11 +108,11 @@ module ActionView class Partial < Node; end class Missing < Node - def digest(_ = []) '' end + def digest(finder, _ = []) '' end end class Injected < Node - def digest(_ = []) name end + def digest(finder, _ = []) name end end class NullLogger diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index 6384aac46e..56bc967c83 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -319,7 +319,7 @@ class TemplateDigestorTest < ActionView::TestCase finder.variants = options.delete(:variants) || [] node = ActionView::Digestor.tree(template_name, finder, options[:dependencies] || []) - node.digest + node.digest(finder) end def dependencies(template_name)