Permalink
Browse files

Count bytes not key entries

  • Loading branch information...
1 parent 17860d2 commit 8412988317c4ce32aca81457b0ea02b1e19a3911 @josh josh committed Jul 15, 2014
Showing with 30 additions and 16 deletions.
  1. +29 −15 lib/sprockets/cache/file_store.rb
  2. +1 −1 test/test_cache_store.rb
View
44 lib/sprockets/cache/file_store.rb
@@ -17,7 +17,7 @@ class Cache
#
class FileStore
# Internal: Default key limit for store.
- DEFAULT_MAX_SIZE = 1000
+ DEFAULT_MAX_SIZE = 25 * 1024 * 1024
# Internal: Default standard error fatal logger.
#
@@ -34,11 +34,12 @@ def self.default_logger
# max_size - A Integer of the maximum number of keys the store will hold.
# (default: 1000).
def initialize(root, max_size = DEFAULT_MAX_SIZE, logger = self.class.default_logger)
- @root = root
- @size = find_caches.size
+ @root = root
+ @size = find_caches.inject(0) { |n, fn| n + File.size(fn) }
@max_size = max_size
- @logger = logger
- @tmpdir = Dir.tmpdir
+ @gc_size = max_size * 0.75
+ @logger = logger
+ @tmpdir = Dir.tmpdir
end
# Public: Retrieve value from cache.
@@ -88,10 +89,12 @@ def set(key, value)
exists = File.exist?(path)
# Write data
- PathUtils.atomic_write(path, @tmpdir) { |f| Marshal.dump(value, f) }
+ PathUtils.atomic_write(path, @tmpdir) do |f|
+ Marshal.dump(value, f)
+ @size += f.size unless exists
+ end
# GC if necessary
- @size += 1 unless exists
gc! if @size > @max_size
value
@@ -109,23 +112,34 @@ def find_caches
Dir.glob(File.join(@root, '**/*.cache'))
end
+ def compute_size(caches)
+ caches.inject(0) { |sum, (_, stat)| sum + stat.size }
+ end
+
def gc!
start_time = Time.now
- caches = find_caches
- new_size = @max_size * 0.75
- num_to_delete = caches.size - new_size
- return unless num_to_delete > 0
+ caches = find_caches.map! { |filename|
+ [filename, File.stat(filename)]
+ }.sort_by { |filename, stat| stat.mtime.to_i }
+
+ size = compute_size(caches)
+
+ delete_caches, keep_caches = caches.partition { |filename, stat|
+ deleted = size > @gc_size
+ size -= stat.size
+ deleted
+ }
- caches.sort_by! { |path| -File.mtime(path).to_i }
- FileUtils.remove(caches[0, num_to_delete], force: true)
+ return if delete_caches.empty?
- @size = find_caches.size
+ FileUtils.remove(delete_caches.map(&:first), force: true)
+ @size = compute_size(keep_caches)
@logger.warn do
secs = Time.now.to_f - start_time.to_f
"#{self.class}[#{@root}] garbage collected " +
- "#{num_to_delete.to_i} files (#{(secs * 1000).to_i}ms)"
+ "#{delete_caches.size} files (#{(secs * 1000).to_i}ms)"
end
end
end
View
2 test/test_cache_store.rb
@@ -115,7 +115,7 @@ def teardown
def test_inspect
Dir::mktmpdir "sprockets-file-store-inspect" do |dir|
store = Sprockets::Cache::FileStore.new(dir)
- assert_equal "#<Sprockets::Cache::FileStore size=0/1000>", store.inspect
+ assert_equal "#<Sprockets::Cache::FileStore size=0/26214400>", store.inspect
end
end

0 comments on commit 8412988

Please sign in to comment.