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 in seconds 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.
56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/semian/lru_hash.rb', line 56 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? ::Thread::Mutex.new else ::LRUHash::NoopMutex.new end end |
Instance Method Details
#[](key) ⇒ Object
119 120 121 |
# File 'lib/semian/lru_hash.rb', line 119 def [](key) get(key) end |
#[]=(key, resource) ⇒ Object
115 116 117 |
# File 'lib/semian/lru_hash.rb', line 115 def []=(key, resource) set(key, resource) end |
#clear ⇒ Object
38 39 40 |
# File 'lib/semian/lru_hash.rb', line 38 def clear @lock.synchronize { @table.clear } end |
#count(&block) ⇒ Object
72 73 74 |
# File 'lib/semian/lru_hash.rb', line 72 def count(&block) @lock.synchronize { @table.count(&block) } end |
#delete(key) ⇒ Object
109 110 111 112 113 |
# File 'lib/semian/lru_hash.rb', line 109 def delete(key) @lock.synchronize do @table.delete(key) end end |
#empty? ⇒ Boolean
76 77 78 |
# File 'lib/semian/lru_hash.rb', line 76 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”.
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/semian/lru_hash.rb', line 98 def get(key) @lock.synchronize do found = @table.delete(key) if found @table[key] = found found.updated_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) end found end end |
#keys ⇒ Object
34 35 36 |
# File 'lib/semian/lru_hash.rb', line 34 def keys @lock.synchronize { @table.keys } end |
#set(key, resource) ⇒ Object
84 85 86 87 88 89 90 91 |
# File 'lib/semian/lru_hash.rb', line 84 def set(key, resource) @lock.synchronize do @table.delete(key) @table[key] = resource resource.updated_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) end clear_unused_resources if @table.length > @max_size end |
#size ⇒ Object
68 69 70 |
# File 'lib/semian/lru_hash.rb', line 68 def size @lock.synchronize { @table.size } end |
#values ⇒ Object
80 81 82 |
# File 'lib/semian/lru_hash.rb', line 80 def values @lock.synchronize { @table.values } end |