Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #616 from sstephenson/file-store-cache-count-bytes

Change File Store cache to count bytes, not files
  • Loading branch information...
commit ab49b3452022b6dc0bd9b53ce9bd78dbf406eefd 2 parents 17860d2 + 8412988
@josh josh authored
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
Please sign in to comment.
Something went wrong with that request. Please try again.