-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial addition of ttl cache under the names LruRedux::TTL::Cache an…
…d LruRedux::TTL::ThreadSafeCache. Added #ttl method (noop) to lru cache to keep cache api consistent.
- Loading branch information
Seberius
committed
Mar 29, 2015
1 parent
ca99733
commit e4f4b6d
Showing
6 changed files
with
219 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,4 +6,6 @@ | |
|
||
require "lru_redux/thread_safe_cache" | ||
|
||
require "lru_redux/ttl" | ||
|
||
require "lru_redux/version" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
require "lru_redux/util" | ||
|
||
require "lru_redux/ttl/cache" | ||
require "lru_redux/ttl/thread_safe_cache" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
module LruRedux | ||
module TTL | ||
class Cache | ||
def initialize(*args) | ||
max_size, ttl = args | ||
|
||
ttl ||= :none | ||
|
||
raise ArgumentError.new(:max_size) if | ||
max_size < 1 | ||
raise ArgumentError.new(:ttl) unless | ||
ttl == :none || ((ttl.is_a? Numeric) && ttl >= 0) | ||
|
||
@max_size = max_size | ||
@ttl = ttl | ||
@data_lru = {} | ||
@data_ttl = {} | ||
end | ||
|
||
def max_size=(max_size) | ||
max_size ||= @max_size | ||
|
||
raise ArgumentError.new(:max_size) if | ||
max_size < 1 | ||
|
||
@max_size = max_size | ||
|
||
resize | ||
end | ||
|
||
def ttl=(ttl) | ||
ttl ||= @ttl | ||
|
||
raise ArgumentError.new(:ttl) unless | ||
ttl == :none || ((ttl.is_a? Numeric) && ttl >= 0) | ||
|
||
@ttl = ttl | ||
|
||
ttl_evict | ||
end | ||
|
||
def getset(key) | ||
ttl_evict | ||
|
||
found = true | ||
value = @data_lru.delete(key){ found = false } | ||
if found | ||
@data_lru[key] = value | ||
else | ||
result = @data_lru[key] = yield | ||
@data_ttl = Time.now | ||
|
||
if @data_lru.size > @max_size | ||
key, _ = @data_lru.tail | ||
|
||
@data_ttl.delete(key) | ||
@data_lru.delete(key) | ||
end | ||
|
||
result | ||
end | ||
end | ||
|
||
def fetch(key) | ||
ttl_evict | ||
|
||
found = true | ||
value = @data_lru.delete(key){ found = false } | ||
if found | ||
@data_lru[key] = value | ||
else | ||
yield if block_given? | ||
end | ||
end | ||
|
||
def [](key) | ||
ttl_evict | ||
|
||
found = true | ||
value = @data_lru.delete(key){ found = false } | ||
if found | ||
@data_lru[key] = value | ||
else | ||
nil | ||
end | ||
end | ||
|
||
def []=(key, val) | ||
ttl_evict | ||
|
||
@data_lru.delete(key) | ||
@data_ttl.delete(key) | ||
|
||
@data_lru[key] = val | ||
@data_ttl[key] = Time.now | ||
|
||
if @data_lru.size > @max_size | ||
key, _ = @data_lru.tail | ||
|
||
@data_ttl.delete(key) | ||
@data_lru.delete(key) | ||
end | ||
|
||
val | ||
end | ||
|
||
def each | ||
ttl_evict | ||
|
||
array = @data_lru.to_a | ||
array.reverse!.each do |pair| | ||
yield pair | ||
end | ||
end | ||
|
||
# used further up the chain, non thread safe each | ||
alias_method :each_unsafe, :each | ||
|
||
def to_a | ||
ttl_evict | ||
|
||
array = @data_lru.to_a | ||
array.reverse! | ||
end | ||
|
||
def delete(key) | ||
ttl_evict | ||
|
||
@data_lru.delete(key) | ||
@data_ttl.delete(key) | ||
end | ||
|
||
alias_method :evict, :delete | ||
|
||
def key?(key) | ||
ttl_evict | ||
|
||
@data_lru.key?(key) | ||
end | ||
|
||
alias_method :has_key?, :key? | ||
|
||
def clear | ||
@data_lru.clear | ||
@data_ttl.clear | ||
end | ||
|
||
def count | ||
@data_lru.size | ||
end | ||
|
||
# for cache validation only, ensures all is sound | ||
def valid? | ||
@data_lru.size == @data_ttl.size | ||
end | ||
|
||
protected | ||
|
||
def ttl_evict | ||
return if @ttl == :none | ||
|
||
ttl_horizon = Time.now - @ttl | ||
key, time = @data_ttl.tail | ||
|
||
until time.nil? || time > ttl_horizon | ||
@data_ttl.delete(key) | ||
@data_lru.delete(key) | ||
|
||
key, time = @data_ttl.tail | ||
end | ||
end | ||
|
||
def resize | ||
ttl_evict | ||
|
||
while @data_lru.size > @max_size | ||
key, _ = @data_lru.tail | ||
|
||
@data_ttl.delete(key) | ||
@data_lru.delete(key) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
class LruRedux::TTL::ThreadSafeCache < LruRedux::TTL::Cache | ||
include LruRedux::Util::SafeSync | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters