Class: Arrow::Cache

Inherits:
Cache
  • Object
show all
Extends:
Forwardable
Includes:
Loggable
Defined in:
lib/arrow/cache.rb

Overview

A derivative of the Cache class from the ruby-cache module. It adds a few convenience and introspection methods to its parent.

Instances of this class are LRU caches for disk-based objects which keep track of the cached object’s modification time, expiring the cached version when the disk-based version changes (e.g., for template caching).

Authors

  • Michael Granger

Please see the file LICENSE in the top-level directory for licensing details.

Constant Summary

DefaultConfig =

Default configuration values

{
  :maxNum     => 10,
  :maxObjSize   => nil,
  :maxSize    => nil,
  :expiration   => 3600,
}

Class Attribute Summary

Instance Attribute Summary

Instance Method Summary

Methods included from Loggable

#log

Constructor Details

- (Cache) initialize(name, config = {}, &cleanup)

Create a new cache. This merges the DefaultConfig with the specified values and transforms camelCased keys into under_barred ones.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/arrow/cache.rb', line 53

def initialize( name, config={}, &cleanup )
  @name = name

  # Merge defaults and specified values
  merged = DefaultConfig.merge( config )

  # Transform the config hash into the form the superclass expects
  merged.each_key do |key|
    lckey = key.to_s.gsub( /(.)([A-Z])/ ) {|match|
      match[0,1] + "_" + match[1,1].downcase
    }.to_sym

    next if key == lckey
    merged[ lckey ] = merged.delete( key )
  end

  # Register this instance with the class for introspection (costs
  # much less than ObjectSpace.each_object).
  obj = super( merged, &cleanup )
  self.class.extent << obj

  return obj
end

Class Attribute Details

+ (Object) extent (readonly)

Returns the value of attribute extent



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

def extent
  @extent
end

Instance Attribute Details

- (Object) hits (readonly)

Total count of cache hits



90
91
92
# File 'lib/arrow/cache.rb', line 90

def hits
  @hits
end

- (Object) list (readonly)

The list of cached objects



99
100
101
# File 'lib/arrow/cache.rb', line 99

def list
  @list
end

- (Object) misses (readonly)

Total count of cache misses



93
94
95
# File 'lib/arrow/cache.rb', line 93

def misses
  @misses
end

- (Object) name (readonly)

The name of the cache; used in introspection



87
88
89
# File 'lib/arrow/cache.rb', line 87

def name
  @name
end

- (Object) size (readonly)

Cache size in bytes



96
97
98
# File 'lib/arrow/cache.rb', line 96

def size
  @size
end

Instance Method Details

- (Object) []=(key, obj)

Overridden from the superclass to prevent .to_s from being called on objects to determine their size if the object supports a #memsize method. This is mostly to stop templates from being rendered every time they’re cached.



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/arrow/cache.rb', line 127

def []=( key, obj )
  self.expire
  
  self.invalidate( key ) if self.cached?( key )

  if obj.respond_to?( :memsize )
    size = obj.memsize
  else
    size = obj.to_s.size
  end

  # Test against size threshold
  if @max_obj_size && size > @max_obj_size
    Arrow::Logger[self.class].debug \
      "%p not cached: size exceeds maxObjSize: %d" %
      [ obj, @max_obj_size ]
    return obj
  end
  if @max_obj_size.nil? && @max_size && size > @max_size
    Arrow::Logger[self.class].debug \
      "%p not cached: size exceeds maxSize: %d" %
      [ obj, @max_size ]
    return obj
  end
  
  if @max_num && @list.size >= @max_num
    Arrow::Logger[self.class].debug \
      "Dropping %p from the cache: count exceeds maxNum: %d" %
      [ @list.first, @max_num ]
    self.invalidate( @list.first )
  end

  @size += size
  if @max_size
    while @size > @max_size
      Arrow::Logger[self.class].debug \
        "Dropping %p from the cache: size exceeds maxSize: %d" %
        [ @list.first, @max_size ]
      self.invalidate( @list.first )
    end
  end

  @objs[ key ] = Cache::CACHE_OBJECT.new( obj, size, Time.now.to_i )
  @list.push( key )

  return obj
end

- (Object) expire

Overridden to provide logging of expire phase.



117
118
119
120
# File 'lib/arrow/cache.rb', line 117

def expire
  self.log.debug "looking for expired entries in %s" % [self.name]
  super
end

- (Object) invalidate(key)

Overridden to provide logging of invalidated keys.



103
104
105
106
# File 'lib/arrow/cache.rb', line 103

def invalidate( key )
  self.log.debug "invalidating cache key '%p' for %s" % [key, self.name]
  super
end

- (Object) invalidate_all

Overridden for logging.



110
111
112
113
# File 'lib/arrow/cache.rb', line 110

def invalidate_all
  self.log.debug "invalidating all cached objects for %s" % [self.name]
  super
end