UNPKG

rrcache

Version:

Random Replacement Cache with TTL and preload option. A simple and clean RR cache that just works.

128 lines (122 loc) 3.14 kB
// rrcache // RR Cache with TTL // Copyright (C) 2014 by angleman, // All Rights Reserved // License: MIT function ramcache(initOptions) { var fs = require('fs') var cache, keys, ttls var options = initOptions || {} function init() { cache = {} keys = [] ttls = {} } function loadCache(values) { if (values) { cache = values keys = [] for (var key in cache) { if (!options.max || keys.length < options.max) { // room in cache keys.push(key) } else { delete cache[key] // cache size exceeded, drop the rest } } } } function clearTTL(key) { if (ttls[key]) { clearInterval(ttls[key]) delete ttls[key] } } function clearTTLs() { for(var key in ttls) { clearTTL(key) } } function cleanCache() { while (options.max && keys.length >= options.max) { var random = Math.round(Math.random() * keys.length) var key = keys[random] keys.splice(random, 1) delete cache[key] clearTTL(key) } } function set(key, value, ttl) { if (typeof key != 'undefined') { clearTTL(key) if (typeof value == 'undefined') { if (cache[key]) { // delete cache existing entry delete cache[key] var idx = keys.indexOf(key) keys.splice(idx, 1) } } else { cache[key] = value if (keys.indexOf(key) < 0) { cleanCache() keys.push(key) } if (ttl) ttls[key] = setTimeout(expire, ttl, key) } } } function loadData(file) { file = file || options.file if (file) { options.file = file if (fs.existsSync(file)) { var json = fs.readFileSync(file, 'utf8') options.data = JSON.parse(json) } } } function loadFile(file) { init() loadData(file) loadCache(options.data) if (options.data) delete options.data // clean up memory } function saveFile(file) { file = file || options.file if (file) { var json = JSON.stringify(cache) fs.writeFileSync(file, json, 'utf8') } } options.max = options.max || 100000 init() loadData(options.file) loadCache(options.data) function expire(key) { if (ttls[key]) delete ttls[key] if (cache[key]) delete cache[key] var i = keys.indexOf(key) if (i > 0) keys.splice(i, 1) } var publicFunctions = { get: function(key) { return cache[key] }, set: set, options: function(newOptions) { options = newOptions || options cleanCache() }, clear: init, length: function() { return keys.length }, values: function() { return cache }, load: loadCache, loadFile: loadFile, saveFile: saveFile } return publicFunctions } module.exports = ramcache