From b4005a7ffe0a5ad7e388cfcd9e116015ea2f0f19 Mon Sep 17 00:00:00 2001 From: azivner Date: Mon, 16 Apr 2018 23:13:33 -0400 Subject: [PATCH] optimizations to the lazy loading - expanding tree now takes only one request --- src/public/javascripts/entities/note_short.js | 26 ++---- src/public/javascripts/services/tree.js | 2 +- .../javascripts/services/tree_builder.js | 6 +- src/public/javascripts/services/tree_cache.js | 89 +++++++++++-------- src/routes/api/tree.js | 10 +-- 5 files changed, 67 insertions(+), 66 deletions(-) diff --git a/src/public/javascripts/entities/note_short.js b/src/public/javascripts/entities/note_short.js index ac9346cec..f98cd5cc0 100644 --- a/src/public/javascripts/entities/note_short.js +++ b/src/public/javascripts/entities/note_short.js @@ -14,13 +14,10 @@ class NoteShort { } async getBranches() { - const branches = []; + const branchIds = this.treeCache.parents[this.noteId].map( + parentNoteId => this.treeCache.getBranchIdByChildParent(this.noteId, parentNoteId)); - for (const parentNoteId of this.treeCache.parents[this.noteId]) { - branches.push(await this.treeCache.getBranchByChildParent(this.noteId, parentNoteId)); - } - - return branches; + return this.treeCache.getBranches(branchIds); } hasChildren() { @@ -33,13 +30,10 @@ class NoteShort { return []; } - const branches = []; + const branchIds = this.treeCache.children[this.noteId].map( + childNoteId => this.treeCache.getBranchIdByChildParent(childNoteId, this.noteId)); - for (const childNoteId of this.treeCache.children[this.noteId]) { - branches.push(await this.treeCache.getBranchByChildParent(childNoteId, this.noteId)); - } - - return branches; + return await this.treeCache.getBranches(branchIds); } async __getNotes(noteIds) { @@ -47,13 +41,7 @@ class NoteShort { return []; } - const notes = []; - - for (const noteId of noteIds) { - notes.push(await this.treeCache.getNote(noteId)); - } - - return notes; + return this.treeCache.getNotes(noteIds); } async getParentNotes() { diff --git a/src/public/javascripts/services/tree.js b/src/public/javascripts/services/tree.js index a89e9c6df..0ead17615 100644 --- a/src/public/javascripts/services/tree.js +++ b/src/public/javascripts/services/tree.js @@ -375,7 +375,7 @@ async function loadTree() { startNotePath = getNotePathFromAddress(); } - return await treeBuilder.prepareTree(resp.notes, resp.branches, resp.parentToChildren); + return await treeBuilder.prepareTree(resp.notes, resp.branches, resp.relations); } function collapseTree(node = null) { diff --git a/src/public/javascripts/services/tree_builder.js b/src/public/javascripts/services/tree_builder.js index 2631cd68d..2c9515323 100644 --- a/src/public/javascripts/services/tree_builder.js +++ b/src/public/javascripts/services/tree_builder.js @@ -5,10 +5,10 @@ import server from "./server.js"; import treeCache from "./tree_cache.js"; import messagingService from "./messaging.js"; -async function prepareTree(noteRows, branchRows, parentToChildren) { - utils.assertArguments(noteRows, branchRows, parentToChildren); +async function prepareTree(noteRows, branchRows, relations) { + utils.assertArguments(noteRows, branchRows, relations); - treeCache.load(noteRows, branchRows, parentToChildren); + treeCache.load(noteRows, branchRows, relations); return await prepareRealBranch(await treeCache.getNote('root')); } diff --git a/src/public/javascripts/services/tree_cache.js b/src/public/javascripts/services/tree_cache.js index d3f9aca48..4bd29030b 100644 --- a/src/public/javascripts/services/tree_cache.js +++ b/src/public/javascripts/services/tree_cache.js @@ -5,7 +5,7 @@ import infoService from "./info.js"; import server from "./server.js"; class TreeCache { - load(noteRows, branchRows, parentToChildren) { + load(noteRows, branchRows, relations) { this.parents = {}; this.children = {}; this.childParentToBranch = {}; @@ -16,10 +16,10 @@ class TreeCache { /** @type {Object.} */ this.branches = {}; - this.addResp(noteRows, branchRows, parentToChildren); + this.addResp(noteRows, branchRows, relations); } - addResp(noteRows, branchRows, parentToChildren) { + addResp(noteRows, branchRows, relations) { for (const noteRow of noteRows) { const note = new NoteShort(this, noteRow); @@ -32,26 +32,33 @@ class TreeCache { this.addBranch(branch); } - for (const relation of parentToChildren) { + for (const relation of relations) { this.addBranchRelationship(relation.branchId, relation.childNoteId, relation.parentNoteId); } } + async getNotes(noteIds) { + const missingNoteIds = noteIds.filter(noteId => this.notes[noteId] === undefined); + + if (missingNoteIds.length > 0) { + const resp = await server.post('tree/load', { noteIds: missingNoteIds }); + + this.addResp(resp.notes, resp.branches, resp.relations); + } + + return noteIds.map(noteId => { + if (!this.notes[noteId]) { + throw new Error(`Can't find note ${noteId}`); + } + else { + return this.notes[noteId]; + } + }); + } + /** @return NoteShort */ async getNote(noteId) { - if (this.notes[noteId] === undefined) { - const resp = await server.post('tree/load', { - noteIds: [noteId] - }); - - this.addResp(resp.notes, resp.branches, resp.parentToChildren); - } - - if (!this.notes[noteId]) { - throw new Error(`Can't find note ${noteId}`); - } - - return this.notes[noteId]; + return (await this.getNotes([noteId]))[0]; } addBranch(branch) { @@ -61,12 +68,8 @@ class TreeCache { } addBranchRelationship(branchId, childNoteId, parentNoteId) { - this.addParentChildRelationship(parentNoteId, childNoteId); - this.childParentToBranch[childNoteId + '-' + parentNoteId] = branchId; - } - addParentChildRelationship(parentNoteId, childNoteId) { this.parents[childNoteId] = this.parents[childNoteId] || []; if (!this.parents[childNoteId].includes(parentNoteId)) { @@ -86,36 +89,46 @@ class TreeCache { this.addBranch(branch); } + async getBranches(branchIds) { + const missingBranchIds = branchIds.filter(branchId => this.branches[branchId] === undefined); + + if (missingBranchIds.length > 0) { + const resp = await server.post('tree/load', { branchIds: branchIds }); + + this.addResp(resp.notes, resp.branches, resp.relations); + } + + return branchIds.map(branchId => { + if (!this.branches[branchId]) { + throw new Error(`Can't find branch ${branchId}`); + } + else { + return this.branches[branchId]; + } + }); + } + /** @return Branch */ async getBranch(branchId) { - if (this.branches[branchId] === undefined) { - const resp = await server.post('tree/load', { - branchIds: [branchId] - }); - - this.addResp(resp.notes, resp.branches, resp.parentToChildren); - } - - if (!this.branches[branchId]) { - throw new Error(`Can't find branch ${branchId}`); - } - - return this.branches[branchId]; + return (await this.getBranches([branchId]))[0]; } /** @return Branch */ async getBranchByChildParent(childNoteId, parentNoteId) { - // this will make sure the note and its relationships are loaded - await this.getNote(parentNoteId); + const branchId = this.getBranchIdByChildParent(childNoteId, parentNoteId); - const key = (childNoteId + '-' + parentNoteId); + return await this.getBranch(branchId); + } + + getBranchIdByChildParent(childNoteId, parentNoteId) { + const key = childNoteId + '-' + parentNoteId; const branchId = this.childParentToBranch[key]; if (!branchId) { infoService.throwError("Cannot find branch for child-parent=" + key); } - return await this.getBranch(branchId); + return branchId; } /* Move note from one parent to another. */ diff --git a/src/routes/api/tree.js b/src/routes/api/tree.js index 0aa95dd5c..98ed5afd8 100644 --- a/src/routes/api/tree.js +++ b/src/routes/api/tree.js @@ -17,7 +17,7 @@ async function getNotes(noteIds) { return notes; } -async function getParentToChildren(noteIds) { +async function getRelations(noteIds) { const questionMarks = noteIds.map(() => "?").join(","); return await sql.getRows(`SELECT branchId, noteId AS 'childNoteId', parentNoteId FROM branches WHERE isDeleted = 0 @@ -40,13 +40,13 @@ async function getTree() { const notes = await getNotes(noteIds); - const parentToChildren = await getParentToChildren(noteIds); + const relations = await getRelations(noteIds); return { startNotePath: await optionService.getOption('startNotePath'), branches, notes, - parentToChildren + relations }; } @@ -64,12 +64,12 @@ async function load(req) { const notes = await getNotes(noteIds); - const parentToChildren = await getParentToChildren(noteIds); + const relations = await getRelations(noteIds); return { branches, notes, - parentToChildren + relations }; }