summaryrefslogtreecommitdiffstats
path: root/lua-squarkdb.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2010-08-13 10:17:31 +0300
committerTimo Teräs <timo.teras@iki.fi>2010-08-13 10:17:31 +0300
commit8bc76c78a69360efc7a07a3c4e92f393cca22543 (patch)
tree447d60cf98355698ef9d6ad2480550b0d71ed266 /lua-squarkdb.c
parente0a013397a51963039c43877be3afe954e519be0 (diff)
downloadsquark-8bc76c78a69360efc7a07a3c4e92f393cca22543.tar.bz2
squark-8bc76c78a69360efc7a07a3c4e92f393cca22543.tar.xz
db: smarter string pointer encoding (include length field)
So we don't need explicit null terminator in most cases saving space. It will also speed up comparisons as getting string blob is now constant time (no strlen needed).
Diffstat (limited to 'lua-squarkdb.c')
-rw-r--r--lua-squarkdb.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/lua-squarkdb.c b/lua-squarkdb.c
index dbac6d0..09d4afe 100644
--- a/lua-squarkdb.c
+++ b/lua-squarkdb.c
@@ -227,7 +227,7 @@ static int Lsqdb_map_strings(lua_State *L)
{
struct sqdb *db;
const char *str;
- char *ptr;
+ unsigned char *ptr;
size_t len, total, pos;
db = Lsqdb_checkarg(L, 1);
@@ -238,7 +238,9 @@ static int Lsqdb_map_strings(lua_State *L)
lua_pushnil(L);
while (lua_next(L, 2) != 0) {
str = luaL_checklstring(L, -2, &len);
- total += len + 1;
+ total += len;
+ if (len >= (1 << SQDB_LENGTH_BITS))
+ total++;
lua_pop(L, 1);
}
@@ -252,15 +254,20 @@ static int Lsqdb_map_strings(lua_State *L)
lua_pushnil(L);
while (lua_next(L, 2) != 0) {
str = lua_tolstring(L, -2, &len);
- memcpy(&ptr[pos], str, len + 1);
lua_pop(L, 1);
- /* table[key] = pos */
+ /* table[key] = encoded_string_pointer */
lua_pushvalue(L, -1);
- lua_pushinteger(L, pos);
- lua_rawset(L, 2);
+ if (len >= (1 << SQDB_LENGTH_BITS)) {
+ lua_pushinteger(L, pos << SQDB_LENGTH_BITS);
+ ptr[pos++] = len;
+ } else {
+ lua_pushinteger(L, (pos << SQDB_LENGTH_BITS) + len);
+ }
+ memcpy(&ptr[pos], str, len);
+ pos += len;
- pos += len + 1;
+ lua_rawset(L, 2);
}
return 0;