From 99df0ed4b886d71c1d60be602aae78411ca576ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net> Date: Mon, 11 Nov 2024 02:34:49 -0500 Subject: [PATCH] Optimize read/save of Seen config Previously, this uses INI format files, with ini file accessors to read and save this file. Now it just dumps a JSON file in and slurps it out. This saves about 0.4s/msg on my system when reading headers. --- exec/imapservice.js | 102 ++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 27 deletions(-) diff --git a/exec/imapservice.js b/exec/imapservice.js index 946448ba72..e520066998 100644 --- a/exec/imapservice.js +++ b/exec/imapservice.js @@ -295,10 +295,11 @@ function send_fetch_response(msgnum, fmat, uid) saved_config[index.code] = {}; if(saved_config[index.code].Seen == undefined) saved_config[index.code].Seen = {}; - if(saved_config[index.code].Seen[msgnum] != 1) + if(saved_config[index.code].Seen[msgnum] != 1) { seen_changed=true; - saved_config[index.code].Seen[msgnum]=1; - save_cfg(false); + saved_config[index.code].Seen[msgnum]=1; + save_cfg(false); + } apply_seen(index); unlock_cfg(); idx.attr |= MSG_READ; @@ -1369,6 +1370,17 @@ function open_cfg(usr) tagged(tag, "NO", "Can't open imap state file"); return false; } + lock_cfg(); + // Check if it's the old INI format... + if (cfgfile.length > 0) { + var ch = cfgfile.read(1); + if (ch != '{') { + // INI file, convert... + read_old_cfg(); + save_cfg(); + } + } + unlock_cfg(); return true; } @@ -1457,31 +1469,29 @@ function save_cfg(lck) var b; var s; var scpy; + var new_cfg = {}; if(user.number > 0) { - if (lck) - lock_cfg(); - cfgfile.rewind(); - for(sub in saved_config) { - s = undefined; + for (sub in saved_config) { + scpy = undefined; if (saved_config[sub].Seen !== undefined) { scpy = JSON.parse(JSON.stringify(saved_config[sub].Seen)); - s=saved_config[sub].Seen; - delete saved_config[sub].Seen; } - cfgfile.iniSetObject(sub,saved_config[sub]); - if(s != undefined) { - // First, try any "binary" Seen compression - b = binify(s); - cfgfile.iniRemoveSection(sub+'.bseen'); - if (b != undefined) - cfgfile.iniSetObject(sub+'.bseen',b); - cfgfile.iniRemoveSection(sub+'.seen'); - if (Object.keys(s).length > 0) - cfgfile.iniSetObject(sub+'.seen',s); - saved_config[sub].Seen=scpy; + if(scpy !== undefined) { + var bin = binify(scpy); + if (bin !== undefined || scpy !== undefined) { + new_cfg[sub] = {}; + } + if (bin !== undefined) + new_cfg[sub].bseen = bin; + new_cfg[sub].seen = scpy; } } + if (lck) + lock_cfg(); + cfgfile.rewind(); + cfgfile.truncate(); + cfgfile.write(JSON.stringify(new_cfg)); cfgfile.flush(); if (lck) unlock_cfg(); @@ -2275,7 +2285,7 @@ var selected_command_handlers = { }, }; -function read_cfg(sub, lck) +function read_old_cfg() { var secs; var sec; @@ -2291,11 +2301,6 @@ function read_cfg(sub, lck) var bit; var asc; - if(saved_config[sub]==undefined) - saved_config[sub]={}; - - if (lck) - lock_cfg(); cfgfile.rewind(); secs=cfgfile.iniGetSections(); for(sec in secs) { @@ -2345,6 +2350,49 @@ function read_cfg(sub, lck) } } } +} + +function read_cfg(sub, lck) +{ + var basemsg; + var bstr; + var newsub; + var newfile; + var i; + var byte; + var asc; + var bit; + + if (lck) + lock_cfg(); + if(saved_config[sub]==undefined) + saved_config[sub]={}; + + cfgfile.rewind(); + newfile = JSON.parse(cfgfile.read()); + for (newsub in newfile) { + saved_config[newsub] = {}; + if (newfile[newsub].hasOwnProperty('seen')) + saved_config[newsub].Seen = newfile[newsub].seen; + else + saved_config[newsub].Seen = newfile[newsub].seen = {}; + if (newfile[newsub].hasOwnProperty('bseen')) { + for (i in newfile[newsub].bseen) { + basemsg = parseInt(i, 10); + bstr = base64_decode(newfile[newsub].bseen[i]); + for (byte = 0; byte < bstr.length; byte++) { + asc = ascii(bstr[byte]); + if (asc == 0) + continue; + for (bit=0; bit<8; bit++) { + if (asc & (1<<bit)) + saved_config[newsub].Seen[basemsg+(byte*8+bit)]=1; + } + } + } + } + } + if (lck) unlock_cfg(); -- GitLab