1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Optimize the most common resolver case.

This commit is contained in:
José Valim 2011-05-09 11:17:24 +02:00
parent 4f03e404b2
commit a9b72fbc9e
3 changed files with 28 additions and 15 deletions

View file

@ -35,7 +35,7 @@ module ActionView #:nodoc:
each_with_index do |path, i|
path = path.to_s if path.is_a?(Pathname)
next unless path.is_a?(String)
self[i] = FileSystemResolver.new(path)
self[i] = OptimizedFileSystemResolver.new(path)
end
end
end

View file

@ -111,7 +111,8 @@ module ActionView
end
end
class PathResolver < Resolver
# An abstract class that implements a Resolver with path semantics.
class PathResolver < Resolver #:nodoc:
EXTENSIONS = [:locale, :formats, :handlers]
DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}"
@ -124,12 +125,11 @@ module ActionView
def find_templates(name, prefix, partial, details)
path = Path.build(name, prefix, partial)
extensions = Hash[EXTENSIONS.map { |ext| [ext, details[ext]] }.flatten(0)]
query(path, extensions, details[:formats])
query(path, details, details[:formats])
end
def query(path, exts, formats)
query = build_query(path, exts)
def query(path, details, formats)
query = build_query(path, details)
templates = []
sanitizer = Hash.new { |h,k| h[k] = Dir["#{File.dirname(k)}/*"] }
@ -137,7 +137,7 @@ module ActionView
next if File.directory?(p) || !sanitizer[p].include?(p)
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,
:virtual_path => path.virtual, :format => format, :updated_at => mtime(p))
@ -147,17 +147,14 @@ module ActionView
end
# 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.gsub!(/\:prefix(\/)?/, path.prefix.empty? ? "" : "#{path.prefix}\\1") # prefix can be empty...
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!('.{html,', '.{html,text.html,')
query.gsub!('.{text,', '.{text,text.plain,')
end
File.expand_path(query, @path)
end
@ -234,9 +231,25 @@ module ActionView
alias :== :eql?
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
# a virtual path since it is invalid for such resolvers.
class FallbackFileSystemResolver < FileSystemResolver
class FallbackFileSystemResolver < FileSystemResolver #:nodoc:
def self.instances
[new(""), new("/")]
end

View file

@ -325,7 +325,7 @@ class CachedViewRenderTest < ActiveSupport::TestCase
# Ensure view path cache is primed
def setup
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)
end