Class: TimeoutCache
- Inherits:
-
Object
- Object
- TimeoutCache
- Defined in:
- lib/timeout_cache.rb
Overview
TimeoutCache is a simple key-value store where entries expire after a certain time. It implements parts of the Hash interface.
cache = TimeoutCache.new
cache[:foo] = :bar
cache[:foo] #=> bar
# wait some time (by default, 60 seconds)
cache[:foo] #=> nil
Defined Under Namespace
Classes: TimedObject
Constant Summary collapse
- VERSION =
"0.0.2"
- DEFAULT_TIMEOUT =
The default number of seconds an object stays alive.
60
Instance Attribute Summary collapse
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
Instance Method Summary collapse
-
#[](key) ⇒ Object
(also: #get)
Returns the value for the given key.
-
#[]=(key, value) ⇒ Object
Stores an object in the cache with an expire time DEFAULT_TIMEOUT seconds from now.
-
#delete(key) ⇒ Object
Deletes the key-value pair for the given key.
-
#empty? ⇒ Boolean
Calls #prune and then returns true if the cache is empty, otherwise false.
-
#expire_time(key) ⇒ Object
Returns the expire time of the value for the given key.
-
#initialize(timeout = DEFAULT_TIMEOUT) ⇒ TimeoutCache
constructor
Creates a new TimeoutCache.
- #inspect ⇒ Object
-
#prune ⇒ Object
Removes any expired entries from the cache.
-
#set(key, value, options = {}) ⇒ Object
Stores an object in the cache.
-
#size ⇒ Object
(also: #length)
Calls #prune and then returns the number of items in the cache.
Constructor Details
#initialize(timeout = DEFAULT_TIMEOUT) ⇒ TimeoutCache
Creates a new TimeoutCache.
If timeout
is specified, #to_int is called on the argument, and the return value is used as the default survival time for a cache entry in seconds.
If no default value is used, then DEFAULT_TIMEOUT is the default time-to-expire in seconds.
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/timeout_cache.rb', line 47 def initialize(timeout = DEFAULT_TIMEOUT) timeout = timeout.to_int if timeout.respond_to?(:to_int) raise ArgumentError.new("Timeout must be > 0") unless timeout > 0 @timeout = timeout # we can use this for look-ups in O(1), instead of only find-min in O(1) @store = {} end |
Instance Attribute Details
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
37 38 39 |
# File 'lib/timeout_cache.rb', line 37 def timeout @timeout end |
Instance Method Details
#[](key) ⇒ Object Also known as: get
Returns the value for the given key. If there is no such key in the cache, then this returns nil. If the value has an expire time earlier than or equal to the current time, this returns nil.
This method calls #prune whenever it finds an element that has expired.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/timeout_cache.rb', line 70 def [](key) val = @store[key] if val if val.expired? prune nil else val.value end else nil end end |
#[]=(key, value) ⇒ Object
Stores an object in the cache with an expire time DEFAULT_TIMEOUT seconds from now.
93 94 95 96 |
# File 'lib/timeout_cache.rb', line 93 def []=(key, value) v = TimedObject.new(value, Time.now + timeout) @store[key] = v end |
#delete(key) ⇒ Object
Deletes the key-value pair for the given key.
Returns nil if there is no such key, otherwise returns the deleted value.
147 148 149 150 |
# File 'lib/timeout_cache.rb', line 147 def delete(key) v = @store.delete(key) v ? v.value : v end |
#empty? ⇒ Boolean
Calls #prune and then returns true if the cache is empty, otherwise false.
139 140 141 142 |
# File 'lib/timeout_cache.rb', line 139 def empty? prune @store.empty? end |
#expire_time(key) ⇒ Object
Returns the expire time of the value for the given key.
87 88 89 |
# File 'lib/timeout_cache.rb', line 87 def expire_time(key) @store[key].expires_at end |
#inspect ⇒ Object
166 167 168 |
# File 'lib/timeout_cache.rb', line 166 def inspect %Q{#<#{self.class} #{@store.inspect}>} end |
#prune ⇒ Object
Removes any expired entries from the cache.
If nothing was removed, returns nil, otherwise returns the number of elements removed.
156 157 158 159 160 161 162 163 164 |
# File 'lib/timeout_cache.rb', line 156 def prune return nil if @store.empty? count = 0 @store.delete_if { |k, v| v.expired? && count += 1 } count == 0 ? nil : count end |
#set(key, value, options = {}) ⇒ Object
Stores an object in the cache. options is a hash with symbol keys:
- :time
-
can be either an Integer representing the number of seconds the object should be alive or a Time object representing a fixed time.
If time is not specified in the hash, the default timeout length is used.
If the object would expire immediately, returns nil, otherwise returns the object stored.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/timeout_cache.rb', line 106 def set(key, value, = {}) time = [:time] || timeout # we can technically do away with checking against Integer explicitly since # the to_int call will take care of it for us through Integer#to_int returning # self, but it's here for the sake of clarity, mostly. # # on the other hand, the #to_time call is necessary, since, for some reason, # Time#to_time only exists if you require "time". time = case time when Integer Time.now + time when Time time else if time.respond_to?(:to_int) Time.now + time.to_int elsif time.respond_to?(:to_time) time.to_time end end raise(ArgumentError, "time argument #{time.inspect} could not be converted to a time") if time.nil? return nil if time <= Time.now v = TimedObject.new(value, time) @store[key] = v value end |
#size ⇒ Object Also known as: length
Calls #prune and then returns the number of items in the cache.
59 60 61 62 |
# File 'lib/timeout_cache.rb', line 59 def size prune @store.size end |