Class: Lutaml::Store::CacheStore
- Inherits:
-
Object
- Object
- Lutaml::Store::CacheStore
- Defined in:
- lib/lutaml/store/cache_store.rb
Overview
TTL-aware cache store with LRU eviction. Wraps a storage adapter directly.
Defined Under Namespace
Classes: CacheEntry
Instance Attribute Summary collapse
-
#adapter ⇒ Object
readonly
Returns the value of attribute adapter.
Instance Method Summary collapse
- #cache_info ⇒ Object
- #cleanup_expired ⇒ Object
- #clear ⇒ Object
- #close ⇒ Object
- #delete(key) ⇒ Object
- #exists?(key) ⇒ Boolean
- #expire(key) ⇒ Object
- #expire_all ⇒ Object
- #fetch(key, ttl: :default, metadata: {}, &block) ⇒ Object
- #get(key) ⇒ Object
-
#initialize(config = {}) ⇒ CacheStore
constructor
A new instance of CacheStore.
- #keys ⇒ Object
- #set(key, value, ttl: :default, metadata: {}) ⇒ Object
- #size ⇒ Object
- #touch(key, ttl: nil) ⇒ Object
- #ttl(key) ⇒ Object
Constructor Details
#initialize(config = {}) ⇒ CacheStore
Returns a new instance of CacheStore.
53 54 55 56 57 58 59 60 |
# File 'lib/lutaml/store/cache_store.rb', line 53 def initialize(config = {}) @adapter = create_adapter(config) @default_ttl = config[:default_ttl] @max_size = config[:max_size] @cleanup_interval = config[:cleanup_interval] || 300 @last_cleanup = Time.now @access_times = {} end |
Instance Attribute Details
#adapter ⇒ Object (readonly)
Returns the value of attribute adapter.
51 52 53 |
# File 'lib/lutaml/store/cache_store.rb', line 51 def adapter @adapter end |
Instance Method Details
#cache_info ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/lutaml/store/cache_store.rb', line 189 def cache_info total_keys = @adapter.keys.size valid_keys = keys.size expired_keys = total_keys - valid_keys { total_entries: total_keys, valid_entries: valid_keys, expired_entries: expired_keys, max_size: @max_size, default_ttl: @default_ttl, last_cleanup: @last_cleanup } end |
#cleanup_expired ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/lutaml/store/cache_store.rb', line 170 def cleanup_expired expired_keys = [] @adapter.each_key do |key| entry_data = @adapter.get(key) next unless entry_data entry = deserialize_entry(entry_data) expired_keys << key if entry.expired? rescue StandardError expired_keys << key end expired_keys.each { |key| delete(key) } @last_cleanup = Time.now expired_keys.size end |
#clear ⇒ Object
117 118 119 120 |
# File 'lib/lutaml/store/cache_store.rb', line 117 def clear @access_times.clear @adapter.clear end |
#close ⇒ Object
236 237 238 |
# File 'lib/lutaml/store/cache_store.rb', line 236 def close @adapter.close end |
#delete(key) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/lutaml/store/cache_store.rb', line 98 def delete(key) value = nil entry_data = @adapter.get(key) if entry_data begin entry = deserialize_entry(entry_data) value = entry.value unless entry.expired? rescue StandardError # If we can't deserialize, treat as nil end end @access_times.delete(key) deleted = @adapter.delete(key) deleted ? value : nil end |
#exists?(key) ⇒ Boolean
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/lutaml/store/cache_store.rb', line 122 def exists?(key) return false unless @adapter.exists?(key) entry_data = @adapter.get(key) return false unless entry_data begin entry = deserialize_entry(entry_data) !entry.expired? rescue StandardError false end end |
#expire(key) ⇒ Object
162 163 164 |
# File 'lib/lutaml/store/cache_store.rb', line 162 def expire(key) delete(key) end |
#expire_all ⇒ Object
166 167 168 |
# File 'lib/lutaml/store/cache_store.rb', line 166 def expire_all clear end |
#fetch(key, ttl: :default, metadata: {}, &block) ⇒ Object
225 226 227 228 229 230 231 232 233 234 |
# File 'lib/lutaml/store/cache_store.rb', line 225 def fetch(key, ttl: :default, metadata: {}, &block) value = get(key) return value unless value.nil? return nil unless block_given? value = block.call set(key, value, ttl: ttl, metadata: ) value end |
#get(key) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/lutaml/store/cache_store.rb', line 62 def get(key) cleanup_expired if should_cleanup? entry_data = @adapter.get(key) return nil unless entry_data begin entry = deserialize_entry(entry_data) if entry.expired? delete(key) return nil end @access_times[key] = Time.now entry.value rescue StandardError delete(key) nil end end |
#keys ⇒ Object
136 137 138 139 |
# File 'lib/lutaml/store/cache_store.rb', line 136 def keys cleanup_expired if should_cleanup? @adapter.keys.select { |key| exists?(key) } end |
#set(key, value, ttl: :default, metadata: {}) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/lutaml/store/cache_store.rb', line 84 def set(key, value, ttl: :default, metadata: {}) cleanup_expired if should_cleanup? evict_if_needed effective_ttl = ttl == :default ? @default_ttl : ttl entry = CacheEntry.new(value, ttl: effective_ttl, metadata: ) serialized_entry = serialize_entry(entry) @adapter.set(key, serialized_entry) @access_times[key] = Time.now value end |
#size ⇒ Object
141 142 143 144 |
# File 'lib/lutaml/store/cache_store.rb', line 141 def size cleanup_expired if should_cleanup? keys.size end |
#touch(key, ttl: nil) ⇒ Object
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/lutaml/store/cache_store.rb', line 204 def touch(key, ttl: nil) entry_data = @adapter.get(key) return false unless entry_data begin entry = deserialize_entry(entry_data) return false if entry.expired? new_ttl = ttl || entry.ttl new_entry = CacheEntry.new(entry.value, ttl: new_ttl, metadata: entry.) serialized_entry = serialize_entry(new_entry) @adapter.set(key, serialized_entry) @access_times[key] = Time.now true rescue StandardError false end end |
#ttl(key) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/lutaml/store/cache_store.rb', line 146 def ttl(key) entry_data = @adapter.get(key) return nil unless entry_data begin entry = deserialize_entry(entry_data) return nil if entry.expired? return nil unless entry.ttl remaining = entry.ttl - (Time.now - entry.created_at) remaining.positive? ? remaining : nil rescue StandardError nil end end |