Class: Arrow::Cache

Inherits:
Cache
  • Object
show all
Extended by:
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

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

Constant Summary collapse

DefaultConfig =

Default configuration values

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

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

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

.extentObject (readonly)

Returns the value of attribute extent.



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

def extent
  @extent
end

Instance Attribute Details

#hitsObject (readonly)

Total count of cache hits



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

def hits
  @hits
end

#listObject (readonly)

The list of cached objects



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

def list
  @list
end

#missesObject (readonly)

Total count of cache misses



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

def misses
  @misses
end

#nameObject (readonly)

The name of the cache; used in introspection



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

def name
  @name
end

#sizeObject (readonly)

Cache size in bytes



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

def size
  @size
end

Instance Method Details

#[]=(key, obj) ⇒ Object

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

#expireObject

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

#invalidate(key) ⇒ Object

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

#invalidate_allObject

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