Class: UniCache

Inherits:
Hash
  • Object
show all
Defined in:
lib/unicache.rb

Overview

UniCache is Universal purpose Cache with Least Recently Used replacement policy by default. Cache can be configured with another policy.

UniCache is intended to be Thread safe.

User can register callbacks that are run at various UniCache events. ":getdata" callback is used to retreive cache data if not in cache. Others do not effect the UniCache state.

Usage example:

require 'unicache'

# Create cache with size 2.
c = UniCache.new( 2 )

# Register callbacks for some events (two for hit).
c.registerCallback( :hit, Proc.new{ |k,v| puts  "Hit:   #{k}:#{v}" } )
c.registerCallback( :hit, Proc.new{ |k,v| puts  "Found: #{k}:#{v}" } )
c.registerCallback( :miss, Proc.new{ |k,v| puts "Miss:  #{k}:<NA>" } )

# Set some values.
c[0] = 'foo'   # set 0 as 'foo'
c.put( 'bar', 'foo' )

# Get (or try to get) some values.
a = c[ 'bar' ] # hit, a == 'foo'
b = c.get( 0 ) # hit, b == 'foo'
c.get( 'foo' ) # miss
c.get( 2 )     # miss

Produces:

Hit:   bar:foo
Found: bar:foo
Hit:   0:foo
Found: 0:foo
Miss:  foo:<NA>
Miss:  2:<NA>

Defined Under Namespace

Classes: CallbackError, Error, FetchError, LruEviction, RemoveError, SizeError

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (UniCache) initialize(size, evict = LruEviction.new)

Cache initialization.

Parameters:

  • size (Integer)

    Cache size.

  • evict (Object) (defaults to: LruEviction.new)

    Eviction policy.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/unicache.rb', line 68

def initialize( size, evict = LruEviction.new )
    super()

    @lock = Mutex.new

    resize( size )

    setEviction( evict )

    # See: registerCallback.
    @callbacks = {}

    @callbackType = [ :getdata,
                      :add, :replace, :put, :overwrite,
                      :remove, :valueremove, :hit, :miss,
                      :peek ]
    
    @callbackType.each do |type|
        @callbacks[ type ] = []
    end

end

Instance Attribute Details

- (Object) lock (readonly)

Access lock.



62
63
64
# File 'lib/unicache.rb', line 62

def lock
  @lock
end

- (Object) size (readonly)

Cache size.



59
60
61
# File 'lib/unicache.rb', line 59

def size
  @size
end

Instance Method Details

- (Object) [](key)

Get operator.



162
163
164
# File 'lib/unicache.rb', line 162

def []( key )
    get( key )
end

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

Put operator.



137
138
139
# File 'lib/unicache.rb', line 137

def []=( key, value )
    self.put( key, value )
end

- (Object) clear

Clear all Cache entries.



287
288
289
290
291
292
293
294
# File 'lib/unicache.rb', line 287

def clear
    @lock.lock
    self.each do |k,v|
        removeEntry( k )
    end
    @evict.clear
    @lock.unlock
end

- (Boolean) exist?(key)

Get Cache entry existance by key (no effect to eviction). Uses "peek", i.e. peek CB is run.

Parameters:

  • key (Object)

    Entry key or tag.

Returns:

  • (Boolean)


180
181
182
183
184
185
186
# File 'lib/unicache.rb', line 180

def exist?( key )
    if peek( key )
        true
    else
        false
    end
end

- (Object) get(key) { ... }

Get Cache entry by key or return nil if not in Cache.

If block is provided, it is run under UniCache lock and will protect the used data from being removed (concurrently).

If ":getdata" callback is defined, it is used to get data. Data is always used, also when nil. UniCache lock is released before callback is called.

Parameters:

  • key (Object)

    Key (or tag) of the Cache entry.

Yields:

  • Procedure to fetch the data.



153
154
155
156
157
158
# File 'lib/unicache.rb', line 153

def get( key, &blk )
    @lock.lock
    ret = _get( key, &blk )
    @lock.unlock
    ret 
end

- (Object) hash_get_op



101
# File 'lib/unicache.rb', line 101

alias :hash_get_op :[]

- (Object) hash_set_op



100
# File 'lib/unicache.rb', line 100

alias :hash_set_op :[]=

- (Object) hash_store



103
# File 'lib/unicache.rb', line 103

alias :hash_store :store

- (Object) peek(key)

Get Cache entry by key (no effect to eviction).

Parameters:

  • key (Object)

    Entry key or tag.



170
171
172
173
# File 'lib/unicache.rb', line 170

def peek( key )
    runCallbacks( :peek, key )
    hash_fetch( key, nil )
end

- (Object) put(key, value)

Put new entry to the Cache. Make space for the new entry if needed.

Parameters:

  • key (Object)

    Key (or tag) of the Cache entry.

  • value (Object)

    Value of the Cache entry.



128
129
130
131
132
133
# File 'lib/unicache.rb', line 128

def put( key, value )
    @lock.lock
    ret = _put( key, value )
    @lock.unlock
    ret 
end

- (Object) registerCallback(type, proc)

Register a callback to be executed on Cache event.

Possible events:

getdata

Data not found in cache, callback is used to fetch it. Data is always added to cache unless an exception is raised. Also all retrys should be captured into ":getdata". <key,value> from request.

add

Item is added to Cache without anything being replaced. <key,value> from request.

replace

Item is added to Cache and another item is removed. <key,value> is evicted entry.

put

Item is added to Cache. Cache conditions has no effect i.e. always run for "put". <key,value> from request.

overwrite

Existing entry value is replaced by new item value. <key,value> from request.

remove

Entry is deleted from Cache.

valueremove

Entry value is removed (remove or overwrite). <key,value> from old entry.

hit

Entry is found in Cache. <key,value> from cache.

miss

Entry is not found in Cache. <key> from request.

peek

Cache peek. <key,value> from request.

Example:

registerCallback( :add,
  Proc.new do |k,v,o| puts "Key: #{k} with value #{v} added" end

Parameters:

  • type (Symbol)

    Callback event.

  • proc (Proc)

    Callback called with args: <key>, <value>, <self>.



263
264
265
266
267
268
269
# File 'lib/unicache.rb', line 263

def registerCallback( type, proc )
    if proc.kind_of?( Proc ) && @callbackType.index( type )
        @callbacks[ type ].push proc
    else
        raise CallbackError, "UniCache: Trying to register invalid callback..."
    end
end

- (Object) remove(key = nil)

Remove oldest Cache entry (Least Recently Used) or given.

Parameters:

  • key (Object) (defaults to: nil)

    Key to remove.

Returns:

  • (Object, Object)

    Key/value pair removed or nil if no entries.



193
194
195
196
197
198
# File 'lib/unicache.rb', line 193

def remove( key = nil )
    @lock.lock
    ret = _remove( key )
    @lock.unlock
    ret
end

- (Object) removeCallback(type = nil)

Remove all callbacks for type or all.

Parameters:

  • type (Symbol) (defaults to: nil)

    Remove callback by type.



275
276
277
278
279
280
281
282
283
# File 'lib/unicache.rb', line 275

def removeCallback( type = nil )
    if type
        @callbacks[ type ] = []
    else
        @callbackType.each do |type|
            @callbacks[ type ] = []
        end
    end
end

- (Object) resize(size)

Resize the Cache.

Parameters:

  • size (Integer)

    New Cache size.

Raises:



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/unicache.rb', line 204

def resize( size )
    
    raise SizeError, "UniCache: Size must be bigger than 0" unless size > 0

    @lock.lock

    # Remove entries that does not fit anymore.
    if @size && size < @size
        ( @size - size ).times do
            _remove
        end
    end

    ret = @size = size

    @lock.unlock

    ret
end

- (Object) setEviction(evict)

Set the eviction policy.

Parameters:

  • evict (Object)

    Cache eviction policy.



95
96
97
# File 'lib/unicache.rb', line 95

def setEviction( evict )
    @evict = evict
end

- (Object) store

Dummy definition for "store" just for removal.



117
# File 'lib/unicache.rb', line 117

def store(); end