Class: Rospatent::Cache
- Inherits:
-
Object
- Object
- Rospatent::Cache
- Includes:
- MonitorMixin
- Defined in:
- lib/rospatent/cache.rb
Overview
Simple in-memory cache with TTL and size limits
Defined Under Namespace
Classes: CacheEntry
Instance Attribute Summary collapse
-
#stats ⇒ Object
readonly
Returns the value of attribute stats.
Instance Method Summary collapse
-
#cleanup_expired ⇒ Integer
Clean up expired entries.
-
#clear ⇒ Object
Clear all entries from the cache.
-
#delete(key) ⇒ Object?
Delete a specific key.
-
#empty? ⇒ Boolean
Check if cache is empty.
-
#fetch(key, default_value = nil, ttl: nil) { ... } ⇒ Object
Fetch value with fallback block or default value.
-
#get(key) ⇒ Object?
Get a value from the cache.
-
#initialize(ttl: 300, max_size: 1000) ⇒ Cache
constructor
Initialize a new cache.
-
#key?(key) ⇒ Boolean
Check if a key exists and is not expired.
-
#set(key, value, ttl: nil) ⇒ Object
Set a value in the cache.
-
#size ⇒ Integer
Get current cache size.
-
#statistics ⇒ Hash
Get cache statistics.
Constructor Details
#initialize(ttl: 300, max_size: 1000) ⇒ Cache
Initialize a new cache
26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/rospatent/cache.rb', line 26 def initialize(ttl: 300, max_size: 1000) super() @ttl = ttl @max_size = max_size @store = {} @access_order = [] @stats = { hits: 0, misses: 0, evictions: 0, expired: 0 } end |
Instance Attribute Details
#stats ⇒ Object (readonly)
Returns the value of attribute stats.
21 22 23 |
# File 'lib/rospatent/cache.rb', line 21 def stats @stats end |
Instance Method Details
#cleanup_expired ⇒ Integer
Clean up expired entries
160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/rospatent/cache.rb', line 160 def cleanup_expired synchronize do expired_keys = [] @store.each do |key, entry| expired_keys << key if entry.expired? end expired_keys.each { |key| delete_entry(key) } @stats[:expired] += expired_keys.size expired_keys.size end end |
#clear ⇒ Object
Clear all entries from the cache
123 124 125 126 127 128 129 |
# File 'lib/rospatent/cache.rb', line 123 def clear synchronize do @store.clear @access_order.clear reset_stats end end |
#delete(key) ⇒ Object?
Delete a specific key
114 115 116 117 118 119 120 |
# File 'lib/rospatent/cache.rb', line 114 def delete(key) synchronize do entry = @store.delete(key) @access_order.delete(key) entry&.value end end |
#empty? ⇒ Boolean
Check if cache is empty
139 140 141 |
# File 'lib/rospatent/cache.rb', line 139 def empty? synchronize { @store.empty? } end |
#fetch(key, default_value = nil, ttl: nil) { ... } ⇒ Object
Fetch value with fallback block or default value
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/rospatent/cache.rb', line 180 def fetch(key, default_value = nil, ttl: nil) value = get(key) return value unless value.nil? result = if default_value default_value elsif block_given? yield else return nil end set(key, result, ttl: ttl) unless result.nil? result end |
#get(key) ⇒ Object?
Get a value from the cache
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/rospatent/cache.rb', line 43 def get(key) synchronize do entry = @store[key] unless entry @stats[:misses] += 1 return nil end if entry.expired? delete_entry(key) @stats[:expired] += 1 @stats[:misses] += 1 return nil end # Update access order for LRU @access_order.delete(key) @access_order.push(key) entry.touch! @stats[:hits] += 1 entry.value end end |
#key?(key) ⇒ Boolean
Check if a key exists and is not expired
96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/rospatent/cache.rb', line 96 def key?(key) synchronize do entry = @store[key] return false unless entry if entry.expired? delete_entry(key) @stats[:expired] += 1 return false end true end end |
#set(key, value, ttl: nil) ⇒ Object
Set a value in the cache
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/rospatent/cache.rb', line 73 def set(key, value, ttl: nil) synchronize do effective_ttl = ttl || @ttl expires_at = Time.now + effective_ttl entry = CacheEntry.new(value, expires_at, Time.now, 0) # Remove existing entry if present @access_order.delete(key) if @store.key?(key) @store[key] = entry @access_order.push(key) # Evict entries if over size limit evict_if_needed value end end |
#size ⇒ Integer
Get current cache size
133 134 135 |
# File 'lib/rospatent/cache.rb', line 133 def size synchronize { @store.size } end |
#statistics ⇒ Hash
Get cache statistics
145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/rospatent/cache.rb', line 145 def statistics synchronize do total_requests = @stats[:hits] + @stats[:misses] hit_rate = total_requests.positive? ? (@stats[:hits].to_f / total_requests * 100).round(2) : 0 @stats.merge( size: @store.size, total_requests: total_requests, hit_rate_percent: hit_rate ) end end |