提交 a9b72fbc 编写于 作者: J José Valim

Optimize the most common resolver case.

上级 4f03e404
...@@ -35,7 +35,7 @@ def typecast! ...@@ -35,7 +35,7 @@ def typecast!
each_with_index do |path, i| each_with_index do |path, i|
path = path.to_s if path.is_a?(Pathname) path = path.to_s if path.is_a?(Pathname)
next unless path.is_a?(String) next unless path.is_a?(String)
self[i] = FileSystemResolver.new(path) self[i] = OptimizedFileSystemResolver.new(path)
end end
end end
end end
......
...@@ -111,7 +111,8 @@ def sort_locals(locals) #:nodoc: ...@@ -111,7 +111,8 @@ def sort_locals(locals) #:nodoc:
end end
end end
class PathResolver < Resolver # An abstract class that implements a Resolver with path semantics.
class PathResolver < Resolver #:nodoc:
EXTENSIONS = [:locale, :formats, :handlers] EXTENSIONS = [:locale, :formats, :handlers]
DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}" DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}"
...@@ -124,12 +125,11 @@ def initialize(pattern=nil) ...@@ -124,12 +125,11 @@ def initialize(pattern=nil)
def find_templates(name, prefix, partial, details) def find_templates(name, prefix, partial, details)
path = Path.build(name, prefix, partial) path = Path.build(name, prefix, partial)
extensions = Hash[EXTENSIONS.map { |ext| [ext, details[ext]] }.flatten(0)] query(path, details, details[:formats])
query(path, extensions, details[:formats])
end end
def query(path, exts, formats) def query(path, details, formats)
query = build_query(path, exts) query = build_query(path, details)
templates = [] templates = []
sanitizer = Hash.new { |h,k| h[k] = Dir["#{File.dirname(k)}/*"] } sanitizer = Hash.new { |h,k| h[k] = Dir["#{File.dirname(k)}/*"] }
...@@ -137,7 +137,7 @@ def query(path, exts, formats) ...@@ -137,7 +137,7 @@ def query(path, exts, formats)
next if File.directory?(p) || !sanitizer[p].include?(p) next if File.directory?(p) || !sanitizer[p].include?(p)
handler, format = extract_handler_and_format(p, formats) handler, format = extract_handler_and_format(p, formats)
contents = File.open(p, "rb") {|io| io.read } contents = File.open(p, "rb") { |io| io.read }
templates << Template.new(contents, File.expand_path(p), handler, templates << Template.new(contents, File.expand_path(p), handler,
:virtual_path => path.virtual, :format => format, :updated_at => mtime(p)) :virtual_path => path.virtual, :format => format, :updated_at => mtime(p))
...@@ -147,17 +147,14 @@ def query(path, exts, formats) ...@@ -147,17 +147,14 @@ def query(path, exts, formats)
end end
# Helper for building query glob string based on resolver's pattern. # Helper for building query glob string based on resolver's pattern.
def build_query(path, exts) def build_query(path, details)
query = @pattern.dup query = @pattern.dup
query.gsub!(/\:prefix(\/)?/, path.prefix.empty? ? "" : "#{path.prefix}\\1") # prefix can be empty... query.gsub!(/\:prefix(\/)?/, path.prefix.empty? ? "" : "#{path.prefix}\\1") # prefix can be empty...
query.gsub!(/\:action/, path.partial? ? "_#{path.name}" : path.name) query.gsub!(/\:action/, path.partial? ? "_#{path.name}" : path.name)
exts.each { |ext, variants| details.each do |ext, variants|
query.gsub!(/\:#{ext}/, "{#{variants.compact.uniq.join(',')}}") query.gsub!(/\:#{ext}/, "{#{variants.compact.uniq.join(',')}}")
} end
query.gsub!('.{html,', '.{html,text.html,')
query.gsub!('.{text,', '.{text,text.plain,')
File.expand_path(query, @path) File.expand_path(query, @path)
end end
...@@ -234,9 +231,25 @@ def eql?(resolver) ...@@ -234,9 +231,25 @@ def eql?(resolver)
alias :== :eql? alias :== :eql?
end end
# An Optimized resolver for Rails' most common case.
class OptimizedFileSystemResolver < FileSystemResolver #:nodoc:
def build_query(path, details)
exts = EXTENSIONS.map { |ext| details[ext] }
query = File.join(@path, path)
exts.each do |ext|
query << "{"
ext.compact.each { |e| query << ".#{e}," }
query << "}"
end
query
end
end
# The same as FileSystemResolver but does not allow templates to store # The same as FileSystemResolver but does not allow templates to store
# a virtual path since it is invalid for such resolvers. # a virtual path since it is invalid for such resolvers.
class FallbackFileSystemResolver < FileSystemResolver class FallbackFileSystemResolver < FileSystemResolver #:nodoc:
def self.instances def self.instances
[new(""), new("/")] [new(""), new("/")]
end end
......
...@@ -325,7 +325,7 @@ class CachedViewRenderTest < ActiveSupport::TestCase ...@@ -325,7 +325,7 @@ class CachedViewRenderTest < ActiveSupport::TestCase
# Ensure view path cache is primed # Ensure view path cache is primed
def setup def setup
view_paths = ActionController::Base.view_paths view_paths = ActionController::Base.view_paths
assert_equal ActionView::FileSystemResolver, view_paths.first.class assert_equal ActionView::OptimizedFileSystemResolver, view_paths.first.class
setup_view(view_paths) setup_view(view_paths)
end end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册