diff --git a/apps/cory/index.json b/apps/cory/index.json index a4f0b98f..f922c445 100644 --- a/apps/cory/index.json +++ b/apps/cory/index.json @@ -1 +1 @@ -{"type":"tildefriends-app","files":{"app.js":"&ZPex8H1nwzrEHSgi5SkvfTlSzSIutT6iHOY08LWkwZg=.sha256","index.html":"&H2L4kR9xDS6oS7EDpesDCDB3JXDjcLTBg9XoR2mZaZw=.sha256","vue-material.js":"&K5cdLqXYCENPak/TCINHQhyJhpS4G9DlZHGwoh/LF2g=.sha256","tf-user.js":"&DdJwZYEo7AqFyutYMvEjykoVXxdHVog0UXye6Sbo0TU=.sha256","tf-message.js":"&3dPiSNYjoJE3zn1oTT1SBhbvkW9MHr7ZUDxUJiBI1Ss=.sha256","tf.js":"&RAwMitnSkY+F3lDbyXAvWYT1QOX0lUsNZC+JE7KW4JM=.sha256","commonmark.min.js":"&EP0OeR9zyLwZannz+0ga4s9AGES2RLvvIIQYHqqV6+k=.sha256","vue.js":"&g1wvA+yHl1sVC+eufTsg9If7ZeVyMTBU+h0tks7ZNzE=.sha256","vue-material-theme-default-dark.css":"&RP2nr+2CR18BpHHw5ST9a5GJUCOG9n0G2kuGkcQioWE=.sha256","vue-material.min.css":"&kGbUM2QgFSyHZRzqQb0b+0S3EVIlZ0AXpdiAVjIhou8=.sha256","roboto.css":"&jJv43Om673mQO5JK0jj7714s5E+5Yrf82H6LcDx7wUs=.sha256","material-icons.css":"&a28PdcVvgq/DxyIvJAx/e+ZOEtOuHnr3kjLWKyzH11M=.sha256","tf-shared.js":"&+qPP3g4CAUlkt8K4iBCZ+F5Fy6N7fu6MggvSVss2juE=.sha256"}} \ No newline at end of file +{"type":"tildefriends-app","files":{"app.js":"&OOcUHSIAA6CR2dYSv2BwOMBZ1hjFg+PJZPABhZMe1Gc=.sha256","index.html":"&H2L4kR9xDS6oS7EDpesDCDB3JXDjcLTBg9XoR2mZaZw=.sha256","vue-material.js":"&K5cdLqXYCENPak/TCINHQhyJhpS4G9DlZHGwoh/LF2g=.sha256","tf-user.js":"&DdJwZYEo7AqFyutYMvEjykoVXxdHVog0UXye6Sbo0TU=.sha256","tf-message.js":"&3dPiSNYjoJE3zn1oTT1SBhbvkW9MHr7ZUDxUJiBI1Ss=.sha256","tf.js":"&RAwMitnSkY+F3lDbyXAvWYT1QOX0lUsNZC+JE7KW4JM=.sha256","commonmark.min.js":"&EP0OeR9zyLwZannz+0ga4s9AGES2RLvvIIQYHqqV6+k=.sha256","vue.js":"&g1wvA+yHl1sVC+eufTsg9If7ZeVyMTBU+h0tks7ZNzE=.sha256","vue-material-theme-default-dark.css":"&RP2nr+2CR18BpHHw5ST9a5GJUCOG9n0G2kuGkcQioWE=.sha256","vue-material.min.css":"&kGbUM2QgFSyHZRzqQb0b+0S3EVIlZ0AXpdiAVjIhou8=.sha256","roboto.css":"&jJv43Om673mQO5JK0jj7714s5E+5Yrf82H6LcDx7wUs=.sha256","material-icons.css":"&a28PdcVvgq/DxyIvJAx/e+ZOEtOuHnr3kjLWKyzH11M=.sha256","tf-shared.js":"&+qPP3g4CAUlkt8K4iBCZ+F5Fy6N7fu6MggvSVss2juE=.sha256"}} \ No newline at end of file diff --git a/apps/cory/index/app.js b/apps/cory/index/app.js index 1594653d..0bf4367a 100644 --- a/apps/cory/index/app.js +++ b/apps/cory/index/app.js @@ -7,8 +7,9 @@ var g_ready = false; var g_selected = null; var g_following_cache = {}; -var g_followers_cache = {}; var g_following_deep_cache = {}; +var g_stats = {}; +var g_sequence = {}; async function following(db, id) { if (g_following_cache[id]) { @@ -41,6 +42,7 @@ async function following(db, id) { f.users.delete(row.contact); } f.sequence = row.sequence; + g_sequence[id] = row.sequence; }); var as_set = f.users; f.users = Array.from(f.users).sort(); @@ -76,34 +78,38 @@ async function getAbout(db, id) { if (!f || f.version != k_version) { f = {about: {}, sequence: 0, version: k_version}; } - await ssb.sqlStream( - "SELECT "+ - " sequence, "+ - " content "+ - "FROM messages "+ - "WHERE "+ - " sequence > ?1 AND "+ - " author = ?2 AND "+ - " json_extract(content, '$.type') = 'about' AND "+ - " json_extract(content, '$.about') = author "+ - "UNION SELECT MAX(sequence) as sequence, NULL FROM messages WHERE author = ?2 "+ - "ORDER BY sequence", - [f.sequence, id], - function(row) { - f.sequence = row.sequence; - if (row.content) { - var about = {}; - try { - about = JSON.parse(row.content); - } catch { + if (g_sequence[id] > f.sequence) { + await ssb.sqlStream( + "SELECT "+ + " sequence, "+ + " content "+ + "FROM messages "+ + "WHERE "+ + " author = ?1 AND "+ + " sequence > ?2 AND "+ + " json_extract(content, '$.type') = 'about' AND "+ + " json_extract(content, '$.about') = ?1 "+ + "UNION SELECT MAX(sequence) as sequence, NULL FROM messages WHERE author = ?1 "+ + "ORDER BY sequence", + [id, f.sequence], + function(row) { + g_stats.rows_read = (g_stats.rows_read || 0) + 1; + f.sequence = row.sequence; + if (row.content) { + var about = {}; + try { + about = JSON.parse(row.content); + } catch { + } + delete about.about; + delete about.type; + f.about = Object.assign(f.about, about); } - delete about.about; - delete about.type; - f.about = Object.assign(f.about, about); - } - }); + }); + } var j = JSON.stringify(f); if (o != j) { + g_stats.rows_written = (g_stats.rows_written || 0) + 1; await db.set(id + ":about", j); } return f.about; @@ -250,27 +256,29 @@ async function getVotes(db, id) { if (!f || f.version != k_version) { f = {votes: [], sequence: 0, version: k_version}; } - await ssb.sqlStream( - "SELECT "+ - " author, "+ - " id, "+ - " sequence, "+ - " timestamp, "+ - " content "+ - "FROM messages "+ - "WHERE "+ - " author = ? AND "+ - " sequence > ? AND "+ - " json_extract(content, '$.type') = 'vote' "+ - "UNION SELECT NULL, NULL, MAX(sequence), NULL, NULL FROM messages WHERE author = ? "+ - "ORDER BY sequence DESC LIMIT ?", - [f.sequence, id, id, k_votes_max], - function(row) { - if (row.id) { - votes.push(row); - } - f.sequence = Math.max(f.sequence, row.sequence); - }); + if (g_sequence[id] > f.sequence) { + await ssb.sqlStream( + "SELECT "+ + " author, "+ + " id, "+ + " sequence, "+ + " timestamp, "+ + " content "+ + "FROM messages "+ + "WHERE "+ + " author = ? AND "+ + " sequence > ? AND "+ + " json_extract(content, '$.type') = 'vote' "+ + "UNION SELECT NULL, NULL, MAX(sequence), NULL, NULL FROM messages WHERE author = ? "+ + "ORDER BY sequence DESC LIMIT ?", + [f.sequence, id, id, k_votes_max], + function(row) { + if (row.id) { + votes.push(row); + } + f.sequence = Math.max(f.sequence, row.sequence); + }); + } f.votes = [].concat(votes, f.votes).slice(0, k_votes_max); var j = JSON.stringify(f); if (o != j) { @@ -308,8 +316,8 @@ async function refresh(selected) { var timing = []; timing.push({name: 'start', time: new Date()}); g_following_cache = {}; - g_followers_cache = {}; g_following_deep_cache = {}; + g_sequence = {}; await app.postMessage({clear: true}); var whoami = await ssb.whoami(); var db = await database("ssb"); @@ -353,13 +361,24 @@ async function refresh(selected) { timing.push({name: 'get_root_posts', time: new Date()}); await Promise.all(all_posts.map(x => app.postMessage({message: x}))); timing.push({name: 'send_posts', time: new Date()}); - await Promise.all(all_followed.map(id => getAbout(db, id).then(results => app.postMessage({user: {user: id, about: results}})))); + await Promise.all(all_followed.map(id => getAbout(db, id).then(results => Object.keys(results).length ? app.postMessage({user: {user: id, about: results}}) : null))); timing.push({name: 'about', time: new Date()}); await Promise.all(all_followed.map(id => getVotes(db, id).then(results => results.length ? app.postMessage({votes: results}) : null))); timing.push({name: 'votes', time: new Date()}); - await Promise.all(all_followed.map(id => following(db, id).then(results => app.postMessage({following: {id: id, users: [...results]}})))); + await all_followed.map( + id => app.postMessage( + { + following: { + id: id, + users: [...(g_following_cache[id] || [])], + } + } + ) + ); timing.push({name: 'following', time: new Date()}); + print(JSON.stringify(g_stats)); + var times = {}; var previous = null; for (let t of timing) { diff --git a/src/ssb.db.c b/src/ssb.db.c index ec76e601..41bcb20d 100644 --- a/src/ssb.db.c +++ b/src/ssb.db.c @@ -30,8 +30,6 @@ void tf_ssb_db_init(tf_ssb_t* ssb) sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_id_index ON messages (author, id)", NULL, NULL, NULL); sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_sequence_index ON messages (author, sequence)", NULL, NULL, NULL); sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_timestamp_index ON messages (author, timestamp)", NULL, NULL, NULL); - sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_type_sequence_index ON messages (author, json_extract(content, '$.type'), sequence)", NULL, NULL, NULL); - sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_type_timestamp_index ON messages (author, json_extract(content, '$.type'), timestamp)", NULL, NULL, NULL); sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS blobs (" " id TEXT PRIMARY KEY,"