Last active
December 11, 2025 19:07
-
-
Save Snawoot/427471411256a98ecb118b513a22d98a to your computer and use it in GitHub Desktop.
simple JS (ES5) cache
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Cache(n, f) { | |
| if (!new.target) { | |
| return new Cache(n, f); | |
| } | |
| n = n >= 2 ? n : 2; | |
| var kv = Object.create(null); | |
| var ki = Object.create(null); | |
| var ik = Object.create(null); | |
| var size = 0; | |
| function randomInt(n) { | |
| var limit = Math.floor((0x100000000 - n) / n) * n; // largest multiple of n <= 2^32 | |
| var rnd; | |
| do { | |
| // Get 32 random bits | |
| rnd = (Math.random() * 0x100000000) >>> 0; // equivalent to Math.floor(Math.random() * 4294967296) | |
| } while (rnd >= limit); | |
| return rnd % n; | |
| } | |
| var has = Object.__proto__.hasOwnProperty.bind(kv); | |
| function getRandom() { | |
| if (size === 0) { | |
| return [undefined, undefined]; | |
| } | |
| var k = ik[randomInt(size)]; | |
| var item = kv[k]; | |
| return [k, item]; | |
| } | |
| function del(key) { | |
| var k = key.toString(); | |
| if (!has(k)) return; | |
| var deletedIdx = ki[k]; | |
| delete ki[k]; | |
| delete kv[k]; | |
| size--; | |
| if (deletedIdx !== size) { | |
| var relocatedKey = ik[size]; | |
| ki[relocatedKey] = deletedIdx; | |
| ik[deletedIdx] = relocatedKey; | |
| } | |
| delete ik[size]; | |
| } | |
| function doEviction() { | |
| for (var i=0; i < n; i++) { | |
| var randomPair = getRandom(); | |
| var k = randomPair[0]; | |
| var v = randomPair[1]; | |
| if (k === undefined) return; | |
| if (!f(k, v)) del(k); | |
| } | |
| } | |
| function get(key) { | |
| return kv[key.toString()]; | |
| } | |
| function set(key, value) { | |
| var k = key.toString(); | |
| var found = has(k); | |
| kv[k] = value; | |
| if (!found) { | |
| // new element added, link it | |
| ik[size] = key; | |
| ki[key] = size; | |
| size++; | |
| doEviction(); | |
| } | |
| } | |
| this.get = get; | |
| this.set = set; | |
| this.has = has; | |
| this.delete = del; | |
| this.getRandom = getRandom; | |
| Object.defineProperty(this, 'size', { | |
| get: function () { | |
| return size; | |
| }, | |
| enumerable: true, | |
| }); | |
| Object.freeze(this); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment