Class: RingCache
- Inherits:
-
Object
show all
- Defined in:
- lib/ring_cache.rb,
lib/ring_cache/version.rb
Defined Under Namespace
Classes: KeyNotFoundError
Constant Summary
collapse
- VERSION =
'1.1'
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(options = {}) ⇒ RingCache
Returns a new instance of RingCache.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# File 'lib/ring_cache.rb', line 8
def initialize(options = {})
@duplicate_on_store = options.fetch(:duplicate_on_store, false)
@duplicate_on_retrieve = options.fetch(:duplicate_on_retrieve, false)
execute_on_retrieve = options.fetch(:execute_on_retrieve, [])
@execute_on_retrieve = execute_on_retrieve.kind_of?(Array) ? execute_on_retrieve : [execute_on_retrieve]
@capacity = options.fetch(:capacity, nil)
@target_hit_rate = options.fetch(:target_hit_rate, nil)
unless @target_hit_rate.nil? or (@target_hit_rate > 0.0 and @target_hit_rate < 1.0)
raise ArgumentError, 'Invalid target_hit_rate'
end
reset
end
|
Instance Attribute Details
#capacity ⇒ Object
Returns the value of attribute capacity.
6
7
8
|
# File 'lib/ring_cache.rb', line 6
def capacity
@capacity
end
|
#target_hit_rate ⇒ Object
Returns the value of attribute target_hit_rate.
6
7
8
|
# File 'lib/ring_cache.rb', line 6
def target_hit_rate
@target_hit_rate
end
|
Instance Method Details
#evict(key) ⇒ Object
24
25
26
27
28
29
30
31
32
|
# File 'lib/ring_cache.rb', line 24
def evict(key)
if @cache.has_key?(key)
@access_time_index.delete([@cache[key][:last_accessed_at], key])
@cache.delete(key)
true
else
false
end
end
|
#fetch(key, options = {}, &block) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
|
# File 'lib/ring_cache.rb', line 34
def fetch(key, options = {}, &block)
cache_nil = options.fetch(:cache_nil, true)
unless (data = read(key))
data = catch(:dont_cache) do
data_to_cache = block.call
write(key, data_to_cache) unless data_to_cache.nil? and !cache_nil
data_to_cache
end
end
data
end
|
#has_key?(key) ⇒ Boolean
47
48
49
|
# File 'lib/ring_cache.rb', line 47
def has_key?(key)
@cache.has_key?(key)
end
|
#hit_rate ⇒ Object
51
52
53
|
# File 'lib/ring_cache.rb', line 51
def hit_rate
(@access_count > 0) ? (@hit_count / @access_count.to_f) : 0.0
end
|
#last_access(key) ⇒ Object
55
56
57
|
# File 'lib/ring_cache.rb', line 55
def last_access(key)
has_key?(key) ? @cache[key][:last_accessed_at] : nil
end
|
#read(key) ⇒ Object
92
93
94
95
96
|
# File 'lib/ring_cache.rb', line 92
def read(key)
read!(key)
rescue KeyNotFoundError
return nil
end
|
#read!(key) ⇒ Object
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/ring_cache.rb', line 59
def read!(key)
@access_count += 1
if @cache.has_key?(key)
access_time = Time.now
@access_time_index.delete([@cache[key][:last_accessed_at], key])
@access_time_index << [access_time, key]
@cache[key][:last_accessed_at] = access_time
@hit_count += 1
data = @cache[key][:data]
data = data.dup if @duplicate_on_retrieve and !data.nil?
unless @execute_on_retrieve.empty? or data.nil?
@execute_on_retrieve.each do |method|
method = method.to_sym
if data.respond_to?(method)
data.send(method)
elsif data.kind_of?(Enumerable) and data.all? { |d| d.respond_to?(method) }
data.each { |d| d.send(method) }
else
raise RuntimeError, "Retrieved data does not respond to #{method.inspect}"
end
end
end
data
else
fail KeyNotFoundError, "Cache does not have content indexed by #{key}"
end
end
|
#reset ⇒ Object
98
99
100
101
102
103
104
|
# File 'lib/ring_cache.rb', line 98
def reset
@cache = {}
@access_time_index = SortedSet.new
@access_count = 0
@hit_count = 0
true
end
|
#size ⇒ Object
106
107
108
|
# File 'lib/ring_cache.rb', line 106
def size
@cache.size
end
|
#write(key, data) ⇒ Object
110
111
112
113
114
115
116
117
118
119
|
# File 'lib/ring_cache.rb', line 110
def write(key, data)
unless evict(key)
evict_oldest if must_evict?
end
data = data.dup if @duplicate_on_store and !data.nil?
access_time = Time.now
@cache[key] = { last_accessed_at: access_time, data: data }
@access_time_index << [access_time, key]
true
end
|