Class: LruCache

Inherits:
Object
  • Object
show all
Defined in:
lib/kotoshu/embeddings/lru_cache.rb

Overview

LruCache - Least Recently Used Cache

Provides efficient O(1) LRU caching with optional TTL support. Used for caching embeddings during similarity search.

Examples:

Basic usage

cache = LruCache.new(max_size: 1000)
cache[:key] = value
cache[:key]  # => value

With TTL

cache = LruCache.new(max_size: 1000, ttl: 300)  # 5 minutes

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_size: 1000, ttl: nil) ⇒ LruCache

Create a new LRU cache

Parameters:

  • max_size (Integer) (defaults to: 1000)

    Maximum number of entries (default: 1000)

  • ttl (Integer, nil) (defaults to: nil)

    Time-to-live in seconds (default: nil = no expiry)



34
35
36
37
38
39
40
41
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 34

def initialize(max_size: 1000, ttl: nil)
  @max_size = max_size
  @ttl = ttl
  @cache = {}  # key -> {value: v, accessed_at: t, created_at: t}
  @order = []  # Ordered list of keys (most recently used first)
  @hits = 0
  @misses = 0
end

Instance Attribute Details

#hitsInteger (readonly)

Returns Number of cache hits.

Returns:

  • (Integer)

    Number of cache hits



24
25
26
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 24

def hits
  @hits
end

#max_sizeInteger (readonly)

Returns Maximum number of entries.

Returns:

  • (Integer)

    Maximum number of entries



18
19
20
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 18

def max_size
  @max_size
end

#missesInteger (readonly)

Returns Number of cache misses.

Returns:

  • (Integer)

    Number of cache misses



27
28
29
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 27

def misses
  @misses
end

#ttlInteger? (readonly)

Returns TTL in seconds.

Returns:

  • (Integer, nil)

    TTL in seconds



21
22
23
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 21

def ttl
  @ttl
end

Instance Method Details

#[](key) ⇒ Object?

Get value for key

Parameters:

  • key (Object)

    Cache key

Returns:

  • (Object, nil)

    Cached value or nil if not found/expired



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 48

def [](key)
  entry = @cache[key]
  return nil unless entry

  # Check TTL
  if @ttl && (Time.now - entry[:created_at]) > @ttl
    delete(key)
    @misses += 1
    return nil
  end

  # Update access order (move to front = most recently used)
  @order.delete(key)
  @order.unshift(key)
  entry[:accessed_at] = Time.now

  @hits += 1
  entry[:value]
end

#[]=(key, value) ⇒ Object

Set value for key

Parameters:

  • key (Object)

    Cache key

  • value (Object)

    Value to cache

Returns:

  • (Object)

    The value



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 74

def []=(key, value)
  # Evict LRU if at capacity
  if @cache.key?(key)
    # Update existing entry
    @cache[key][:value] = value
    @cache[key][:accessed_at] = Time.now
    # Move to front
    @order.delete(key)
    @order.unshift(key)
    return value
  end

  if @cache.size >= @max_size
    evict_lru
  end

  @cache[key] = {
    value: value,
    accessed_at: Time.now,
    created_at: Time.now
  }
  @order.unshift(key)

  value
end

#clearself

Clear all entries

Returns:

  • (self)


132
133
134
135
136
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 132

def clear
  @cache.clear
  @order.clear
  self
end

#delete(key) ⇒ Object?

Delete key from cache

Parameters:

  • key (Object)

    Cache key

Returns:

  • (Object, nil)

    Deleted value or nil



122
123
124
125
126
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 122

def delete(key)
  entry = @cache.delete(key)
  @order.delete(key)
  entry&.[](:value)
end

#empty?Boolean

Check if empty

Returns:

  • (Boolean)


150
151
152
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 150

def empty?
  @cache.empty?
end

#fetch(key, &block) ⇒ Object

Fetch with block (cache-aside pattern)

Parameters:

  • key (Object)

    Cache key

Returns:

  • (Object)

    Cached value or block result



213
214
215
216
217
218
219
220
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 213

def fetch(key, &block)
  result = self[key]
  return result if result || key?(key)

  value = block.call
  self[key] = value
  value
end

#key?(key) ⇒ Boolean

Check if key exists

Parameters:

  • key (Object)

    Cache key

Returns:

  • (Boolean)

    True if key exists and not expired



105
106
107
108
109
110
111
112
113
114
115
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 105

def key?(key)
  entry = @cache[key]
  return false unless entry

  if @ttl && (Time.now - entry[:created_at]) > @ttl
    delete(key)
    return false
  end

  true
end

#keysArray<Object>

Get all keys

Returns:

  • (Array<Object>)

    Array of keys



180
181
182
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 180

def keys
  @order.dup
end

#lruArray<Object, Object>?

Get least recently used key-value pair

Returns:

  • (Array<Object, Object>, nil)


158
159
160
161
162
163
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 158

def lru
  return nil if @order.empty?

  key = @order.last
  [key, @cache[key][:value]]
end

#mruArray<Object, Object>?

Get most recently used key-value pair

Returns:

  • (Array<Object, Object>, nil)


169
170
171
172
173
174
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 169

def mru
  return nil if @order.empty?

  key = @order.first
  [key, @cache[key][:value]]
end

#sizeInteger

Get current size

Returns:

  • (Integer)

    Number of entries



142
143
144
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 142

def size
  @cache.size
end

#statsHash

Get cache statistics

Returns:

  • (Hash)

    Statistics



196
197
198
199
200
201
202
203
204
205
206
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 196

def stats
  total = @hits + @misses
  {
    size: size,
    max_size: @max_size,
    hits: @hits,
    misses: @misses,
    hit_rate: total.zero? ? 0.0 : @hits.to_f / total,
    ttl: @ttl
  }
end

#valuesArray<Object>

Get all values

Returns:

  • (Array<Object>)

    Array of values



188
189
190
# File 'lib/kotoshu/embeddings/lru_cache.rb', line 188

def values
  @order.map { |key| @cache[key][:value] }
end