From 8cf0f0df6e03b7768b08a219f2627e90fa2a6452 Mon Sep 17 00:00:00 2001 From: Robin Wellner Date: Tue, 23 Dec 2014 23:56:46 +0100 Subject: [PATCH] Add support for lots of tables (> 200) Now only a single variable is used (_). What effect does this have on the file size and runtime? I have no idea. I don't think it'll be *that* much, though. --- bigtest.lua | 12 ++++++++++++ ser.lua | 17 +++++++++-------- tests.lua | 25 ++++++++++++++----------- 3 files changed, 35 insertions(+), 19 deletions(-) create mode 100644 bigtest.lua diff --git a/bigtest.lua b/bigtest.lua new file mode 100644 index 0000000..a6e5ec9 --- /dev/null +++ b/bigtest.lua @@ -0,0 +1,12 @@ +local serialize = require 'ser' + +local t = {} +for i = 1, 15 do + t[i] = {} + for j = 1, 10 do + t[i][j] = {{'woo'}} + end +end +local s = serialize(t) +print(s) +loadstring(s)() diff --git a/ser.lua b/ser.lua index 6b5bd36..1583968 100644 --- a/ser.lua +++ b/ser.lua @@ -22,7 +22,7 @@ local function write(t, memo, rev_memo) memo[t] = index rev_memo[index] = t end - return '_' .. memo[t] + return '_[' .. memo[t] .. ']' else error("Trying to serialize unsupported type " .. ty) end @@ -53,9 +53,9 @@ end local function write_table_ex(t, memo, rev_memo, srefs, name) if type(t) == 'function' then - return 'local _' .. name .. ' = loadstring ' .. make_safe(dump(t)) + return '_[' .. name .. '] = loadstring ' .. make_safe(dump(t)) end - local m = {'local _', name, ' = {'} + local m = {'_[', name, '] = {'} local mi = 3 for i = 1, #t do -- don't use ipairs here, we need the gaps local v = t[i] @@ -106,16 +106,17 @@ return function(t) -- phase 3: add all the tricky cyclic stuff for i, v in ipairs(srefs) do n = n + 1 - result[n] = write_key_value_pair(v[2], v[3], memo, rev_memo, '_' .. v[1]) + result[n] = write_key_value_pair(v[2], v[3], memo, rev_memo, '_[' .. v[1] .. ']') end -- phase 4: add something about returning the main table - if result[n]:sub(1, 8) == 'local _0' then - result[n] = 'return' .. result[n]:sub(11) + if result[n]:sub(1, 5) == '_[0] ' then + result[n] = 'return' .. result[n]:sub(7) else - result[n + 1] = 'return _0' + result[n + 1] = 'return _[0]' end -- phase 5: just concatenate everything - return concat(result, '\n') + result = concat(result, '\n') + return n > 1 and 'local _ = {}\n' .. result or result end diff --git a/tests.lua b/tests.lua index bb284f5..db0dc9d 100644 --- a/tests.lua +++ b/tests.lua @@ -36,14 +36,16 @@ case({}, 'return {}', 'empty table') case({true}, 'return {true}', 'simple table') case({{}}, [[ -local _1 = {} -return {_1}]], 'empty table within a table') +local _ = {} +_[1] = {} +return {_[1]}]], 'empty table within a table') local _t = {} _t.self = _t -case(_t, [[local _0 = {} -_0.self = _0 -return _0]], 'simple cycle') +case(_t, [=[local _ = {} +_[0] = {} +_[0].self = _[0] +return _[0]]=], 'simple cycle') case_error({coroutine.create(function()end)}, './ser.lua:27: Trying to serialize unsupported type thread', 'unsupported type') @@ -54,12 +56,13 @@ case({'\127\230\255\254\128\12\0128\n\31'}, 'return {"\\127\\230\\255\\254\\128\ case({['\127\230\255\254\128\12\0128\n\31'] = '\0'}, 'return {["\\127\\230\\255\\254\\128\\12\\0128\\n\\31"] = "\\0"}', 'non-ASCII or control characters in string key') local x = {} -case({x, {x}, x}, [[ -local _2 = {} -local _1 = {} -local _0 = {_1, _2, _1} -_2[1] = _1 -return _0]], 'repeated table') +case({x, {x}, x}, [=[ +local _ = {} +_[2] = {} +_[1] = {} +_[0] = {_[1], _[2], _[1]} +_[2][1] = _[1] +return _[0]]=], 'repeated table') case({['end'] = true, ['false'] = false}, 'return {["false"] = false, ["end"] = true}', 'keywords as table keys')