Class: LRUHash
- Inherits:
-
Object
- Object
- LRUHash
- Defined in:
- lib/semian/lru_hash.rb
Defined Under Namespace
Classes: NoopMutex
Instance Method Summary collapse
- #[](key) ⇒ Object
- #[]=(key, resource) ⇒ Object
- #clear ⇒ Object
- #count(&block) ⇒ Object
- #delete(key) ⇒ Object
- #empty? ⇒ Boolean
-
#get(key) ⇒ Object
This method uses the property that “Hashes enumerate their values in the order that the corresponding keys were inserted.” Deleting a key and re-inserting it effectively moves it to the front of the cache.
-
#initialize(max_size: Semian.maximum_lru_size, min_time: Semian.minimum_lru_time) ⇒ LRUHash
constructor
Create an LRU hash.
- #keys ⇒ Object
- #set(key, resource) ⇒ Object
- #size ⇒ Object
- #values ⇒ Object
Constructor Details
#initialize(max_size: Semian.maximum_lru_size, min_time: Semian.minimum_lru_time) ⇒ LRUHash
Create an LRU hash
Arguments:
+max_size+ The maximum size of the table
+min_time+ The minimum time a resource can live in the cache
Note:
The +min_time+ is a stronger guarantee than +max_size+. That is, if there are
more than +max_size+ entries in the cache, but they've all been updated more
recently than +min_time+, the garbage collection will not remove them and the
cache can grow without bound. This usually means that you have many active
circuits to disparate endpoints (or your circuit names are bad).
If the max_size is 0, the garbage collection will be very aggressive and
potentially computationally expensive.
52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/semian/lru_hash.rb', line 52 def initialize(max_size: Semian.maximum_lru_size, min_time: Semian.minimum_lru_time) @max_size = max_size @min_time = min_time @table = {} @lock = if Semian.thread_safe? Mutex.new else NoopMutex.new end end |
Instance Method Details
#[](key) ⇒ Object
115 116 117 |
# File 'lib/semian/lru_hash.rb', line 115 def [](key) get(key) end |
#[]=(key, resource) ⇒ Object
111 112 113 |
# File 'lib/semian/lru_hash.rb', line 111 def []=(key, resource) set(key, resource) end |
#clear ⇒ Object
34 35 36 |
# File 'lib/semian/lru_hash.rb', line 34 def clear @lock.synchronize { @table.clear } end |
#count(&block) ⇒ Object
68 69 70 |
# File 'lib/semian/lru_hash.rb', line 68 def count(&block) @lock.synchronize { @table.count(&block) } end |
#delete(key) ⇒ Object
105 106 107 108 109 |
# File 'lib/semian/lru_hash.rb', line 105 def delete(key) @lock.synchronize do @table.delete(key) end end |
#empty? ⇒ Boolean
72 73 74 |
# File 'lib/semian/lru_hash.rb', line 72 def empty? @lock.synchronize { @table.empty? } end |
#get(key) ⇒ Object
This method uses the property that “Hashes enumerate their values in the order that the corresponding keys were inserted.” Deleting a key and re-inserting it effectively moves it to the front of the cache. Update the ‘updated_at` field so we can use it later do decide if the resource is “in use”.
94 95 96 97 98 99 100 101 102 103 |
# File 'lib/semian/lru_hash.rb', line 94 def get(key) @lock.synchronize do found = @table.delete(key) if found @table[key] = found found.updated_at = Time.now end found end end |
#keys ⇒ Object
30 31 32 |
# File 'lib/semian/lru_hash.rb', line 30 def keys @lock.synchronize { @table.keys } end |
#set(key, resource) ⇒ Object
80 81 82 83 84 85 86 87 |
# File 'lib/semian/lru_hash.rb', line 80 def set(key, resource) @lock.synchronize do @table.delete(key) @table[key] = resource resource.updated_at = Time.now end clear_unused_resources if @table.length > @max_size end |
#size ⇒ Object
64 65 66 |
# File 'lib/semian/lru_hash.rb', line 64 def size @lock.synchronize { @table.size } end |
#values ⇒ Object
76 77 78 |
# File 'lib/semian/lru_hash.rb', line 76 def values @lock.synchronize { @table.values } end |