Permalink
Browse files

use an adapter class to avoid runtime checks

We can speed up cache get and set by using a proxy adapter object.  Then
we only have to check for respond_to once (rather than every get / set)
  • Loading branch information...
1 parent cfebc24 commit b147caa1c3fcdda753dea9408d369c42608df0c2 @tenderlove tenderlove committed Nov 14, 2013
Showing with 39 additions and 29 deletions.
  1. +1 −0 lib/sprockets/base.rb
  2. +36 −29 lib/sprockets/caching.rb
  3. +1 −0 lib/sprockets/environment.rb
  4. +1 −0 lib/sprockets/index.rb
View
1 lib/sprockets/base.rb
@@ -96,6 +96,7 @@ def digest
def cache=(cache)
expire_index!
@cache = cache
+ @cache_adapter = make_cache_adapter(cache)
end
def prepend_path(path)
View
65 lib/sprockets/caching.rb
@@ -2,43 +2,18 @@ module Sprockets
# `Caching` is an internal mixin whose public methods are exposed on
# the `Environment` and `Index` classes.
module Caching
+ attr_reader :cache_adapter
+
# Low level cache getter for `key`. Checks a number of supported
# cache interfaces.
def cache_get(key)
- # `Cache#get(key)` for Memcache
- if cache.respond_to?(:get)
- cache.get(key)
-
- # `Cache#[key]` so `Hash` can be used
- elsif cache.respond_to?(:[])
- cache[key]
-
- # `Cache#read(key)` for `ActiveSupport::Cache` support
- elsif cache.respond_to?(:read)
- cache.read(key)
-
- else
- nil
- end
+ cache_adapter.get(key)
end
# Low level cache setter for `key`. Checks a number of supported
# cache interfaces.
def cache_set(key, value)
- # `Cache#set(key, value)` for Memcache
- if cache.respond_to?(:set)
- cache.set(key, value)
-
- # `Cache#[key]=value` so `Hash` can be used
- elsif cache.respond_to?(:[]=)
- cache[key] = value
-
- # `Cache#write(key, value)` for `ActiveSupport::Cache` support
- elsif cache.respond_to?(:write)
- cache.write(key, value)
- end
-
- value
+ cache_adapter.set(key, value)
end
protected
@@ -92,5 +67,37 @@ def cache_set_hash(key, hash)
cache_set(expand_cache_key(key), hash)
hash
end
+
+ def make_cache_adapter(cache)
+ # `Cache#get(key)` for Memcache
+ if cache.respond_to?(:get)
+ cache
+
+ # `Cache#[key]` so `Hash` can be used
+ elsif cache.respond_to?(:[])
+ HashAdapter.new cache
+
+ # `Cache#read(key)` for `ActiveSupport::Cache` support
+ elsif cache.respond_to?(:read)
+ ReadWriteAdapter.new cache
+ else
+ NullAdapter.new
+ end
+ end
+
+ class HashAdapter < Struct.new(:cache)
+ def get(key); cache[key]; end
+ def set(key, value); cache[key] = value; end
+ end
+
+ class ReadWriteAdapter < Struct.new(:cache)
+ def get(key); cache.read(key); end
+ def set(key, value); cache.write(key, value); end
+ end
+
+ class NullAdapter
+ def get(key); nil; end
+ def set(key, value); value; end
+ end
end
end
View
1 lib/sprockets/environment.rb
@@ -51,6 +51,7 @@ def initialize(root = ".")
@trail.append_extension(ext)
end
+ self.cache = nil
expire_index!
yield self if block_given?
View
1 lib/sprockets/index.rb
@@ -22,6 +22,7 @@ def initialize(environment)
@logger = environment.logger
@context_class = environment.context_class
@cache = environment.cache
+ @cache_adapter = environment.cache_adapter
@trail = environment.trail.index
@digest = environment.digest
@digest_class = environment.digest_class

0 comments on commit b147caa

Please sign in to comment.