about summary refs log tree commit
diff options
context:
space:
mode:
authorEric Wong <e@yhbt.net>2011-01-17 03:17:28 +0000
committerEric Wong <normalperson@yhbt.net>2011-01-17 09:18:31 +0000
commit2c913347a6e5cc8be776b14e1a177adec0fbd5b6 (patch)
tree8d001fa557ef23c66bc56aa6c2fba943e428382e
parent34a18520286313a05edc9a927ac4bed95b05191c (diff)
downloadmetropolis-2c913347a6e5cc8be776b14e1a177adec0fbd5b6.tar.gz
use constants everywhere to reduce GC thrashing
This makes it easier to notice a typo, too.
-rw-r--r--lib/metropolis.rb1
-rw-r--r--lib/metropolis/common.rb13
-rw-r--r--lib/metropolis/common/ro.rb6
-rw-r--r--lib/metropolis/constants.rb20
-rw-r--r--lib/metropolis/deflate.rb17
-rw-r--r--lib/metropolis/gzip.rb17
-rw-r--r--lib/metropolis/hash.rb10
-rw-r--r--lib/metropolis/input_wrapper.rb6
-rw-r--r--lib/metropolis/multi_hash/digest.rb12
-rw-r--r--lib/metropolis/suffix_mime.rb3
-rw-r--r--lib/metropolis/tc/hdb.rb10
-rw-r--r--lib/metropolis/tdb.rb10
12 files changed, 81 insertions, 44 deletions
diff --git a/lib/metropolis.rb b/lib/metropolis.rb
index 284cd30..986f5b8 100644
--- a/lib/metropolis.rb
+++ b/lib/metropolis.rb
@@ -41,4 +41,5 @@ module Metropolis
   end
 end
 
+require 'metropolis/constants'
 require 'metropolis/common'
diff --git a/lib/metropolis/common.rb b/lib/metropolis/common.rb
index a6688f3..383ebe9 100644
--- a/lib/metropolis/common.rb
+++ b/lib/metropolis/common.rb
@@ -1,10 +1,13 @@
 # -*- encoding: binary -*-
 module Metropolis::Common
   include Rack::Utils # unescape
+  include Metropolis::Constants
+  HTTP_STATUS_BODIES = {}
+
   autoload :RO, 'metropolis/common/ro'
 
   def setup(opts)
-    @headers = { 'Content-Type' => 'application/octet-stream' }
+    @headers = { Content_Type => 'application/octet-stream' }
     @headers.merge!(opts[:response_headers] || {})
     @nr_slots = opts[:nr_slots]
 
@@ -39,16 +42,16 @@ module Metropolis::Common
   end
 
   def r(code, body = nil)
-    body ||= "#{HTTP_STATUS_CODES[code]}\n"
+    body ||= HTTP_STATUS_BODIES[code] ||= "#{HTTP_STATUS_CODES[code]}\n"
     [ code,
-      { 'Content-Length' => body.size.to_s, 'Content-Type' => 'text/plain' },
+      { Content_Length => body.size.to_s, Content_Type => Text_Plain },
       [ body ] ]
   end
 
   def call(env)
-    if %r{\A/(.*)\z} =~ env["PATH_INFO"]
+    if %r{\A/(.*)\z} =~ env[PATH_INFO]
       key = unescape($1)
-      case env["REQUEST_METHOD"]
+      case env[REQUEST_METHOD]
       when "GET"
         get(key, env)
       when "HEAD"
diff --git a/lib/metropolis/common/ro.rb b/lib/metropolis/common/ro.rb
index 390e2c6..c6015df 100644
--- a/lib/metropolis/common/ro.rb
+++ b/lib/metropolis/common/ro.rb
@@ -1,9 +1,11 @@
 # -*- encoding: binary -*-
 module Metropolis::Common::RO
+  include Metropolis::Constants
+
   def call(env)
-    if %r{\A/(.*)\z} =~ env["PATH_INFO"]
+    if %r{\A/(.*)\z} =~ env[PATH_INFO]
       key = unescape($1)
-      case env["REQUEST_METHOD"]
+      case env[REQUEST_METHOD]
       when "GET"
         get(key, env)
       when "HEAD"
diff --git a/lib/metropolis/constants.rb b/lib/metropolis/constants.rb
new file mode 100644
index 0000000..d0a0ffd
--- /dev/null
+++ b/lib/metropolis/constants.rb
@@ -0,0 +1,20 @@
+# -*- encoding: binary -*-
+module Metropolis::Constants
+
+  # response headers, frozen for speed since they're settable hash keys
+  Content_Length = "Content-Length".freeze
+  Content_Type = "Content-Type".freeze
+  Content_Encoding = "Content-Encoding".freeze
+  Vary = "Vary".freeze
+
+  Text_Plain = "text/plain"
+  Accept_Encoding = "Accept-Encoding"
+
+  # request headers, no need to freeze since we only read them
+  Rack_Input = "rack.input"
+  PATH_INFO = "PATH_INFO"
+  REQUEST_METHOD = "REQUEST_METHOD"
+  HTTP_ACCEPT_ENCODING = "HTTP_ACCEPT_ENCODING"
+  HTTP_CONTENT_ENCODING = "HTTP_CONTENT_ENCODING"
+  HTTP_X_TT_PDMODE = "HTTP_X_TT_PDMODE"
+end
diff --git a/lib/metropolis/deflate.rb b/lib/metropolis/deflate.rb
index 438985e..c965033 100644
--- a/lib/metropolis/deflate.rb
+++ b/lib/metropolis/deflate.rb
@@ -4,28 +4,31 @@ require "zlib"
 # allows storing pre-deflated data on disk and serving it
 # as-is for clients that accept that deflate encoding
 module Metropolis::Deflate
+  include Metropolis::Constants
+  Compression = "deflate"
+
   def get(key, env)
     status, headers, body = r = super
-    if 200 == status && /\bdeflate\b/ !~ env['HTTP_ACCEPT_ENCODING']
+    if 200 == status && /\bdeflate\b/ !~ env[HTTP_ACCEPT_ENCODING]
       inflater = Zlib::Inflate.new(-Zlib::MAX_WBITS)
       body[0] = inflater.inflate(body[0]) << inflater.finish
       inflater.end
-      headers['Content-Length'] = body[0].size.to_s
-      headers.delete('Content-Encoding')
-      headers.delete('Vary')
+      headers[Content_Length] = body[0].size.to_s
+      headers.delete(Content_Encoding)
+      headers.delete(Vary)
     end
     r
   end
 
   def put(key, env)
-    Wrapper.new(env) if 'deflate' != env['HTTP_CONTENT_ENCODING']
+    Wrapper.new(env) if Compression != env[HTTP_CONTENT_ENCODING]
     super(key, env)
   end
 
   def self.extended(obj)
     obj.instance_eval do
-      @headers['Content-Encoding'] = 'deflate'
-      @headers['Vary'] = 'Accept-Encoding'
+      @headers[Content_Encoding] = Compression
+      @headers[Vary] = Accept_Encoding
     end
   end
 
diff --git a/lib/metropolis/gzip.rb b/lib/metropolis/gzip.rb
index b3191dc..98dddd6 100644
--- a/lib/metropolis/gzip.rb
+++ b/lib/metropolis/gzip.rb
@@ -4,26 +4,29 @@ require "zlib"
 # allows storing pre-gzipped data on disk and serving it
 # as-is for clients that accept that gzip encoding
 module Metropolis::Gzip
+  include Metropolis::Constants
+  Compression = "gzip"
+
   def get(key, env)
     status, headers, body = r = super
-    if 200 == status && /\bgzip\b/ !~ env['HTTP_ACCEPT_ENCODING']
+    if 200 == status && /\bgzip\b/ !~ env[HTTP_ACCEPT_ENCODING]
       body[0] = Zlib::GzipReader.new(StringIO.new(body[0])).read
-      headers['Content-Length'] = body[0].size.to_s
-      headers.delete('Content-Encoding')
-      headers.delete('Vary')
+      headers[Content_Length] = body[0].size.to_s
+      headers.delete(Content_Encoding)
+      headers.delete(Vary)
     end
     r
   end
 
   def put(key, env)
-    Wrapper.new(env) if 'gzip' != env['HTTP_CONTENT_ENCODING']
+    Wrapper.new(env) if Compression != env[HTTP_CONTENT_ENCODING]
     super(key, env)
   end
 
   def self.extended(obj)
     obj.instance_eval do
-      @headers['Content-Encoding'] = 'gzip'
-      @headers['Vary'] = 'Accept-Encoding'
+      @headers[Content_Encoding] = Compression
+      @headers[Vary] = Accept_Encoding
     end
   end
 
diff --git a/lib/metropolis/hash.rb b/lib/metropolis/hash.rb
index d5c70cb..75cc14e 100644
--- a/lib/metropolis/hash.rb
+++ b/lib/metropolis/hash.rb
@@ -37,16 +37,16 @@ module Metropolis::Hash
 
   def get(key, env)
     value = @db[key] or return r(404)
-    [ 200, { 'Content-Length' => value.size.to_s }.merge!(@headers), [ value ] ]
+    [ 200, { Content_Length => value.size.to_s }.merge!(@headers), [ value ] ]
   end
 
   def put(key, env)
-    value = env["rack.input"].read
-    case env['HTTP_X_TT_PDMODE']
-    when '1'
+    value = env[Rack_Input].read
+    case env[HTTP_X_TT_PDMODE]
+    when "1"
       @db.exists?(key) and r(409)
       @db[key] = value
-    when '2'
+    when "2"
       (tmp = @db[key] ||= "") << value
     else
       @db[key] = value
diff --git a/lib/metropolis/input_wrapper.rb b/lib/metropolis/input_wrapper.rb
index 12a1bcc..334caf6 100644
--- a/lib/metropolis/input_wrapper.rb
+++ b/lib/metropolis/input_wrapper.rb
@@ -1,9 +1,11 @@
 # -*- encoding: binary -*-
 
 class Metropolis::InputWrapper
+  include Metropolis::Constants
+
   def initialize(env)
-    @input = env["rack.input"]
-    env["rack.input"] = self
+    @input = env[Rack_Input]
+    env[Rack_Input] = self
   end
 
   def read(*args)
diff --git a/lib/metropolis/multi_hash/digest.rb b/lib/metropolis/multi_hash/digest.rb
index 974d7ac..56264aa 100644
--- a/lib/metropolis/multi_hash/digest.rb
+++ b/lib/metropolis/multi_hash/digest.rb
@@ -1,23 +1,25 @@
 # -*- encoding: binary -*-
 require 'digest'
 module Metropolis::MultiHash::Digest
+  N = "N"
+
   def digest_sha1(key)
-    ::Digest::SHA1.digest(key)[0,4].unpack("N")[0]
+    ::Digest::SHA1.digest(key)[0,4].unpack(N)[0]
   end
 
   def digest_md5(key)
-    ::Digest::MD5.digest(key)[0,4].unpack("N")[0]
+    ::Digest::MD5.digest(key)[0,4].unpack(N)[0]
   end
 
   def digest_sha256(key)
-    ::Digest::SHA256.digest(key)[0,4].unpack("N")[0]
+    ::Digest::SHA256.digest(key)[0,4].unpack(N)[0]
   end
 
   def digest_sha384(key)
-    ::Digest::SHA384.digest(key)[0,4].unpack("N")[0]
+    ::Digest::SHA384.digest(key)[0,4].unpack(N)[0]
   end
 
   def digest_sha512(key)
-    ::Digest::SHA512.digest(key)[0,4].unpack("N")[0]
+    ::Digest::SHA512.digest(key)[0,4].unpack(N)[0]
   end
 end
diff --git a/lib/metropolis/suffix_mime.rb b/lib/metropolis/suffix_mime.rb
index 76a3f96..1234e82 100644
--- a/lib/metropolis/suffix_mime.rb
+++ b/lib/metropolis/suffix_mime.rb
@@ -1,5 +1,6 @@
 module Metropolis::SuffixMime
   MIME_TYPES = Rack::Mime::MIME_TYPES
+  include Metropolis::Constants
 
   def get(key, env)
     set_mime(key, super)
@@ -12,7 +13,7 @@ module Metropolis::SuffixMime
   def set_mime(key, response)
     status, headers, _ = response
     200 == status && /(\.[^\.]+)\z/ =~ key and
-      type = MIME_TYPES[$1] and headers["Content-Type"] = type
+      type = MIME_TYPES[$1] and headers[Content_Type] = type
     response
   end
 end
diff --git a/lib/metropolis/tc/hdb.rb b/lib/metropolis/tc/hdb.rb
index e63b015..6ba6f85 100644
--- a/lib/metropolis/tc/hdb.rb
+++ b/lib/metropolis/tc/hdb.rb
@@ -95,15 +95,15 @@ module Metropolis::TC::HDB
   end
 
   def put(key, env)
-    value = env["rack.input"].read
+    value = env[Rack_Input].read
     writer(key) do |hdb|
-      case env['HTTP_X_TT_PDMODE']
-      when '1'
+      case env[HTTP_X_TT_PDMODE]
+      when "1"
         unless hdb.putkeep(key, value)
           TCHDB::EKEEP == hdb.ecode and return r(409)
           ex!(:putkeep, hdb)
         end
-      when '2'
+      when "2"
         hdb.putcat(key, value) or ex!(:putcat, hdb)
       else
         # ttserver does not care for other PDMODE values, so we don't, either
@@ -131,7 +131,7 @@ module Metropolis::TC::HDB
         ex!(:get, hdb)
       end
     end
-    [ 200, { 'Content-Length' => value.size.to_s }.merge!(@headers), [ value ] ]
+    [ 200, { Content_Length => value.size.to_s }.merge!(@headers), [ value ] ]
   end
 
   def close!
diff --git a/lib/metropolis/tdb.rb b/lib/metropolis/tdb.rb
index 5621d17..56709b1 100644
--- a/lib/metropolis/tdb.rb
+++ b/lib/metropolis/tdb.rb
@@ -44,13 +44,13 @@ module Metropolis::TDB
   end
 
   def put(key, env)
-    value = env["rack.input"].read
+    value = env[Rack_Input].read
     db(key) do |tdb|
-      case env['HTTP_X_TT_PDMODE']
-      when '1'
+      case env[HTTP_X_TT_PDMODE]
+      when "1"
         # TODO: make this atomic
         return r(409) if tdb.include?(key)
-      when '2'
+      when "2"
         value = (tdb.get(key) || "") << value
       end
       tdb.store(key, value)
@@ -64,6 +64,6 @@ module Metropolis::TDB
 
   def get(key, env)
     value = db(key) { |tdb| tdb.fetch(key, @rbuf) } or return r(404)
-    [ 200, { 'Content-Length' => value.size.to_s }.merge!(@headers), [ value ] ]
+    [ 200, { Content_Length => value.size.to_s }.merge!(@headers), [ value ] ]
   end
 end