From 0a4061e70a1d3b0767352dbce98c961d251e3879 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Thu, 11 May 2017 23:13:27 +1000 Subject: src/ltable.js: Make next() O(1) --- src/ltable.js | 108 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 60 insertions(+), 48 deletions(-) (limited to 'src/ltable.js') diff --git a/src/ltable.js b/src/ltable.js index 32193c8..4a43936 100644 --- a/src/ltable.js +++ b/src/ltable.js @@ -35,13 +35,53 @@ class Table { this.id = L.l_G.id_counter++; this.strong = new Map(); this.dead_hashes = []; + this.f = void 0; /* first entry */ + this.l = void 0; /* last entry */ this.metatable = null; } } +const add = function(t, hash, key, value) { + clean_dead_keys(t); + let prev; + let entry = { + key: key, + value: value, + p: prev = t.l, + n: void 0 + }; + if (!t.f) t.f = entry; + if (prev) prev.n = entry; + t.strong.set(hash, entry); + t.l = entry; +}; + +const remove = function(t, hash) { + let entry = t.strong.get(hash); + if (entry) { + let next = entry.n; + let prev = entry.p; + if(prev) prev.n = next; + if(next) next.p = prev; + if(t.f === entry) t.f = next; + if(t.l === entry) t.l = prev; + t.strong.delete(hash); + } +}; + +/* Can't remove from table immediately due to next() */ +const mark_dead = function(t, hash) { + let e = t.strong.get(hash); + if (e) { + e.key.setdeadvalue(); + e.value = new lobject.TValue(CT.LUA_TNIL, null); + t.dead_hashes.push(hash); + } +} + const clean_dead_keys = function(t) { for (let i=0; i