Class: Philiprehberger::Memo::Cache

Inherits:
Object
  • Object
show all
Defined in:
lib/philiprehberger/memo/cache.rb

Overview

Per-method LRU cache with optional TTL

Instance Method Summary collapse

Constructor Details

#initialize(ttl: nil, max_size: nil) ⇒ Cache

Returns a new instance of Cache.

Parameters:

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

    time-to-live in seconds

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

    maximum entries



9
10
11
12
13
14
15
16
# File 'lib/philiprehberger/memo/cache.rb', line 9

def initialize(ttl: nil, max_size: nil)
  @ttl = ttl
  @max_size = max_size
  @store = {}
  @mutex = Mutex.new
  @hits = 0
  @misses = 0
end

Instance Method Details

#clearObject

Clear all entries and reset stats



96
97
98
99
100
101
102
# File 'lib/philiprehberger/memo/cache.rb', line 96

def clear
  @mutex.synchronize do
    @store.clear
    @hits = 0
    @misses = 0
  end
end

#delete(key) ⇒ Boolean

Remove a specific entry from the cache

Parameters:

  • key (Object)

    cache key

Returns:

  • (Boolean)

    true if an entry was removed



56
57
58
# File 'lib/philiprehberger/memo/cache.rb', line 56

def delete(key)
  @mutex.synchronize { !@store.delete(key).nil? }
end

#get(key) ⇒ Array(Boolean, Object)

Fetch a cached value

Parameters:

  • key (Object)

    cache key

Returns:

  • (Array(Boolean, Object))
    found, value


22
23
24
# File 'lib/philiprehberger/memo/cache.rb', line 22

def get(key)
  @mutex.synchronize { fetch_entry(key) }
end

#key?(key) ⇒ Boolean

Check whether a non-expired entry exists for a key

Parameters:

  • key (Object)

    cache key

Returns:

  • (Boolean)


38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/philiprehberger/memo/cache.rb', line 38

def key?(key)
  @mutex.synchronize do
    return false unless @store.key?(key)

    entry = @store[key]
    if expired?(entry)
      @store.delete(key)
      false
    else
      true
    end
  end
end

#keysArray<Object>

All non-expired cache keys in insertion/LRU order

Returns:

  • (Array<Object>)


70
71
72
73
74
75
# File 'lib/philiprehberger/memo/cache.rb', line 70

def keys
  @mutex.synchronize do
    prune_expired_entries
    @store.keys
  end
end

#prune_expiredInteger

Remove all expired entries without clearing stats

Returns:

  • (Integer)

    number of entries removed



80
81
82
# File 'lib/philiprehberger/memo/cache.rb', line 80

def prune_expired
  @mutex.synchronize { prune_expired_entries }
end

#set(key, value) ⇒ Object

Store a value in the cache

Parameters:

  • key (Object)

    cache key

  • value (Object)

    value to store



30
31
32
# File 'lib/philiprehberger/memo/cache.rb', line 30

def set(key, value)
  @mutex.synchronize { store_entry(key, value) }
end

#sizeInteger

Current number of cached entries

Returns:

  • (Integer)


63
64
65
# File 'lib/philiprehberger/memo/cache.rb', line 63

def size
  @mutex.synchronize { @store.size }
end

#statsHash{Symbol => Numeric}

Cache hit/miss statistics

Returns:

  • (Hash{Symbol => Numeric})

    :hits, :misses, :hit_rate



87
88
89
90
91
92
93
# File 'lib/philiprehberger/memo/cache.rb', line 87

def stats
  @mutex.synchronize do
    total = @hits + @misses
    rate = total.zero? ? 0.0 : @hits.to_f / total
    { hits: @hits, misses: @misses, hit_rate: rate.round(4) }
  end
end