UNPKG

pessimism

Version:

A fast HAMT Map intended for KV caching and optimistic updates

282 lines (249 loc) 7.17 kB
"use strict"; 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, o = i, c = o[0], s = o[1], u = mask(r, n); if ((c | u) !== c) { return [ n, o ]; } var v = indexBit(c, u), f = s[v]; if (f.tag) { return [ n, o ]; } var d = copyIndex(f[0], t); s[v] = __(0, [ d ]), a = n + 1 | 0, i = d; } } function resolveConflict(e, r, t, i, a, n) { var o = mask(e, a), c = mask(r, a), s = o | c; return __(0, [ [ s, o === c ? [ resolveConflict(e, r, t, i, a + 1 | 0, n) ] : 0 !== indexBit(s, o) ? [ 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], o = e[0], c = o.length, s = [], u = 0; u < c; ) { var v = o[u]; if (0 === v[2]) { s.push(v); } else { var f = clearBox(v, r); void 0 !== f && s.push(f); } u = u + 1 | 0; } return s.length > 0 ? __(3, [ s, n ]) : __(4, [ n ]); default: return e; } } function addToBucket(e, r) { for (var t = e.slice(), i = t.length, a = 0 !== r[2], n = 0, o = !1; n < i && !o; ) { var c = t[n]; c[0] === r[0] && (a && (r[3] = c), t[n] = r, o = !0), n = n + 1 | 0; } return o || 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, o = r, c = e, s = mask(i, n); if (!c) { return o; } var u = c[1], v = c[0]; if (0 !== o[0]) { var f = copyIndex(v, a), d = indexBit(f[0], s); f[1][d] = __(0, [ o ]), t = n - 1 | 0, r = f, e = u; } else { t = n - 1 | 0, r = removeFromIndex(v, s, a), e = u; } } } function setOptimistic(e, r, t, i) { var a = e[2], n = copyIndex(e, a), o = hash(r), c = traverseCopy(n, o, a), s = c[1], u = c[0], v = 0 !== i, f = mask(o, u), d = s[0] | f, l = indexBit(d, f); if (d !== s[0]) { s[1].splice(l, 0, __(1, [ r, t, o ])), s[0] = d; } else { var _, m, p, x = s[1][l], h = 0; switch (0 | x.tag) { case 0: _ = x; break; case 1: var k = x[2], B = x[1], b = x[0]; b === r && v ? _ = __(2, [ [ r, t, i, [ b, B, 0, void 0 ] ], o ]) : b === r ? _ = __(1, [ r, t, o ]) : k === o ? _ = __(3, [ [ [ b, B, 0, void 0 ], [ r, t, 0, void 0 ] ], o ]) : (m = k, p = x, h = 1); break; case 2: var g = x[0]; if (g[0] === r && v) { _ = __(2, [ [ r, t, i, g ], o ]); } else if (g[0] === r) { _ = __(2, [ [ r, t, 0, void 0 ], o ]); } else { var I = x[1]; I === o ? _ = __(3, [ [ g, [ r, t, 0, void 0 ] ], o ]) : (m = I, p = x, h = 1); } break; case 3: var y = x[1]; if (y === o) { var O = [ r, t, i, void 0 ]; _ = __(3, [ addToBucket(x[0], O), o ]); } else { m = y, p = x, h = 1; } break; case 4: _ = v ? __(2, [ [ r, t, i, void 0 ], o ]) : __(1, [ r, t, o ]); } 1 === h && (_ = resolveConflict(m, o, p, v ? __(2, [ [ r, t, i, void 0 ], o ]) : __(1, [ r, t, o ]), u + 1 | 0, a)), s[1][l] = _; } return n; } exports.asImmutable = function asImmutable(e) { return e[2] = r, e; }, exports.asMutable = function asMutable(e) { return e[2] === r ? [ e[0], e[1], [ 0 ] ] : e; }, exports.clearOptimistic = 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), o = clearOptimisticNode(t[1][n], r); switch (0 | o.tag) { case 0: var c = clearOptimistic(o[0], r); 0 === c[0] ? (t[1].splice(n, 1), t[0] = t[0] ^ a) : t[1][n] = __(0, [ c ]); break; case 4: t[1].splice(n, 1), t[0] = t[0] ^ a; break; default: t[1][n] = o; } } } return t; }, exports.get = function getUndefined(e, r) { for (var t = hash(r), i = e, a = 0; ;) { var n = a, o = i, c = o[0], s = o[1], u = mask(t, n); if ((c | u) !== c) { return; } var v = s[indexBit(c, u)]; switch (0 | v.tag) { case 0: a = n + 1 | 0, i = v[0]; continue; case 1: return v[0] === r ? v[1] : void 0; case 2: var f = v[0]; return f[0] === r ? f[1] : void 0; case 3: for (var d = v[0], l = r, _ = d.length, m = void 0, p = 0; void 0 === m && p < _; ) { var x = d[p]; x[0] === l && (m = x[1]), p = p + 1 | 0; } return m; case 4: return; } } }, exports.make = function make(e) { return [ 0, [], r ]; }, exports.remove = function remove(e, r) { for (var t = e[2], i = hash(r), a = 0, n = e, o = 0; ;) { var c = o, s = n, u = a, v = s[0], f = s[1], d = mask(i, c); if ((v | d) !== v) { return e; } var l, _ = indexBit(v, d), m = f[_], p = 0; switch (0 | m.tag) { case 0: o = c + 1 | 0, n = m[0], a = [ s, u ]; continue; case 1: l = m[0], p = 1; break; case 2: l = m[0][0], p = 1; break; case 3: if (m[1] === i) { var x = removeFromBucket(m[0], r); if (0 === x.length) { return rebuildWithStack(u, removeFromIndex(s, d, t), c - 1 | 0, i, t); } var h = copyIndex(s, t); return h[1][_] = __(3, [ x, i ]), rebuildWithStack(u, h, c - 1 | 0, i, t); } return e; case 4: return e; } if (1 === p) { return l === r ? rebuildWithStack(u, removeFromIndex(s, d, t), c - 1 | 0, i, t) : e; } } }, exports.set = function set(e, r, t) { return setOptimistic(e, r, t, 0); }, exports.setOptimistic = setOptimistic;