UNPKG

pessimism

Version:

A fast HAMT Map intended for KV caching and optimistic updates

294 lines (255 loc) 7.1 kB
function __(e, r) { return r.tag = e, r; } var e = Math.imul || function(e, r) { return ((e >> 16) * (r |= 0) << 16) + (65535 & e) * r | 0; }, r = [ 0 ]; function mask(r, t) { return 1 << (r >>> e(t, 5) & 31); } function hash(e) { for (var r = e.length - 1 | 0, t = 5381, i = 0; i <= r; ++i) { t = ((t << 5) + t | 0) + e.charCodeAt(i) | 0; } return t >>> 1 & 1073741824 | -1073741825 & t; } function indexBit(e, r) { var t = e & (r - 1 | 0); return 127 & ((t = (t = (t = (858993459 & (t = t - (t >> 1 & 1431655765) | 0)) + (t >> 2 & 858993459) | 0) + (t >> 4) & 252645135) + (t >> 8) | 0) + (t >> 16) | 0); } function copyIndex(e, t) { var i, a; return i = t, a = e[2], i === r || i !== a ? [ e[0], e[1].slice(), t ] : e; } function traverseCopy(e, r, t) { for (var i = e, a = 0; ;) { var n = a, c = i, o = c[0], u = c[1], v = mask(r, n); if ((o | v) !== o) { return [ n, c ]; } var s = indexBit(o, v), f = u[s]; if (f.tag) { return [ n, c ]; } var d = copyIndex(f[0], t); u[s] = __(0, [ d ]), a = n + 1 | 0, i = d; } } function resolveConflict(e, r, t, i, a, n) { var c = mask(e, a), o = mask(r, a), u = c | o; return __(0, [ [ u, c === o ? [ resolveConflict(e, r, t, i, a + 1 | 0, n) ] : 0 !== indexBit(u, c) ? [ i, t ] : [ t, i ], n ] ]); } function removeFromIndex(e, r, t) { var i = e[0], a = i ^ r; if (a !== i) { var n = copyIndex(e, t); return n[1].splice(indexBit(i, r), 1), n[0] = a, n; } return e; } function clearBox(e, r) { for (;;) { var t = e, i = t[3], a = t[2]; if (void 0 !== i) { var n = i; if (a === r) { e = n; continue; } return [ t[0], t[1], t[2], clearBox(n, r) ]; } return a === r ? void 0 : t; } } function clearOptimisticNode(e, r) { switch (0 | e.tag) { case 2: var t = e[0]; if (0 === t[2]) { return e; } var i = e[1], a = clearBox(t, r); return void 0 !== a ? __(2, [ a, i ]) : __(4, [ i ]); case 3: for (var n = e[1], c = e[0], o = c.length, u = [], v = 0; v < o; ) { var s = c[v]; if (0 === s[2]) { u.push(s); } else { var f = clearBox(s, r); void 0 !== f && u.push(f); } v = v + 1 | 0; } return u.length > 0 ? __(3, [ u, n ]) : __(4, [ n ]); default: return e; } } function addToBucket(e, r) { for (var t = e.slice(), i = t.length, a = 0 !== r[2], n = 0, c = !1; n < i && !c; ) { var o = t[n]; o[0] === r[0] && (a && (r[3] = o), t[n] = r, c = !0), n = n + 1 | 0; } return c || t.push(r), t; } function removeFromBucket(e, r) { for (var t = e.length, i = [], a = 0; a < t; ) { var n = e[a]; n[0] !== r && i.push(n), a = a + 1 | 0; } return i; } function rebuildWithStack(e, r, t, i, a) { for (;;) { var n = t, c = r, o = e, u = mask(i, n); if (!o) { return c; } var v = o[1], s = o[0]; if (0 !== c[0]) { var f = copyIndex(s, a), d = indexBit(f[0], u); f[1][d] = __(0, [ c ]), t = n - 1 | 0, r = f, e = v; } else { t = n - 1 | 0, r = removeFromIndex(s, u, a), e = v; } } } function make(e) { return [ 0, [], r ]; } function asMutable(e) { return e[2] === r ? [ e[0], e[1], [ 0 ] ] : e; } function asImmutable(e) { return e[2] = r, e; } function getUndefined(e, r) { for (var t = hash(r), i = e, a = 0; ;) { var n = a, c = i, o = c[0], u = c[1], v = mask(t, n); if ((o | v) !== o) { return; } var s = u[indexBit(o, v)]; switch (0 | s.tag) { case 0: a = n + 1 | 0, i = s[0]; continue; case 1: return s[0] === r ? s[1] : void 0; case 2: var f = s[0]; return f[0] === r ? f[1] : void 0; case 3: for (var d = s[0], l = r, _ = d.length, m = void 0, h = 0; void 0 === m && h < _; ) { var k = d[h]; k[0] === l && (m = k[1]), h = h + 1 | 0; } return m; case 4: return; } } } function setOptimistic(e, r, t, i) { var a = e[2], n = copyIndex(e, a), c = hash(r), o = traverseCopy(n, c, a), u = o[1], v = o[0], s = 0 !== i, f = mask(c, v), d = u[0] | f, l = indexBit(d, f); if (d !== u[0]) { u[1].splice(l, 0, __(1, [ r, t, c ])), u[0] = d; } else { var _, m, h, k = u[1][l], p = 0; switch (0 | k.tag) { case 0: _ = k; break; case 1: var x = k[2], g = k[1], B = k[0]; B === r && s ? _ = __(2, [ [ r, t, i, [ B, g, 0, void 0 ] ], c ]) : B === r ? _ = __(1, [ r, t, c ]) : x === c ? _ = __(3, [ [ [ B, g, 0, void 0 ], [ r, t, 0, void 0 ] ], c ]) : (m = x, h = k, p = 1); break; case 2: var b = k[0]; if (b[0] === r && s) { _ = __(2, [ [ r, t, i, b ], c ]); } else if (b[0] === r) { _ = __(2, [ [ r, t, 0, void 0 ], c ]); } else { var I = k[1]; I === c ? _ = __(3, [ [ b, [ r, t, 0, void 0 ] ], c ]) : (m = I, h = k, p = 1); } break; case 3: var y = k[1]; if (y === c) { var O = [ r, t, i, void 0 ]; _ = __(3, [ addToBucket(k[0], O), c ]); } else { m = y, h = k, p = 1; } break; case 4: _ = s ? __(2, [ [ r, t, i, void 0 ], c ]) : __(1, [ r, t, c ]); } 1 === p && (_ = resolveConflict(m, c, h, s ? __(2, [ [ r, t, i, void 0 ], c ]) : __(1, [ r, t, c ]), v + 1 | 0, a)), u[1][l] = _; } return n; } function set(e, r, t) { return setOptimistic(e, r, t, 0); } function remove(e, r) { for (var t = e[2], i = hash(r), a = 0, n = e, c = 0; ;) { var o = c, u = n, v = a, s = u[0], f = u[1], d = mask(i, o); if ((s | d) !== s) { return e; } var l, _ = indexBit(s, d), m = f[_], h = 0; switch (0 | m.tag) { case 0: c = o + 1 | 0, n = m[0], a = [ u, v ]; continue; case 1: l = m[0], h = 1; break; case 2: l = m[0][0], h = 1; break; case 3: if (m[1] === i) { var k = removeFromBucket(m[0], r); if (0 === k.length) { return rebuildWithStack(v, removeFromIndex(u, d, t), o - 1 | 0, i, t); } var p = copyIndex(u, t); return p[1][_] = __(3, [ k, i ]), rebuildWithStack(v, p, o - 1 | 0, i, t); } return e; case 4: return e; } if (1 === h) { return l === r ? rebuildWithStack(v, removeFromIndex(u, d, t), o - 1 | 0, i, t) : e; } } } function clearOptimistic(e, r) { for (var t = copyIndex(e, e[2]), i = 0; i <= 31; ++i) { var a = 1 << i; if (0 != (a & t[0])) { var n = indexBit(t[0], a), c = clearOptimisticNode(t[1][n], r); switch (0 | c.tag) { case 0: var o = clearOptimistic(c[0], r); 0 === o[0] ? (t[1].splice(n, 1), t[0] = t[0] ^ a) : t[1][n] = __(0, [ o ]); break; case 4: t[1].splice(n, 1), t[0] = t[0] ^ a; break; default: t[1][n] = c; } } } return t; } export { asImmutable, asMutable, clearOptimistic, getUndefined as get, make, remove, set, setOptimistic };