Class: Weak::Cache

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

Overview

Weak::Cache provides a thread-safe wrapper around Map to provide an object cache. As with a Map, keys and values are both weakly referenced so that a stored key-value pair vanishes if either the key or the value is garbage-collected.

We implement an interface similar to that of ActiveSupport::Cache::Store.

Instance Method Summary collapse

Constructor Details

#initializeCache

Returns a new empty Weak::Cache object



20
21
22
23
# File 'lib/weak/cache.rb', line 20

def initialize
  @map = Map.new
  @mutex = Mutex.new
end

Instance Method Details

#clearself

Clears the entire cache.

Returns:

  • (self)


28
29
30
31
# File 'lib/weak/cache.rb', line 28

def clear
  @mutex.synchronize { @map.clear }
  self
end

#clone(freeze: false) ⇒ Weak::Cache

Weak::Cache objects can't be frozen since this is not enforced by the underlying Map, resp. its ObjectSpace::WeakMap implementation. Thus, we try to signal this by not actually setting the frozen? flag and ignoring attempts to freeze us with just a warning.

Parameters:

  • freeze (Bool, nil) (defaults to: false)

    ignored; we always behave as if this is false. If this is set to a truethy value, we emit a warning.

Returns:

  • (Weak::Cache)

    a new Weak::Cache object containing the same elements as self



42
43
44
45
# File 'lib/weak/cache.rb', line 42

def clone(freeze: false)
  warn("Can't freeze #{self.class}") if freeze
  @mutex.synchronize { super(freeze: false) }
end

#delete(key) ⇒ Bool

Note:

Map does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different String keys are not considered equal, even if they may contain the same content.

Deletes an entry in the cache. Returns true if an entry was deleted, false otherwise.

Parameters:

  • key (Object)

    the key to delete

Returns:

  • (Bool)

    true if the entry was deleted, false otherwise



53
54
55
56
57
58
59
60
# File 'lib/weak/cache.rb', line 53

def delete(key)
  @mutex.synchronize {
    @map.delete(key) do
      return false
    end
    true
  }
end

#dupWeak::Cache

Returns a new Weak::Cache object containing the same elements as self.

Returns:

  • (Weak::Cache)

    a new Weak::Cache object containing the same elements as self



64
65
66
# File 'lib/weak/cache.rb', line 64

def dup
  @mutex.synchronize { super }
end

#each_key(&block) ⇒ undocumented



68
69
70
71
72
# File 'lib/weak/cache.rb', line 68

def each_key(&block)
  return enum_for(__method__) { size } unless block_given?
  keys.each(&block)
  self
end

#empty?Boolean

Returns true if self contains no elements.

Returns:

  • (Boolean)

    true if self contains no elements



75
76
77
# File 'lib/weak/cache.rb', line 75

def empty?
  @mutex.synchronize { @map.empty? }
end

#exist?(key) ⇒ Bool Also known as: include?, key?

Note:

Map does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different String keys are not considered equal, even if they may contain the same content.

Returns true if the given key is included in self and has an associated live value, false otherwise.

Parameters:

  • key (Object)

    a possible key

Returns:

  • (Bool)

    true if the given key is included in self and has an associated live value, false otherwise



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

def exist?(key)
  @mutex.synchronize { @map.include?(key) }
end

#fetch(key, skip_nil: false) {|key| ... } ⇒ Object

Note:

Map does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different String keys are not considered equal, even if they may contain the same content.

Fetches data from the cache, using the given key. If there is a value in the cache for the given key, that value is returned.

If there is no value in the cache (a cache miss), then the given block will be passed the key and executed in the event of a cache miss. The return value of the block will be written to the cache under the given cache key, and that return value will be returned.

Parameters:

  • key (Object)

    the key for the requested value

  • skip_nil (Bool) (defaults to: false)

    prevents caching a nil value from the block

Yields:

  • (key)

    if no value was set at key, we call the block, write its returned value for the key in the cache and return the value

Yield Parameters:

  • key (String)

    the given key

Returns:

  • (Object)

    the value for the given key if present in the cache. If the key was not found, we return the value of the given block.

Raises:

  • (ArgumentError)

    if no block was provided



103
104
105
106
107
108
109
110
111
112
# File 'lib/weak/cache.rb', line 103

def fetch(key, skip_nil: false)
  raise ArgumentError, "must provide a block" unless block_given?

  @mutex.synchronize {
    @map.fetch(key) {
      value = yield(key)
      @map[key] = value unless skip_nil && value.nil?
    }
  }
end

#freezeself

Weak::Cache objects can't be frozen since this is not enforced by the underlying Map, resp. its ObjectSpace::WeakMap implementation. Thus, we try to signal this by not actually setting the frozen? flag and ignoring attempts to freeze us with just a warning.

Returns:

  • (self)


120
121
122
123
# File 'lib/weak/cache.rb', line 120

def freeze
  warn("Can't freeze #{self.class}")
  self
end

#inspectundocumented



125
126
127
# File 'lib/weak/cache.rb', line 125

def inspect
  @mutex.synchronize { "#<#{self.class} #{@map._inspect}>" }
end

#keysArray

Note:

In contrast to a Hash, Weak::Maps do not necessarily retain insertion order.

Returns an Array containing all keys of the map for which we have a valid value. Keys with garbage-collected values are excluded.

Returns:

  • (Array)

    an Array containing all keys of the map for which we have a valid value. Keys with garbage-collected values are excluded.

See Also:



130
131
132
# File 'lib/weak/cache.rb', line 130

def keys
  @mutex.synchronize { @map.keys }
end

#read(key) ⇒ Object Also known as: []

Note:

Map does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different String keys are not considered equal, even if they may contain the same content.

Returns the value associated with the given key, or nil if no value was found for the key.

Parameters:

  • key (Object)

    the key for the requested value

Returns:

  • (Object)

    the value associated with the given key, or nil if no value was found for the key



153
154
155
# File 'lib/weak/cache.rb', line 153

def read(key)
  @mutex.synchronize { @map[key] }
end

#sizeundocumented Also known as: length



158
159
160
# File 'lib/weak/cache.rb', line 158

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

#to_h {|key, value| ... } ⇒ Hash

Returns a new Hash which considers object identity for keys which contains the key-value pairs in self.

Yields:

  • (key, value)

    When a block is given, returns a new Hash object whose content is based on the block; the block should return a 2-element Array object specifying the key-value pair to be included in the returned Hash.

Yield Parameters:

  • key (Object)

    the key of the current key-value pair

  • value (Object)

    the value of the current key-value pair

Returns:

  • (Hash)

    a new Hash which considers object identity for keys which contains the key-value pairs in self.



164
165
166
# File 'lib/weak/cache.rb', line 164

def to_h(&block)
  @mutex.synchronize { @map.to_h(&block) }
end

#write(key, value) ⇒ Object Also known as: []=

Note:

Map does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different String keys are not considered equal, even if they may contain the same content.

Associates the given value with the given key; returns value. If the given key exists, replaces its value with the given value.

Parameters:

  • key (Object)

    the key for the set key-value pair

  • value (Object)

    the value of the set key-value pair

Returns:

  • (Object)

    the given value



169
170
171
# File 'lib/weak/cache.rb', line 169

def write(key, value)
  @mutex.synchronize { @map[key] = value }
end