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

#initialize(size, evict = LruEviction.new) ⇒ UniCache

Cache initialization.

Parameters:

  • size (Integer)

    Cache size.

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

    Eviction policy.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/unicache.rb', line 72

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

    @lock = Mutex.new

    resize( size )

    setEviction( evict )

    @cb = NotifyHub.declare( :getdata,
                             :add, :replace, :put, :overwrite,
                             :remove, :valueremove, :hit, :miss,
                             :peek )
end

Instance Attribute Details

#lockObject (readonly)

Access lock.



65
66
67
# File 'lib/unicache.rb', line 65

def lock
  @lock
end

#sizeObject (readonly)

Cache size.



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

def size
  @size
end

Instance Method Details

#[](key) ⇒ Object

Get operator.



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

def []( key )
    get( key )
end

#[]=(key, value) ⇒ Object

Put operator.



133
134
135
# File 'lib/unicache.rb', line 133

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

#clearObject

Clear all Cache entries.



283
284
285
286
287
288
289
290
# File 'lib/unicache.rb', line 283

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

#exist?(key) ⇒ Boolean

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)


176
177
178
179
180
181
182
# File 'lib/unicache.rb', line 176

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

#get(key) { ... } ⇒ Object

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.



149
150
151
152
153
154
# File 'lib/unicache.rb', line 149

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

#hash_get_opObject



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

alias :hash_get_op :[]

#hash_set_opObject



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

alias :hash_set_op :[]=

#hash_storeObject



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

alias :hash_store :store

#peek(key) ⇒ Object

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

Parameters:

  • key (Object)

    Entry key or tag.



166
167
168
169
# File 'lib/unicache.rb', line 166

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

#put(key, value) ⇒ Object

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.



124
125
126
127
128
129
# File 'lib/unicache.rb', line 124

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

#registerCallback(type, proc) ⇒ Object

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>.



259
260
261
262
263
264
265
# File 'lib/unicache.rb', line 259

def registerCallback( type, proc )
    begin
        @cb[ type ].action( &proc )
    rescue
        raise CallbackError, "UniCache: Trying to register invalid callback..."
    end
end

#remove(key = nil) ⇒ Object

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.



189
190
191
192
193
194
# File 'lib/unicache.rb', line 189

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

#removeCallback(type = nil) ⇒ Object

Remove all callbacks for type or all.

Parameters:

  • type (Symbol) (defaults to: nil)

    Remove callback by type.



271
272
273
274
275
276
277
278
279
# File 'lib/unicache.rb', line 271

def removeCallback( type = nil )
    if type
        @cb.remove( type )
    else
        @cb.ids.each do |id|
            @cb[id].remove
        end
    end
end

#resize(size) ⇒ Object

Resize the Cache.

Parameters:

  • size (Integer)

    New Cache size.

Raises:



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/unicache.rb', line 200

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

#setEviction(evict) ⇒ Object

Set the eviction policy.

Parameters:

  • evict (Object)

    Cache eviction policy.



91
92
93
# File 'lib/unicache.rb', line 91

def setEviction( evict )
    @evict = evict
end

#storeObject

Dummy definition for “store” just for removal.



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

def store(); end