From 2c913347a6e5cc8be776b14e1a177adec0fbd5b6 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 17 Jan 2011 03:17:28 +0000 Subject: use constants everywhere to reduce GC thrashing This makes it easier to notice a typo, too. --- lib/metropolis.rb | 1 + lib/metropolis/common.rb | 13 ++++++++----- lib/metropolis/common/ro.rb | 6 ++++-- lib/metropolis/constants.rb | 20 ++++++++++++++++++++ lib/metropolis/deflate.rb | 17 ++++++++++------- lib/metropolis/gzip.rb | 17 ++++++++++------- lib/metropolis/hash.rb | 10 +++++----- lib/metropolis/input_wrapper.rb | 6 ++++-- lib/metropolis/multi_hash/digest.rb | 12 +++++++----- lib/metropolis/suffix_mime.rb | 3 ++- lib/metropolis/tc/hdb.rb | 10 +++++----- lib/metropolis/tdb.rb | 10 +++++----- 12 files changed, 81 insertions(+), 44 deletions(-) create mode 100644 lib/metropolis/constants.rb 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 -- cgit v1.2.3-24-ge0c7