Class: UniCache

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

Overview

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

UniCache is created with defined size (or without size limitations). UniCache inherits Hash and thus almost all Hash methods are usable. The cache content is set and referenced using Hash methods.

User can register callbacks that are run at various UniCache events (see: #registerCallback). ":getdata" callback is used to retreive cache data if not in cache. Other callbacks don't effect the UniCache state (unless explicitly changed).

Cache can be setup with content using #open and content can be stored after use with #close. The "open"/"close" actions are defined in the corresponding callbacks.

UniCache is intended to be Thread safe. It uses Mutex to implement access control.

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

Constant Summary

VERSION =
"0.0.4"

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

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

Cache initialization.

Parameters:

  • size (Integer)

    Cache size (> 0), nil for infinite size.

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

    Eviction policy.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/unicache.rb', line 84

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

    # Access control
    @lock = Mutex.new

    # Set cache size.
    resize( size )

    # Set eviction policy.
    setEviction( evict )

    # Declare all callbacks.
    @cb = NotifyHub.declare( :open, :close, :getdata,
                             :add, :replace, :put, :overwrite,
                             :remove, :valueremove, :hit, :miss,
                             :peek )
end

Instance Attribute Details

- (Object) lock (readonly)

Access lock.



77
78
79
# File 'lib/unicache.rb', line 77

def lock
  @lock
end

- (Object) size (readonly)

Cache size.



74
75
76
# File 'lib/unicache.rb', line 74

def size
  @size
end

Class Method Details

+ (Object) version



3
4
5
# File 'lib/version.rb', line 3

def UniCache.version
    UniCache::VERSION
end

Instance Method Details

- (Object) [](key)

Get operator (See: #get)



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

def []( key )
    get( key )
end

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

Put operator (See: #put)



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

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

- (Object) clear

Clear all Cache entries.



335
336
337
338
339
340
341
342
# File 'lib/unicache.rb', line 335

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

- (Object) close

Close UniCache access. The ":close" callback is executed. Typically the user would perform UniCache content store with the callback.



141
142
143
# File 'lib/unicache.rb', line 141

def close
    runCallbacks( :close, nil )
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)

    True if value found.



213
214
215
216
217
218
219
# File 'lib/unicache.rb', line 213

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 run with the data.

Returns:

  • (Object)

    Cache data.



184
185
186
187
188
189
# File 'lib/unicache.rb', line 184

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

- (Object) hash_get_op



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

alias :hash_get_op :[]

- (Object) hash_set_op



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

alias :hash_set_op :[]=

- (Object) hash_store



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

alias :hash_store :store

- (Object) open

Open UniCache for access. The ":open" callback is executed. Typically the user would perform UniCache content initialization with the callback.



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

def open
    runCallbacks( :open, nil )
end

- (Object) peek(key)

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

Parameters:

  • key (Object)

    Entry key or tag.

Returns:

  • (Object)

    Cache data.



202
203
204
205
# File 'lib/unicache.rb', line 202

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.



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

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. Callbacks are passed with following arguments: CacheKey, CacheValue, CacheObject.

Possible events:

:open

Called when #open is executed. This is typically used to initialize the UniCache content.

:close

Called when #close is executed. This is typically used to store the UniCache content for next session.

: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. Callback is called before ":getdata".

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



311
312
313
314
315
316
317
# File 'lib/unicache.rb', line 311

def registerCallback( type, proc )
    begin
        @cb[ type ].action( &proc )
    rescue
        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.



226
227
228
229
230
231
# File 'lib/unicache.rb', line 226

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.



323
324
325
326
327
328
329
330
331
# File 'lib/unicache.rb', line 323

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

- (Integer) resize(size)

Resize the Cache.

Parameters:

  • size (Integer)

    New Cache size, “> 0” or “nil”.

Returns:

  • (Integer)

    New Cache size.

Raises:



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/unicache.rb', line 238

def resize( size )

    return nil if size == nil

    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. Evictor should have the same interface as LruEviction.

Parameters:

  • evict (Object)

    Cache eviction policy.



108
109
110
# File 'lib/unicache.rb', line 108

def setEviction( evict )
    @evict = evict
end

- (Object) store

Dummy definition for "store" just for removal.



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

def store(); end