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, default = nil, ttl: :default, metadata: {}) ⇒ 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.
54 55 56 57 58 59 60 61 |
# File 'lib/lutaml/store/cache_store.rb', line 54 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.
52 53 54 |
# File 'lib/lutaml/store/cache_store.rb', line 52 def adapter @adapter end |
Instance Method Details
#cache_info ⇒ Object
190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/lutaml/store/cache_store.rb', line 190 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
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/lutaml/store/cache_store.rb', line 171 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
118 119 120 121 |
# File 'lib/lutaml/store/cache_store.rb', line 118 def clear @access_times.clear @adapter.clear end |
#close ⇒ Object
240 241 242 |
# File 'lib/lutaml/store/cache_store.rb', line 240 def close @adapter.close end |
#delete(key) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/lutaml/store/cache_store.rb', line 99 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
123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/lutaml/store/cache_store.rb', line 123 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
163 164 165 |
# File 'lib/lutaml/store/cache_store.rb', line 163 def expire(key) delete(key) end |
#expire_all ⇒ Object
167 168 169 |
# File 'lib/lutaml/store/cache_store.rb', line 167 def expire_all clear end |
#fetch(key, default = nil, ttl: :default, metadata: {}) ⇒ Object
226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/lutaml/store/cache_store.rb', line 226 def fetch(key, default = nil, ttl: :default, metadata: {}) value = get(key) return value unless value.nil? if block_given? value = yield set(key, value, ttl: ttl, metadata: ) value elsif !default.nil? set(key, default, ttl: ttl, metadata: ) default end end |
#get(key) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/lutaml/store/cache_store.rb', line 63 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
137 138 139 140 |
# File 'lib/lutaml/store/cache_store.rb', line 137 def keys cleanup_expired if should_cleanup? @adapter.keys.select { |key| exists?(key) } end |
#set(key, value, ttl: :default, metadata: {}) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/lutaml/store/cache_store.rb', line 85 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
142 143 144 145 |
# File 'lib/lutaml/store/cache_store.rb', line 142 def size cleanup_expired if should_cleanup? keys.size end |
#touch(key, ttl: nil) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/lutaml/store/cache_store.rb', line 205 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
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/lutaml/store/cache_store.rb', line 147 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 |