Class: Tina4::CacheBackends::MemoryBackend

Inherits:
BaseBackend
  • Object
show all
Defined in:
lib/tina4/cache_backends/memory_backend.rb

Overview

Thread-safe in-memory LRU cache with TTL (parity with Python _MemoryBackend). Default backend — zero dependencies.

Instance Method Summary collapse

Methods inherited from BaseBackend

#available?

Constructor Details

#initialize(max_entries: 1000) ⇒ MemoryBackend

Returns a new instance of MemoryBackend.



10
11
12
13
14
15
16
# File 'lib/tina4/cache_backends/memory_backend.rb', line 10

def initialize(max_entries: 1000)
  @max_entries = max_entries
  @store = {} # key => [value, expires_at] ; Ruby Hash preserves insertion order
  @mutex = Mutex.new
  @hits = 0
  @misses = 0
end

Instance Method Details

#clearObject



54
55
56
57
58
59
60
# File 'lib/tina4/cache_backends/memory_backend.rb', line 54

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

#delete(key) ⇒ Object



50
51
52
# File 'lib/tina4/cache_backends/memory_backend.rb', line 50

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

#get(key) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/tina4/cache_backends/memory_backend.rb', line 18

def get(key)
  @mutex.synchronize do
    entry = @store[key]
    if entry.nil?
      @misses += 1
      return nil
    end
    value, expires_at = entry
    if expires_at && monotonic > expires_at
      @store.delete(key)
      @misses += 1
      return nil
    end
    @hits += 1
    # Move to end (most recently used)
    @store.delete(key)
    @store[key] = entry
    value
  end
end

#nameObject



70
71
72
# File 'lib/tina4/cache_backends/memory_backend.rb', line 70

def name
  "memory"
end

#set(key, value, ttl) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/tina4/cache_backends/memory_backend.rb', line 39

def set(key, value, ttl)
  @mutex.synchronize do
    expires_at = ttl > 0 ? monotonic + ttl : nil
    @store.delete(key)
    @store[key] = [value, expires_at]
    while @store.size > @max_entries
      @store.delete(@store.keys.first)
    end
  end
end

#statsObject



62
63
64
65
66
67
68
# File 'lib/tina4/cache_backends/memory_backend.rb', line 62

def stats
  @mutex.synchronize do
    now = monotonic
    @store.reject! { |_k, (_v, exp)| exp && now > exp }
    { hits: @hits, misses: @misses, size: @store.size, backend: "memory" }
  end
end