Class: FatCache
- Inherits:
-
Object
show all
- Defined in:
- lib/fat_cache.rb,
lib/fat_cache/shortcuts.rb
Defined Under Namespace
Modules: Shortcuts
Classes: AmbiguousHit, CacheMiss
Class Attribute Summary collapse
Class Method Summary
collapse
-
.cached?(key) ⇒ Boolean
-
.dump ⇒ Object
-
.ensure_cached(key) ⇒ Object
-
.ensure_data_available_for(key) ⇒ Object
-
.ensure_fetchable(key) ⇒ Object
-
.ensure_indexed(key, on) ⇒ Object
-
.fetch!(key) ⇒ Object
-
.fetch_index!(key, on) ⇒ Object
-
.fetchable?(key) ⇒ Boolean
-
.get(key) ⇒ Object
Gets from cache or pays fetch cost if necessary to get, raises if none available.
-
.get_index(key, on) ⇒ Object
-
.index(key, on, &block) ⇒ Object
-
.index_defined?(key, on) ⇒ Boolean
-
.indexed?(key, on) ⇒ Boolean
-
.invalidate!(key) ⇒ Object
-
.load!(datastring) ⇒ Object
-
.lookup(key, options = {}) ⇒ Object
-
.one(key, spec = {}) ⇒ Object
-
.one!(key, spec = {}) ⇒ Object
-
.reset! ⇒ Object
-
.set(key, &fetcher) ⇒ Object
Simply store value as key.
Class Attribute Details
.fatcache ⇒ Object
Returns the value of attribute fatcache.
10
11
12
|
# File 'lib/fat_cache.rb', line 10
def fatcache
@fatcache
end
|
.fetchers ⇒ Object
Returns the value of attribute fetchers.
11
12
13
|
# File 'lib/fat_cache.rb', line 11
def fetchers
@fetchers
end
|
.index_fetchers ⇒ Object
Returns the value of attribute index_fetchers.
11
12
13
|
# File 'lib/fat_cache.rb', line 11
def index_fetchers
@index_fetchers
end
|
.indexed_fatcache ⇒ Object
Returns the value of attribute indexed_fatcache.
10
11
12
|
# File 'lib/fat_cache.rb', line 10
def indexed_fatcache
@indexed_fatcache
end
|
.logger ⇒ Object
Returns the value of attribute logger.
13
14
15
|
# File 'lib/fat_cache.rb', line 13
def logger
@logger
end
|
Class Method Details
.cached?(key) ⇒ Boolean
161
162
163
|
# File 'lib/fat_cache.rb', line 161
def cached?(key)
fatcache && fatcache.has_key?(key)
end
|
.dump ⇒ Object
123
124
125
126
127
128
|
# File 'lib/fat_cache.rb', line 123
def dump
Marshal.dump({
:fatcache => self.fatcache,
:indexed_fatcache => self.indexed_fatcache
})
end
|
.ensure_cached(key) ⇒ Object
149
150
151
|
# File 'lib/fat_cache.rb', line 149
def ensure_cached(key)
raise "no data in cache for #{key}" unless cached?(key)
end
|
.ensure_data_available_for(key) ⇒ Object
145
146
147
|
# File 'lib/fat_cache.rb', line 145
def ensure_data_available_for(key)
raise "no data available for #{key}" unless cached?(key) || fetchable?(key)
end
|
.ensure_fetchable(key) ⇒ Object
157
158
159
|
# File 'lib/fat_cache.rb', line 157
def ensure_fetchable(key)
raise "cannot fetch for #{key}" unless fetchable?(key)
end
|
.ensure_indexed(key, on) ⇒ Object
153
154
155
|
# File 'lib/fat_cache.rb', line 153
def ensure_indexed(key, on)
raise "no index for #{key} on #{on.inspect}" unless indexed?(key, on)
end
|
.fetch!(key) ⇒ Object
89
90
91
92
93
94
95
96
97
98
99
100
|
# File 'lib/fat_cache.rb', line 89
def fetch!(key)
ensure_fetchable(key)
if logger
start_time = Time.now
logger.info "[fatcache] <#{key}> fetching ..."
end
fatcache[key] = fetchers[key].call(self)
if logger
took = Time.now - start_time
logger.info "[fatcache] <#{key}> done! #{(took / 60).floor} minutes, #{(took % 60).floor} seconds"
end
end
|
.fetch_index!(key, on) ⇒ Object
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/fat_cache.rb', line 102
def fetch_index!(key, on)
on = [*on]
index(key, on) unless index_defined?(key, on)
indexed_fatcache[key] = {} unless indexed_fatcache.has_key?(key)
raw_data = get(key)
if logger
start_time = Time.now
logger.info "[fatcache] <#{key}> indexing on #{on.inspect} ..."
end
indexed_fatcache[key][on] = index_fetchers[key][on].call(raw_data)
if logger
took = Time.now - start_time
logger.info "[fatcache] <#{key}> indexing on #{on.inspect} done! #{(took / 60).floor} minutes, #{(took % 60).floor} seconds"
end
end
|
.fetchable?(key) ⇒ Boolean
171
172
173
|
# File 'lib/fat_cache.rb', line 171
def fetchable?(key)
fetchers && fetchers.has_key?(key)
end
|
.get(key) ⇒ Object
Gets from cache or pays fetch cost if necessary to get, raises if none available
24
25
26
27
28
29
30
31
32
33
|
# File 'lib/fat_cache.rb', line 24
def get(key)
unless cached?(key)
if fetchable?(key)
fetch!(key)
else
raise CacheMiss, "no data for #{key}"
end
end
fatcache[key]
end
|
.get_index(key, on) ⇒ Object
137
138
139
140
141
142
143
|
# File 'lib/fat_cache.rb', line 137
def get_index(key, on)
on = [*on]
ensure_indexed(key, on)
indexed_fatcache[key][on]
end
|
.index(key, on, &block) ⇒ Object
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
# File 'lib/fat_cache.rb', line 59
def index(key, on, &block)
on = [*on]
ensure_data_available_for(key)
index_fetchers[key] = {} unless index_fetchers.has_key?(key)
if block
wrapped_block = lambda { |item| [*block.call(self, item)] }
index_fetchers[key][on] = lambda { |data| data.group_by(&wrapped_block) }
else
index_fetchers[key][on] = lambda { |data| data.group_by { |x| on.map { |b| x.send(b) } } }
end
end
|
.index_defined?(key, on) ⇒ Boolean
175
176
177
178
179
|
# File 'lib/fat_cache.rb', line 175
def index_defined?(key, on)
index_fetchers &&
index_fetchers.has_key?(key) &&
index_fetchers[key].has_key?(on)
end
|
.indexed?(key, on) ⇒ Boolean
165
166
167
168
169
|
# File 'lib/fat_cache.rb', line 165
def indexed?(key, on)
indexed_fatcache &&
indexed_fatcache.has_key?(key) &&
indexed_fatcache[key].has_key?(on)
end
|
.invalidate!(key) ⇒ Object
82
83
84
85
86
87
|
# File 'lib/fat_cache.rb', line 82
def invalidate!(key)
return unless cached?(key)
indexed_fatcache.delete(key)
fatcache.delete(key)
end
|
.load!(datastring) ⇒ Object
130
131
132
133
134
135
|
# File 'lib/fat_cache.rb', line 130
def load!(datastring)
init unless initted?
data = Marshal.load(datastring)
self.fatcache = data[:fatcache]
self.indexed_fatcache = data[:indexed_fatcache]
end
|
.lookup(key, options = {}) ⇒ Object
35
36
37
38
39
40
41
42
43
|
# File 'lib/fat_cache.rb', line 35
def lookup(key, options={})
options = options.dup
by = [*options.delete(:by)]
using = [*options.delete(:using)]
fetch_index!(key, by) unless indexed?(key, by)
indexed_fatcache[key][by][using]
end
|
.one(key, spec = {}) ⇒ Object
45
46
47
48
49
50
51
|
# File 'lib/fat_cache.rb', line 45
def one(key, spec={})
result = lookup(key, :by => spec.keys, :using => spec.values)
if result && result.length > 1
raise AmbiguousHit, "expected one record for #{key} with #{spec.inspect}, got #{result.inspect}"
end
result.first if result
end
|
.one!(key, spec = {}) ⇒ Object
53
54
55
56
57
|
# File 'lib/fat_cache.rb', line 53
def one!(key, spec={})
result = one(key, spec)
raise CacheMiss, "could not find #{key} with #{spec.inspect}" unless result
result
end
|
.reset! ⇒ Object
181
182
183
184
185
186
187
|
# File 'lib/fat_cache.rb', line 181
def reset!
self.fetchers = nil
self.index_fetchers = nil
self.fatcache = nil
self.indexed_fatcache = nil
@initted = nil
end
|
.set(key, &fetcher) ⇒ Object
Simply store value as key
16
17
18
19
20
|
# File 'lib/fat_cache.rb', line 16
def set(key, &fetcher)
init unless initted?
fetchers[key] = fetcher
end
|