Skip to content
Snippets Groups Projects
Commit 4db633b8 authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

"Final" optimizations

Use the fastest message base access methods documented.
Cache read/write configs and avoid parsing on read if unchanged.
Make common saves dependent on there being changes.

This is likely as good as it gets (assuming it works)
parent 74403a96
No related branches found
No related tags found
No related merge requests found
...@@ -28,6 +28,7 @@ var line; ...@@ -28,6 +28,7 @@ var line;
var readonly=true; var readonly=true;
var curr_status={exists:0,recent:0,unseen:0,uidnext:0,uidvalidity:0}; var curr_status={exists:0,recent:0,unseen:0,uidnext:0,uidvalidity:0};
var saved_config={mail:{'__config_epoch__':0, scan_ptr:0, subscribed:true, Seen:{}}}; var saved_config={mail:{'__config_epoch__':0, scan_ptr:0, subscribed:true, Seen:{}}};
var loaded_config={};
var scan_ptr; var scan_ptr;
var cfgfile; var cfgfile;
var applied_epoch = -1; var applied_epoch = -1;
...@@ -284,7 +285,7 @@ function send_fetch_response(msgnum, fmat, uid) ...@@ -284,7 +285,7 @@ function send_fetch_response(msgnum, fmat, uid)
*/ */
function get_header() { function get_header() {
if(hdr == undefined) if(hdr == undefined)
hdr=base.get_msg_header(msgnum, /* expand_fields: */false); hdr=base.get_msg_header(true, idx.offset, /* expand_fields: */false);
/* If that didn't work, make up a minimal useless header */ /* If that didn't work, make up a minimal useless header */
if (hdr == undefined) { if (hdr == undefined) {
hdr = Object.create(MsgBase.HeaderPrototype); hdr = Object.create(MsgBase.HeaderPrototype);
...@@ -307,8 +308,12 @@ function send_fetch_response(msgnum, fmat, uid) ...@@ -307,8 +308,12 @@ function send_fetch_response(msgnum, fmat, uid)
} }
function get_rfc822_text() { function get_rfc822_text() {
if(rfc822.text==undefined) if(rfc822.text==undefined) {
rfc822.text=base.get_msg_body(msgnum, true, true, true); if (hdr != undefined)
rfc822.text=base.get_msg_body(hdr, true, true, true);
else
rfc822.text=base.get_msg_body(true, idx.offset, true, true, true);
}
// At least some iPhones in 2024 would not display // At least some iPhones in 2024 would not display
// zero-length messages. Convert them to a single // zero-length messages. Convert them to a single
// space instead. // space instead.
...@@ -347,9 +352,9 @@ function send_fetch_response(msgnum, fmat, uid) ...@@ -347,9 +352,9 @@ function send_fetch_response(msgnum, fmat, uid)
get_header(); get_header();
if(!(hdr.attr & MSG_READ)) { if(!(hdr.attr & MSG_READ)) {
hdr.attr |= MSG_READ; hdr.attr |= MSG_READ;
base.put_msg_header(msgnum, hdr); base.put_msg_header(true, idx.offset, hdr);
index=read_index(base); index=read_index(base);
hdr=base.get_msg_header(msgnum, /* expand_fields: */false); hdr=base.get_msg_header(true, idx.offset, /* expand_fields: */false);
if(hdr.attr & MSG_READ) if(hdr.attr & MSG_READ)
seen_changed=true; seen_changed=true;
} }
...@@ -605,6 +610,7 @@ function send_fetch_response(msgnum, fmat, uid) ...@@ -605,6 +610,7 @@ function send_fetch_response(msgnum, fmat, uid)
resp=resp.replace(/ $/,''); resp=resp.replace(/ $/,'');
resp += ")"; resp += ")";
untagged(resp); untagged(resp);
return seen_changed;
} }
/* /*
...@@ -1637,6 +1643,7 @@ function save_cfg(sub) ...@@ -1637,6 +1643,7 @@ function save_cfg(sub)
function save_one_cfg(osub) function save_one_cfg(osub)
{ {
var new_cfg = {}; var new_cfg = {};
var newfile;
if (osub != locked_code) if (osub != locked_code)
throw new Error('Unlocking ' + osub.toSource() + ' but ' + locked_code.toSource() + ' is locked'); throw new Error('Unlocking ' + osub.toSource() + ' but ' + locked_code.toSource() + ' is locked');
...@@ -1670,7 +1677,9 @@ function save_cfg(sub) ...@@ -1670,7 +1677,9 @@ function save_cfg(sub)
new_cfg.subscribed = true; new_cfg.subscribed = true;
cfgfile.rewind(); cfgfile.rewind();
cfgfile.truncate(); cfgfile.truncate();
cfgfile.write(JSON.stringify(new_cfg)); newfile = JSON.stringify(new_cfg);
cfgfile.write(newfile);
loaded_config[osub] = newfile;
} }
} }
...@@ -1721,6 +1730,7 @@ function open_sub(sub) ...@@ -1721,6 +1730,7 @@ function open_sub(sub)
{ {
var i; var i;
var idx; var idx;
var changed = false;
close_sub(); close_sub();
base=new MsgBase(sub); base=new MsgBase(sub);
...@@ -1735,9 +1745,11 @@ function open_sub(sub) ...@@ -1735,9 +1745,11 @@ function open_sub(sub)
try { try {
read_cfg(); read_cfg();
if (saved_config[sub].scan_ptr > scan_ptr) if (saved_config[sub].scan_ptr > scan_ptr) {
scan_ptr = saved_config[sub].scan_ptr; scan_ptr = saved_config[sub].scan_ptr;
if (!readonly) { changed = true;
}
if (changed && !readonly) {
saved_config[sub].scan_ptr = base.last_msg; saved_config[sub].scan_ptr = base.last_msg;
save_cfg(sub); save_cfg(sub);
} }
...@@ -1872,9 +1884,11 @@ var authenticated_command_handlers = { ...@@ -1872,9 +1884,11 @@ var authenticated_command_handlers = {
lock_cfg(sub); lock_cfg(sub);
try { try {
read_cfg(); read_cfg();
if (!saved_config[sub].subscribed) {
saved_config[sub].subscribed = true; saved_config[sub].subscribed = true;
save_cfg(sub); save_cfg(sub);
} }
}
catch (error) { catch (error) {
unlock_cfg(sub); unlock_cfg(sub);
throw error; throw error;
...@@ -1896,9 +1910,11 @@ var authenticated_command_handlers = { ...@@ -1896,9 +1910,11 @@ var authenticated_command_handlers = {
lock_cfg(sub); lock_cfg(sub);
try { try {
read_cfg(); read_cfg();
if (saved_config[sub].subscribed) {
saved_config[sub].subscribed = false; saved_config[sub].subscribed = false;
save_cfg(sub); save_cfg(sub);
} }
}
catch (error) { catch (error) {
unlock_cfg(sub); unlock_cfg(sub);
throw error; throw error;
...@@ -2043,7 +2059,7 @@ function do_store(seq, uid, item, data) ...@@ -2043,7 +2059,7 @@ function do_store(seq, uid, item, data)
flags=parse_flags(data); flags=parse_flags(data);
for(i in seq) { for(i in seq) {
idx=index.idx[seq[i]]; idx=index.idx[seq[i]];
hdr=base.get_msg_header(seq[i], false); hdr=base.get_msg_header(true, idx.offset, false);
// Hack in our seen flag... // Hack in our seen flag...
if (get_seen_flag(index.code, idx)) { if (get_seen_flag(index.code, idx)) {
idx.attr |= MSG_READ; idx.attr |= MSG_READ;
...@@ -2082,7 +2098,7 @@ function do_store(seq, uid, item, data) ...@@ -2082,7 +2098,7 @@ function do_store(seq, uid, item, data)
hdr.attr ^= chflags.attr; hdr.attr ^= chflags.attr;
hdr.netattr ^= chflags.netattr; hdr.netattr ^= chflags.netattr;
if(!readonly) { if(!readonly) {
base.put_msg_header(seq[i], hdr); base.put_msg_header(true, idx.offset, hdr);
changed=true; changed=true;
} }
} }
...@@ -2142,7 +2158,7 @@ function search_get_headers(msg) ...@@ -2142,7 +2158,7 @@ function search_get_headers(msg)
{ {
if (msg.headers != undefined) if (msg.headers != undefined)
return true; return true;
msg.headers = base.get_msg_header(msg.idx.number, /* expand_fields: */false); msg.headers = base.get_msg_header(true, msg.idx.offset, /* expand_fields: */false);
if (msg.headers == undefined) { if (msg.headers == undefined) {
if (msg.errors === undefined) if (msg.errors === undefined)
msg.errors = []; msg.errors = [];
...@@ -2166,7 +2182,10 @@ function search_get_body(msg) ...@@ -2166,7 +2182,10 @@ function search_get_body(msg)
{ {
if (msg.body != undefined) if (msg.body != undefined)
return; return;
msg.body = base.get_msg_body(msg.idx.number, true, true, true).toUpperCase(); if (msg.headers != undefined)
msg.body = base.get_msg_body(msg.headers, true, true, true).toUpperCase();
else
msg.body = base.get_msg_body(true, msg.idx.offset, true, true, true).toUpperCase();
if (msg.body == undefined) { if (msg.body == undefined) {
if (msg.errors === undefined) if (msg.errors === undefined)
msg.errors = []; msg.errors = [];
...@@ -2896,7 +2915,7 @@ function do_search(args, uid) ...@@ -2896,7 +2915,7 @@ function do_search(args, uid)
continue; continue;
} }
if(search_set.hdr.length > 0 || search_set.all.length > 0) { if(search_set.hdr.length > 0 || search_set.all.length > 0) {
hdr=base.get_msg_header(idx.number, /* expand_fields: */false); hdr=base.get_msg_header(true, idx.offset, /* expand_fields: */false);
if(hdr==null) { if(hdr==null) {
log("Unable to get header for idx.number"); log("Unable to get header for idx.number");
continue; continue;
...@@ -2909,7 +2928,7 @@ function do_search(args, uid) ...@@ -2909,7 +2928,7 @@ function do_search(args, uid)
continue; continue;
} }
if(search_set.body.length > 0 || search_set.all.length > 0) { if(search_set.body.length > 0 || search_set.all.length > 0) {
body=base.get_msg_body(idx.number,true,true,true).toUpperCase(); body=base.get_msg_body(true, idx.offset,true,true,true).toUpperCase();
if(body==null) { if(body==null) {
log("Unable to get body for idx.number"); log("Unable to get body for idx.number");
continue; continue;
...@@ -3007,15 +3026,18 @@ var selected_command_handlers = { ...@@ -3007,15 +3026,18 @@ var selected_command_handlers = {
var seq=parse_seq_set(args[1],false); var seq=parse_seq_set(args[1],false);
var data_items=parse_data_items(args[2]); var data_items=parse_data_items(args[2]);
var i; var i;
var need_save = false;
lock_cfg(get_base_code(base)); lock_cfg(get_base_code(base));
try { try {
read_cfg(); read_cfg();
for(i in seq) { for(i in seq) {
send_fetch_response(seq[i], data_items, false); if (send_fetch_response(seq[i], data_items, false))
need_save = true;
if (!client.socket.is_connected) if (!client.socket.is_connected)
break; break;
} }
if (need_save)
save_cfg(get_base_code(base)); save_cfg(get_base_code(base));
} }
catch (error) { catch (error) {
...@@ -3060,6 +3082,7 @@ var selected_command_handlers = { ...@@ -3060,6 +3082,7 @@ var selected_command_handlers = {
var data_items; var data_items;
var data; var data;
var i; var i;
var need_save = false;
switch(cmd.toUpperCase()) { switch(cmd.toUpperCase()) {
case 'FETCH': case 'FETCH':
...@@ -3073,10 +3096,12 @@ var selected_command_handlers = { ...@@ -3073,10 +3096,12 @@ var selected_command_handlers = {
try { try {
read_cfg(); read_cfg();
for(i in seq) { for(i in seq) {
send_fetch_response(seq[i], data_items, true); if (send_fetch_response(seq[i], data_items, true))
need_save = true;
if (!client.socket.is_connected) if (!client.socket.is_connected)
break; break;
} }
if (need_save)
save_cfg(get_base_code(base)); save_cfg(get_base_code(base));
} }
catch (error) { catch (error) {
...@@ -3292,6 +3317,7 @@ function read_cfg() ...@@ -3292,6 +3317,7 @@ function read_cfg()
else else
newfile = {subscribed:false, __config_epoch__: 0, scan_ptr:0}; newfile = {subscribed:false, __config_epoch__: 0, scan_ptr:0};
} }
if (loaded_config[locked_code] !== newfile) {
if (newfile.__config_epoch__ !== saved_config[locked_code].__config_epoch__) { if (newfile.__config_epoch__ !== saved_config[locked_code].__config_epoch__) {
saved_config.__config_epoch__ = newfile.__config_epoch__; saved_config.__config_epoch__ = newfile.__config_epoch__;
saved_config[locked_code] = {}; saved_config[locked_code] = {};
...@@ -3321,6 +3347,8 @@ function read_cfg() ...@@ -3321,6 +3347,8 @@ function read_cfg()
} }
} }
} }
loaded_config[locked_code] = newfile;
}
if(saved_config[locked_code].Seen==undefined) if(saved_config[locked_code].Seen==undefined)
saved_config[locked_code].Seen={}; saved_config[locked_code].Seen={};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment