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

UniCache is inherits Hash, i.e. almost all Hash methods are usable.

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 collapse

VERSION =
"0.0.3"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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

Cache initialization.

Parameters:

  • size (Integer)

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

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

    Eviction policy.



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

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

    @lock = Mutex.new

    resize( size )

    setEviction( evict )

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

Instance Attribute Details

#lockObject (readonly)

Access lock.



67
68
69
# File 'lib/unicache.rb', line 67

def lock
  @lock
end

#sizeObject (readonly)

Cache size.



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

def size
  @size
end

Class Method Details

.versionObject



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

def UniCache.version
    VERSION
end

Instance Method Details

#[](key) ⇒ Object

Get operator (See: #get)



177
178
179
# File 'lib/unicache.rb', line 177

def []( key )
    get( key )
end

#[]=(key, value) ⇒ Object

Put operator (See: #put)



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

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

#clearObject

Clear all Cache entries.



316
317
318
319
320
321
322
323
# File 'lib/unicache.rb', line 316

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

#closeObject

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



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

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


195
196
197
198
199
200
201
# File 'lib/unicache.rb', line 195

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



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

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

#hash_get_opObject



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

alias :hash_get_op :[]

#hash_set_opObject



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

alias :hash_set_op :[]=

#hash_storeObject



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

alias :hash_store :store

#openObject

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



118
119
120
# File 'lib/unicache.rb', line 118

def open
    runCallbacks( :open, nil )
end

#peek(key) ⇒ Object

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

Parameters:

  • key (Object)

    Entry key or tag.



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

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.



143
144
145
146
147
148
# File 'lib/unicache.rb', line 143

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

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



292
293
294
295
296
297
298
# File 'lib/unicache.rb', line 292

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.



208
209
210
211
212
213
# File 'lib/unicache.rb', line 208

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.



304
305
306
307
308
309
310
311
312
# File 'lib/unicache.rb', line 304

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

#resize(size) ⇒ Integer

Resize the Cache.

Parameters:

  • size (Integer)

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

Returns:

  • (Integer)

    New Cache size.

Raises:



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/unicache.rb', line 220

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

#setEviction(evict) ⇒ Object

Set the eviction policy.

Parameters:

  • evict (Object)

    Cache eviction policy.



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

def setEviction( evict )
    @evict = evict
end

#storeObject

Dummy definition for “store” just for removal.



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

def store(); end