Class: LruReduxStore::Store

Inherits:
ActiveSupport::Cache::Store
  • Object
show all
Defined in:
lib/lru_redux_store/store.rb

Overview

A thread-safe cache store implementation which stores everything in memory in the same process, backed by LruRedux::TTL::ThreadSafeCache. Unlike ActiveSupport::Cache::MemoryStore it is bounded by entry count rather than estimated byte size, and eviction and expiry happen incrementally on each access instead of in periodic full-cache pruning passes.

Constant Summary collapse

PER_ENTRY_OVERHEAD =

Fixed per-entry bookkeeping cost in bytes, counted toward the reported cache size on top of each key and payload. Matches MemoryStore.

240

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = nil) ⇒ Store

Creates a new store. Accepts the standard ActiveSupport::Cache::Store options plus:

  • max_size - the maximum number of entries (default 1000). The least recently used entry is evicted when a write would exceed it.
  • expires_in - optional TTL enforced by the backing cache. Without it entries never expire and only leave through LRU eviction.


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/lru_redux_store/store.rb', line 23

def initialize(options = nil)
  options ||= {}
  # dup/marshal values so the cache never shares object references with
  # callers, matching MemoryStore. pass coder: nil to store raw values
  options[:coder] = DupCoder unless options.key?(:coder) || options.key?(:serializer)
  # Disable compression by default.
  options[:compress] ||= false
  # store-level expiry is enforced solely by the backing TTL cache; keep
  # expires_in out of @options so the base class never embeds it in entries
  @expires_in = options.delete(:expires_in)
  super
  @max_size = options[:max_size] || 1000
  @data = build_data_cache

  @cache_size = 0
end

Class Method Details

.supports_cache_versioning?Boolean

Advertise cache versioning support.

Returns:

  • (Boolean)


41
42
43
# File 'lib/lru_redux_store/store.rb', line 41

def self.supports_cache_versioning?
  true
end

Instance Method Details

#cleanup(_options = nil) ⇒ Object

Preemptively iterates through all stored keys and removes the ones which have expired.



65
66
67
68
69
# File 'lib/lru_redux_store/store.rb', line 65

def cleanup(_options = nil)
  _instrument(:cleanup, size: @data.count) do
    synchronize { @data.expire }
  end
end

#clear(_options = nil) ⇒ Object

Delete all data stored in a given cache store.



46
47
48
49
# File 'lib/lru_redux_store/store.rb', line 46

def clear(_options = nil)
  @data.clear
  @cache_size = 0
end

#decrement(name, amount = 1, **options) ⇒ Object

Decrement a cached integer value. Returns the updated value.

If the key is unset or has expired, it will be set to -amount.

cache.decrement("foo") # => -1

To set a specific value, call #write:

cache.write("baz", 5)
cache.decrement("baz") # => 4


100
101
102
103
104
# File 'lib/lru_redux_store/store.rb', line 100

def decrement(name, amount = 1, **options)
  instrument(:decrement, name, amount: amount) do
    modify_value(name, -amount, **options)
  end
end

#delete_matched(matcher, options = nil) ⇒ Object

Deletes cache entries if the cache key matches a given pattern.



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/lru_redux_store/store.rb', line 52

def delete_matched(matcher, options = nil)
  options = merged_options options
  matcher = key_matcher matcher, options

  instrument :delete_matched, matcher.inspect do
    keys = @data.to_a.map(&:first)
    keys.each do |key|
      delete_entry(key, **options) if key.match matcher
    end
  end
end

#increment(name, amount = 1, **options) ⇒ Object

Increment a cached integer value. Returns the updated value.

If the key is unset, it will be set to amount:

cache.increment("foo") # => 1
cache.increment("bar", 100) # => 100

To set a specific value, call #write:

cache.write("baz", 5)
cache.increment("baz") # => 6


83
84
85
86
87
# File 'lib/lru_redux_store/store.rb', line 83

def increment(name, amount = 1, **options)
  instrument(:increment, name, amount: amount) do
    modify_value(name, amount, **options)
  end
end

#inspectObject

:nodoc:



112
113
114
# File 'lib/lru_redux_store/store.rb', line 112

def inspect # :nodoc:
  "#<#{self.class.name} entries=#{@data.count}, size=#{@cache_size}, options=#{@options.inspect}>"
end

#synchronizeObject

Synchronize calls to the cache. This should be called wherever the underlying cache implementation is not thread safe.



108
109
110
# File 'lib/lru_redux_store/store.rb', line 108

def synchronize(&) # :nodoc:
  @data.synchronize(&)
end