Class: DiskStore

Inherits:
Object
  • Object
show all
Defined in:
lib/disk_store.rb,
lib/disk_store/reaper.rb,
lib/disk_store/version.rb,
lib/disk_store/eviction_strategies/lru.rb

Defined Under Namespace

Classes: MD5DidNotMatch, Reaper

Constant Summary collapse

DIR_FORMATTER =
"%03X"
FILENAME_MAX_SIZE =

max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write)

228
EXCLUDED_DIRS =
['.', '..'].freeze
VERSION =
"0.4.1"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path = nil, opts = {}) ⇒ DiskStore

Returns a new instance of DiskStore.



13
14
15
16
17
18
# File 'lib/disk_store.rb', line 13

def initialize(path=nil, opts = {})
  path ||= "."
  @root_path = File.expand_path path
  @options = opts
  @reaper = Reaper.spawn_for(@root_path, @options)
end

Instance Attribute Details

#reaperObject (readonly)

Returns the value of attribute reaper.



11
12
13
# File 'lib/disk_store.rb', line 11

def reaper
  @reaper
end

Instance Method Details

#delete(key) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/disk_store.rb', line 56

def delete(key)
  file_path = key_file_path(key)
  if exist?(key)
    begin
      File.delete(file_path)
    rescue Error::ENOENT
      # Weirdness can happen with concurrency
    end
    
    delete_empty_directories(File.dirname(file_path))
  end
  true
end

#exist?(key) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/disk_store.rb', line 52

def exist?(key)
  File.exist?(key_file_path(key))
end

#fetch(key, md5 = nil) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/disk_store.rb', line 70

def fetch(key, md5 = nil)
  if block_given?
    if exist?(key)
      read(key, md5)
    else
      io = yield
      write(key, io, md5)
      read(key)
    end
  else
    read(key, md5)
  end
end

#read(key, md5 = nil) ⇒ Object



20
21
22
23
24
25
26
27
# File 'lib/disk_store.rb', line 20

def read(key, md5 = nil)
  fd = File.open(key_file_path(key), 'rb')
  validate_file!(key_file_path(key), md5) if !md5.nil?
  fd
rescue MD5DidNotMatch => e
  delete(key)
  raise e
end

#write(key, io, md5 = nil) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/disk_store.rb', line 29

def write(key, io, md5 = nil)
  file_path = key_file_path(key)
  ensure_cache_path(File.dirname(file_path))

  fd = File.open(file_path, 'wb') do |f|
    begin
      f.flock File::LOCK_EX
      IO::copy_stream(io, f)
    ensure
      # We need to make sure that any data written makes it to the disk.
      # http://stackoverflow.com/questions/6701103/understanding-ruby-and-os-i-o-buffering
      f.fsync
      f.flock File::LOCK_UN
    end
  end

  validate_file!(file_path, md5) if !md5.nil?
  fd
rescue MD5DidNotMatch => e
  delete(key)
  raise e
end