From 9d1b2502045fe7d7bb86570779636c9bbc2ba19a Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 8 May 2017 21:00:41 +1000 Subject: Cache string hashes in TString --- src/llex.js | 2 +- src/lstring.js | 26 ++++++++++++++++++-------- src/ltable.js | 4 ++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/llex.js b/src/llex.js index 220f45d..2e37eca 100644 --- a/src/llex.js +++ b/src/llex.js @@ -208,7 +208,7 @@ const luaX_newstring = function(ls, str) { o.setbvalue(true); } else { /* string already present */ /* HACK: Workaround lack of ltable 'keyfromval' */ - let tpair = ls.h.strong.get(lstring.luaS_hash(ts)); + let tpair = ls.h.strong.get(lstring.luaS_hashlongstr(ts)); assert(tpair.value == o); ts = tpair.key.tsvalue(); /* re-use value previously stored */ } diff --git a/src/lstring.js b/src/lstring.js index 3e94171..cc399b8 100644 --- a/src/lstring.js +++ b/src/lstring.js @@ -7,6 +7,7 @@ const defs = require('./defs.js'); class TString { constructor(L, str) { + this.hash = null; this.realstring = str; } @@ -28,8 +29,16 @@ const luaS_eqlngstr = function(a, b) { /* converts strings (arrays) to a consistent map key */ const luaS_hash = function(str) { - assert(str instanceof TString); - return str.realstring.map(e => `${e}|`).join(''); + assert(Array.isArray(str)); + return str.map(e => `${e}|`).join(''); +}; + +const luaS_hashlongstr = function(ts) { + assert(ts instanceof TString); + if(ts.hash === null) { + ts.hash = luaS_hash(ts.getstr()); + } + return ts.hash; }; /* variant that takes ownership of array */ @@ -48,9 +57,10 @@ const luaS_newliteral = function(L, str) { return luaS_bless(L, defs.to_luastring(str)); }; -module.exports.luaS_eqlngstr = luaS_eqlngstr; -module.exports.luaS_hash = luaS_hash; -module.exports.luaS_bless = luaS_bless; -module.exports.luaS_new = luaS_new; -module.exports.luaS_newliteral = luaS_newliteral; -module.exports.TString = TString; +module.exports.luaS_eqlngstr = luaS_eqlngstr; +module.exports.luaS_hash = luaS_hash; +module.exports.luaS_hashlongstr = luaS_hashlongstr; +module.exports.luaS_bless = luaS_bless; +module.exports.luaS_new = luaS_new; +module.exports.luaS_newliteral = luaS_newliteral; +module.exports.TString = TString; diff --git a/src/ltable.js b/src/ltable.js index a2987d3..1b55256 100644 --- a/src/ltable.js +++ b/src/ltable.js @@ -24,7 +24,7 @@ const table_hash = function(key) { return key.value; case CT.LUA_TSHRSTR: case CT.LUA_TLNGSTR: - return lstring.luaS_hash(key.value); + return lstring.luaS_hashlongstr(key.tsvalue()); default: throw new Error("unknown key type: " + key.type); } @@ -54,7 +54,7 @@ const luaH_getint = function(t, key) { const luaH_getstr = function(t, key) { assert(key instanceof lstring.TString); - return getgeneric(t, lstring.luaS_hash(key)); + return getgeneric(t, lstring.luaS_hashlongstr(key)); }; const luaH_get = function(t, key) { -- cgit v1.2.3-70-g09d2