Skip to content

Instantly share code, notes, and snippets.

@Snawoot
Last active December 11, 2025 19:07
Show Gist options
  • Select an option

  • Save Snawoot/427471411256a98ecb118b513a22d98a to your computer and use it in GitHub Desktop.

Select an option

Save Snawoot/427471411256a98ecb118b513a22d98a to your computer and use it in GitHub Desktop.
simple JS (ES5) cache
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