Class: Kotoshu::Cache::LookupCache

Inherits:
Object
  • Object
show all
Includes:
Cache
Defined in:
lib/kotoshu/cache/lookup_cache.rb

Overview

LRU (Least Recently Used) cache for fast lookups.

This cache automatically evicts the least recently used entries when the maximum size is reached.

Examples:

Basic usage

cache = LookupCache.new(max_size: 1000)
cache.write("key", "value")
cache.read("key")  # => "value"

Using fetch for lazy computation

cache.fetch("expensive_key") { compute_expensive_value() }

Direct Known Subclasses

SuggestionCache

Constant Summary collapse

DEFAULT_MAX_SIZE =

Default maximum cache size

1000

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_size: DEFAULT_MAX_SIZE) ⇒ LookupCache

Create a new LRU cache.

Parameters:

  • max_size (Integer) (defaults to: DEFAULT_MAX_SIZE)

    Maximum number of entries (default: 1000)



31
32
33
34
35
36
# File 'lib/kotoshu/cache/lookup_cache.rb', line 31

def initialize(max_size: DEFAULT_MAX_SIZE)
  @max_size = max_size
  @data = {} # key => [value, access_order]
  @access_order = 0
  @stats = { hits: 0, misses: 0 }
end

Instance Attribute Details

#max_sizeInteger (readonly)

Returns Maximum number of entries.

Returns:

  • (Integer)

    Maximum number of entries



26
27
28
# File 'lib/kotoshu/cache/lookup_cache.rb', line 26

def max_size
  @max_size
end

Instance Method Details

#clearself

Clear all entries from cache.

Returns:

  • (self)

    Self for chaining



100
101
102
103
104
# File 'lib/kotoshu/cache/lookup_cache.rb', line 100

def clear
  @data.clear
  @access_order = 0
  self
end

#delete(key) ⇒ Object?

Delete a value from cache.

Parameters:

  • key (Object)

    The cache key

Returns:

  • (Object, nil)

    The deleted value or nil



92
93
94
95
# File 'lib/kotoshu/cache/lookup_cache.rb', line 92

def delete(key)
  entry = @data.delete(key)
  entry&.first # Return value or nil
end

#fetch(key, default = nil) { ... } ⇒ Object

Retrieve a value from cache, or compute it.

Parameters:

  • key (Object)

    The cache key

  • default (Object) (defaults to: nil)

    Optional default value (if no block given)

Yields:

  • Block to compute value on cache miss

Returns:

  • (Object)

    The cached or computed value



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/kotoshu/cache/lookup_cache.rb', line 44

def fetch(key, default = nil)
  if key?(key)
    record_hit
    @data[key][0] # Return value
  else
    record_miss
    value = block_given? ? yield : default
    write(key, value)
    value
  end
end

#key?(key) ⇒ Boolean

Check if key exists in cache.

Parameters:

  • key (Object)

    The cache key

Returns:

  • (Boolean)

    True if key exists



110
111
112
# File 'lib/kotoshu/cache/lookup_cache.rb', line 110

def key?(key)
  @data.key?(key)
end

#read(key) ⇒ Object?

Read a value from cache.

Parameters:

  • key (Object)

    The cache key

Returns:

  • (Object, nil)

    The cached value or nil



74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/kotoshu/cache/lookup_cache.rb', line 74

def read(key)
  entry = @data[key]

  if entry
    record_hit
    @access_order += 1
    entry[1] = @access_order # Update access order
    entry[0] # Return value
  else
    record_miss
    nil
  end
end

#reset_statsself

Reset statistics counters.

Returns:

  • (self)

    Self for chaining



139
140
141
142
# File 'lib/kotoshu/cache/lookup_cache.rb', line 139

def reset_stats
  @stats = { hits: 0, misses: 0 }
  self
end

#sizeInteger

Get number of entries in cache.

Returns:

  • (Integer)

    Number of entries



117
118
119
# File 'lib/kotoshu/cache/lookup_cache.rb', line 117

def size
  @data.size
end

#statsHash

Get cache statistics.

Returns:

  • (Hash)

    Statistics including :hits, :misses, :size, :hit_rate



124
125
126
127
128
129
130
131
132
133
134
# File 'lib/kotoshu/cache/lookup_cache.rb', line 124

def stats
  total = @stats[:hits] + @stats[:misses]
  hit_rate = total.positive? ? @stats[:hits].to_f / total : 0.0

  {
    hits: @stats[:hits],
    misses: @stats[:misses],
    size: size,
    hit_rate: hit_rate.round(4)
  }
end

#write(key, value) ⇒ Object

Write a value to cache.

Parameters:

  • key (Object)

    The cache key

  • value (Object)

    The value to store

Returns:

  • (Object)

    The stored value



61
62
63
64
65
66
67
68
# File 'lib/kotoshu/cache/lookup_cache.rb', line 61

def write(key, value)
  evict_if_needed

  @access_order += 1
  @data[key] = [value, @access_order]

  value
end