UNPKG

multi-key-cache

Version:

A JavaScript (JS) cache that can have multiple complex values as keys

250 lines (200 loc) 5.83 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.multiKeyCache = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ if (typeof Map !== 'function' || (process && process.env && process.env.TEST_MAPORSIMILAR === 'true')) { module.exports = _dereq_('./similar'); } else { module.exports = Map; } },{"./similar":2}],2:[function(_dereq_,module,exports){ function Similar() { this.list = []; this.lastItem = undefined; this.size = 0; return this; } Similar.prototype.get = function(key) { var index; if (this.lastItem && this.lastItem.key === key) { return this.lastItem.val; } index = this.indexOf(key); if (index >= 0) { this.lastItem = this.list[index]; return this.list[index].val; } return undefined; }; Similar.prototype.set = function(key, val) { var index; if (this.lastItem && this.lastItem.key === key) { this.lastItem.val = val; return this; } index = this.indexOf(key); if (index >= 0) { this.lastItem = this.list[index]; this.list[index].val = val; return this; } this.lastItem = { key: key, val: val }; this.list.push(this.lastItem); this.size++; return this; }; Similar.prototype.delete = function(key) { var index; if (this.lastItem && this.lastItem.key === key) { this.lastItem = undefined; } index = this.indexOf(key); if (index >= 0) { this.size--; return this.list.splice(index, 1)[0]; } return undefined; }; // important that has() doesn't use get() in case an existing key has a falsy value, in which case has() would return false Similar.prototype.has = function(key) { var index; if (this.lastItem && this.lastItem.key === key) { return true; } index = this.indexOf(key); if (index >= 0) { this.lastItem = this.list[index]; return true; } return false; }; Similar.prototype.forEach = function(callback, thisArg) { var i; for (i = 0; i < this.size; i++) { callback.call(thisArg || this, this.list[i].val, this.list[i].key, this); } }; Similar.prototype.indexOf = function(key) { var i; for (i = 0; i < this.size; i++) { if (this.list[i].key === key) { return i; } } return -1; }; module.exports = Similar; },{}],3:[function(_dereq_,module,exports){ var MapOrSimilar = _dereq_('map-or-similar'); function MultiKeyCache() { this.cache = new MapOrSimilar(); this._vAl_kEY_nAMe_no_cOLLision_ = '_vAl_kEY_nAMe_no_cOLLision_'; } MultiKeyCache.prototype.set = function(keys, value) { var keysLen = keys.length, currentCache = this.cache, newSubCache, i; if (!keysLen) { return this; } for (i = 0; i < keysLen; i++) { if (currentCache.has(keys[i])) { currentCache = currentCache.get(keys[i]); continue; } newSubCache = new MapOrSimilar(); currentCache.set(keys[i], newSubCache); currentCache = newSubCache; } currentCache.set(this._vAl_kEY_nAMe_no_cOLLision_, value); return this; }; MultiKeyCache.prototype.get = function(keys) { var keysLen = keys.length, currentCache = this.cache, i; if (!keysLen) { return undefined; } for (i = 0; i < keysLen; i++) { currentCache = currentCache.get(keys[i]); if (!currentCache) { return undefined; } } return currentCache.get(this._vAl_kEY_nAMe_no_cOLLision_); }; MultiKeyCache.prototype.delete = function(keys) { var keysLen = keys.length, currentCache = this.cache, cachePath = [currentCache], i; if (!keysLen) { return false; } // walk up the tree gathering the maps for (i = 0; i < keysLen; i++) { currentCache = currentCache.get(keys[i]); cachePath.push(currentCache); if (!currentCache) { return false; } } // delete the value currentCache.delete(this._vAl_kEY_nAMe_no_cOLLision_); // walk back down the tree deleting any empty maps for (i = keysLen - 1; i >= 0; i--) { currentCache = cachePath[i].get(keys[i]); if (currentCache.size) { break; } cachePath[i].delete(keys[i]); } return true; }; MultiKeyCache.prototype.has = function(keys) { var keysLen = keys.length, currentCache = this.cache, i; if (!keysLen) { return false; } for (i = 0; i < keysLen; i++) { currentCache = currentCache.get(keys[i]); if (!currentCache) { return false; } } return true; }; MultiKeyCache.prototype.values = function() { var self = this, values = []; function getCacheValues(currentCache) { currentCache.forEach(function(val, key) { if (key === self._vAl_kEY_nAMe_no_cOLLision_) { values.push(val); } else { getCacheValues(val); } }); } getCacheValues(this.cache); return values; }; MultiKeyCache.prototype.keyNodes = function() { var keys = []; function getCacheKeys(currentCache) { currentCache.forEach(function(val, key) { keys.push(key); if (val && val.size) { getCacheKeys(val); } }); } getCacheKeys(this.cache); return keys; }; module.exports = MultiKeyCache; },{"map-or-similar":1}]},{},[3])(3) });