-
Notifications
You must be signed in to change notification settings - Fork 68
LRU Cache Feature and usage overview
In-memory LRU cache implementation for Node, inspired by Google Guava Loading Cache .
General Format
var Cache = require("dsjslib").Cache
//General format
var cache = new Cache(cacheSpecObject)
###Loading Cache:
The cache can be a simple loading cache which knows how to load entries when a miss occurs Example below creates a cache of maximum size 100 and a caller provided automatic loader function to load the value in Cache if not present. The loader function can either be synchronous or asynchronous. If an async loader is being used, cache should be accessed using get(key,callback) method whereas if the loader is synchronous, the getSync(key) should be used to access values in cache
When using an async loader, it's possible that multiple requests for the same key is done by the client even when the first request has not finished loading i.e. first call to autoloader to load the key has not returned. The cache logic ensures that even in this case, the auto-loader is called only once and the get() callbacks are queued to be fulfilled when the auto-loader has finished loading the key.
myloader function should take two arguments (key, onCompleteCallbackFn).
Once the function has finished loading the value of the key, it should call onCompleteCallbackFn providing the result and error if any.
onCompleteCallbackFn takes two arguments (error, result)
Loading cache centralizes loading logic and avoids patterns like
if(!getFromCache()){ loadMyData(), putInCache()}
sprayed all over your code
var cache=new Cache(
/*Cache spec object*/{
'maximumSize':100,
'loaderFunction':myLoaderFn
})
//example async load function, say, requires loading data from file
function myLoaderFn(key,onCompleteCallback){
//need to read some data from file
fs.readFile('/depot/dsjs/tests/resources/largetextfile.txt', "utf-8", function (err, data) {
//do something with data and compute value
var computed=....
//Tell the cache you are done loading
onCompleteCallback(err,computed)
}
}
//The client can get the result associated from cache via get call specifying the callback for value
cache.get(key,function(err,value){
// do something with value
})
//Example synchronous load function, say, returns data from computation
function myLoaderFn(key,onCompleteCallback){
var computed= key*key
//Tell the cache you are done loading
onCompleteCallback(err,computed)
}
}
//The client can get the result associated from cache via sync get call
var value = cache.getSync(key)
Of-course, Its completely valid to have a simple non-loading cache as well i.e. no loader function is specified for the cache. In that case, values can be added to the cache using put(key,value) and accessed using getSync(key). Eviction and and other Sizing rules (discussed later) will still apply as configured.
###Eviction
Cache can automatically evict elements based on criteria.
Eviction: Maximum size Elements will be evicted in LRU order. Eviction occurs on write operation.
var cache=new Cache(
/*Cache spec object*/{
'maximumSize':100,
})
Eviction: Maximum Weight e.g. below creates a Cache with capacity based on maximum weight instead of size. weigherFunction would be invoked to get the weight of key, value. Eviction still ocurs in LRU order. Weight is used to determince if the capacity has exceeded not for selecting what to evict. Note that eviction strategy for Cache can be based on max weight or max size but not both.
var cache=new Cache(
{
'maximumWeight':1000,
'weigherFunction':myWeigherFn,
'loaderFunction':myloader,
'onRemove':removeListenerFn
})
Eviction: Time to Live(TTL) Elements expire after the specified time has elapsed since the entry creation or update. Useful for dropping stale data. Cleanup of expired items (if required) happens on read/write access of the Cache. Cache maintains a write queue via additional pointers in addition to access queue.
var cache=new Cache(
'maximumSize':100,
'expiresAfterWrite':60,
'loaderFunction':myloader
})
###Cache performance
Cache stats can be recorded. Hit, Miss and request counts are recorded. Useful to get feedback so that cache configuration can be tuned.
var cache=new Cache(
{
'maximumSize':100,
.................
'recordStats':true
})
###Removal Notifications
If configured, removal notifications are sent as elements get evicted from cache. Useful to close associated resources. The notification callback gets key, value & cause as arguments.
var cache=new Cache(
'maximumSize':100,
'expiresAfterWrite':60,
'loaderFunction':myloader,
'onRemove':removeListenerFn
})