From 7192a5ec5895f5ded477178efe53b289ec5435a6 Mon Sep 17 00:00:00 2001 From: evanweaver Date: Mon, 22 Oct 2007 16:27:45 +0000 Subject: classifier optimization for only one handler on "/", with unit test git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@735 19e92222-5c0b-0410-8929-a290d50e31e9 --- lib/mongrel.rb | 23 ++++++++++++++++------- test/test_uriclassifier.rb | 16 ++++++++++++---- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/lib/mongrel.rb b/lib/mongrel.rb index 87afe00..8debb28 100644 --- a/lib/mongrel.rb +++ b/lib/mongrel.rb @@ -53,6 +53,7 @@ module Mongrel def initialize @handler_map = {} @matcher = // + @root_handler = nil end # Register a handler object at a particular URI. The handler can be whatever @@ -78,8 +79,11 @@ module Mongrel # Resolve a request URI by finding the best partial match in the registered # handler URIs. - def resolve(request_uri) - if match = @matcher.match(request_uri) + def resolve(request_uri) + if @root_handler + # Optimization for the pathological case of only one handler on "/"; e.g. Rails + [Const::SLASH, request_uri, @root_handler] + elsif match = @matcher.match(request_uri) uri = match.to_s path_info = match.post_match # A root mounted ("/") handler must resolve such that path info matches the original URI. @@ -93,12 +97,17 @@ module Mongrel private def rebuild - routes = @handler_map.keys.sort.sort_by do |uri| - -uri.length + if @handler_map.size == 1 and @handler_map[Const::SLASH] + @root_handler = @handler_map.values.first + else + @root_handler = nil + routes = @handler_map.keys.sort.sort_by do |uri| + -uri.length + end + @matcher = Regexp.new(routes.map do |uri| + Regexp.new('^' + Regexp.escape(uri)) + end.join('|')) end - @matcher = Regexp.new(routes.map do |uri| - Regexp.new('^' + Regexp.escape(uri)) - end.join('|')) end end diff --git a/test/test_uriclassifier.rb b/test/test_uriclassifier.rb index cf77384..2acb042 100644 --- a/test/test_uriclassifier.rb +++ b/test/test_uriclassifier.rb @@ -15,11 +15,19 @@ class URIClassifierTest < Test::Unit::TestCase uri_classifier.register("/test", 1) script_name, path_info, value = uri_classifier.resolve("/test") - assert value assert_equal 1, value assert_equal "/test", script_name end - + + def test_root_handler_only + uri_classifier = URIClassifier.new + uri_classifier.register("/", 1) + + script_name, path_info, value = uri_classifier.resolve("/test") + assert_equal 1, value + assert_equal "/", script_name + assert_equal "/test", path_info + end def test_uri_prefix_ops test = "/pre/fix/test" @@ -30,7 +38,7 @@ class URIClassifierTest < Test::Unit::TestCase script_name, path_info, value = uri_classifier.resolve(prefix) script_name, path_info, value = uri_classifier.resolve(test) - assert value + assert_equal 1, value assert_equal prefix, script_name assert_equal test[script_name.length .. -1], path_info @@ -219,7 +227,7 @@ class URIClassifierTest < Test::Unit::TestCase @classifier.register(uri, 1) end -# puts "#{@uris.size} URIs / #{@requests.size * 10000} requests" + puts "#{@uris.size} URIs / #{@requests.size * 10000} requests" Benchmark.bm do |x| x.report do -- cgit v1.2.3-24-ge0c7