Class: Fractor::ResultCache

Inherits:
Object
  • Object
show all
Defined in:
lib/fractor/result_cache.rb

Overview

Caches work results to avoid redundant processing of identical work items. Useful for expensive, deterministic operations.

Examples:

Basic usage

cache = Fractor::ResultCache.new
cached = cache.get(work) { work.process }

With TTL

cache = Fractor::ResultCache.new(ttl: 300)  # 5 minutes

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ttl: nil, max_size: nil, max_memory: nil) ⇒ ResultCache

Initialize a new result cache.

Parameters:

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

    Time-to-live for cache entries in seconds (nil = no expiration)

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

    Maximum number of entries (nil = unlimited)

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

    Maximum memory usage in bytes (nil = unlimited)



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/fractor/result_cache.rb', line 24

def initialize(ttl: nil, max_size: nil, max_memory: nil)
  @cache = {}
  @timestamps = {}
  @access_times = {}
  @ttl = ttl
  @max_size = max_size
  @max_memory = max_memory
  @current_memory = 0
  @mutex = Mutex.new
  @hits = 0
  @misses = 0
end

Instance Attribute Details

#hitsObject (readonly)

Returns the value of attribute hits.



17
18
19
# File 'lib/fractor/result_cache.rb', line 17

def hits
  @hits
end

#missesObject (readonly)

Returns the value of attribute misses.



17
18
19
# File 'lib/fractor/result_cache.rb', line 17

def misses
  @misses
end

Instance Method Details

#cleanup_expiredInteger

Remove expired entries from the cache.

Returns:

  • (Integer)

    Number of entries removed



147
148
149
150
151
152
153
# File 'lib/fractor/result_cache.rb', line 147

def cleanup_expired
  @mutex.synchronize do
    expired_keys = @cache.keys.select { |key| expired?(key) }
    expired_keys.each { |key| remove_entry(key) }
    expired_keys.size
  end
end

#clearvoid

This method returns an undefined value.

Clear all cached results.



117
118
119
120
121
122
123
124
# File 'lib/fractor/result_cache.rb', line 117

def clear
  @mutex.synchronize do
    @cache.clear
    @timestamps.clear
    @access_times.clear
    @current_memory = 0
  end
end

#get(work) { ... } ⇒ WorkResult, Object

Get a cached result or compute and cache it.

Parameters:

Yields:

  • Block to compute the result if not cached

Returns:

  • (WorkResult, Object)

    The cached or computed result



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/fractor/result_cache.rb', line 49

def get(work)
  key = generate_key(work)

  @mutex.synchronize do
    # Check if we have a valid cached result
    if @cache.key?(key) && !expired?(key)
      @hits += 1
      @access_times[key] = Time.now
      return @cache[key]
    end

    @misses += 1

    # Compute the result
    result = yield

    # Cache the result
    cache_entry(key, result)

    result
  end
end

#has?(work) ⇒ Boolean

Check if a work item has a cached result.

Parameters:

Returns:

  • (Boolean)

    true if a valid cached result exists



76
77
78
79
80
81
82
# File 'lib/fractor/result_cache.rb', line 76

def has?(work)
  key = generate_key(work)

  @mutex.synchronize do
    @cache.key?(key) && !expired?(key)
  end
end

#invalidate(work) ⇒ Boolean

Invalidate a cached result.

Parameters:

Returns:

  • (Boolean)

    true if a cached result was removed



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/fractor/result_cache.rb', line 101

def invalidate(work)
  key = generate_key(work)

  @mutex.synchronize do
    if @cache.key?(key)
      remove_entry(key)
      true
    else
      false
    end
  end
end

#set(work, result) ⇒ void

This method returns an undefined value.

Store a result in the cache.

Parameters:



89
90
91
92
93
94
95
# File 'lib/fractor/result_cache.rb', line 89

def set(work, result)
  key = generate_key(work)

  @mutex.synchronize do
    cache_entry(key, result)
  end
end

#sizeInteger

Get the current cache size.

Returns:

  • (Integer)

    Number of entries in the cache



40
41
42
# File 'lib/fractor/result_cache.rb', line 40

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

#statsHash

Get cache statistics.

Returns:

  • (Hash)

    Cache statistics



129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/fractor/result_cache.rb', line 129

def stats
  @mutex.synchronize do
    total = @hits + @misses
    hit_rate = total.positive? ? (@hits.to_f / total * 100).round(2) : 0

    {
      size: @cache.size,
      hits: @hits,
      misses: @misses,
      hit_rate: hit_rate,
      current_memory: @current_memory,
    }
  end
end