mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	optimizations to the lazy loading - expanding tree now takes only one request
This commit is contained in:
		| @@ -14,13 +14,10 @@ class NoteShort { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async getBranches() { |     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]) { |         return this.treeCache.getBranches(branchIds); | ||||||
|             branches.push(await this.treeCache.getBranchByChildParent(this.noteId, parentNoteId)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return branches; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     hasChildren() { |     hasChildren() { | ||||||
| @@ -33,13 +30,10 @@ class NoteShort { | |||||||
|             return []; |             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]) { |         return await this.treeCache.getBranches(branchIds); | ||||||
|             branches.push(await this.treeCache.getBranchByChildParent(childNoteId, this.noteId)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return branches; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async __getNotes(noteIds) { |     async __getNotes(noteIds) { | ||||||
| @@ -47,13 +41,7 @@ class NoteShort { | |||||||
|             return []; |             return []; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         const notes = []; |         return this.treeCache.getNotes(noteIds); | ||||||
|  |  | ||||||
|         for (const noteId of noteIds) { |  | ||||||
|             notes.push(await this.treeCache.getNote(noteId)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return notes; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async getParentNotes() { |     async getParentNotes() { | ||||||
|   | |||||||
| @@ -375,7 +375,7 @@ async function loadTree() { | |||||||
|         startNotePath = getNotePathFromAddress(); |         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) { | function collapseTree(node = null) { | ||||||
|   | |||||||
| @@ -5,10 +5,10 @@ import server from "./server.js"; | |||||||
| import treeCache from "./tree_cache.js"; | import treeCache from "./tree_cache.js"; | ||||||
| import messagingService from "./messaging.js"; | import messagingService from "./messaging.js"; | ||||||
|  |  | ||||||
| async function prepareTree(noteRows, branchRows, parentToChildren) { | async function prepareTree(noteRows, branchRows, relations) { | ||||||
|     utils.assertArguments(noteRows, branchRows, parentToChildren); |     utils.assertArguments(noteRows, branchRows, relations); | ||||||
|  |  | ||||||
|     treeCache.load(noteRows, branchRows, parentToChildren); |     treeCache.load(noteRows, branchRows, relations); | ||||||
|  |  | ||||||
|     return await prepareRealBranch(await treeCache.getNote('root')); |     return await prepareRealBranch(await treeCache.getNote('root')); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ import infoService from "./info.js"; | |||||||
| import server from "./server.js"; | import server from "./server.js"; | ||||||
|  |  | ||||||
| class TreeCache { | class TreeCache { | ||||||
|     load(noteRows, branchRows, parentToChildren) { |     load(noteRows, branchRows, relations) { | ||||||
|         this.parents = {}; |         this.parents = {}; | ||||||
|         this.children = {}; |         this.children = {}; | ||||||
|         this.childParentToBranch = {}; |         this.childParentToBranch = {}; | ||||||
| @@ -16,10 +16,10 @@ class TreeCache { | |||||||
|         /** @type {Object.<string, Branch>} */ |         /** @type {Object.<string, Branch>} */ | ||||||
|         this.branches = {}; |         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) { |         for (const noteRow of noteRows) { | ||||||
|             const note = new NoteShort(this, noteRow); |             const note = new NoteShort(this, noteRow); | ||||||
|  |  | ||||||
| @@ -32,26 +32,33 @@ class TreeCache { | |||||||
|             this.addBranch(branch); |             this.addBranch(branch); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         for (const relation of parentToChildren) { |         for (const relation of relations) { | ||||||
|             this.addBranchRelationship(relation.branchId, relation.childNoteId, relation.parentNoteId); |             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 */ |     /** @return NoteShort */ | ||||||
|     async getNote(noteId) { |     async getNote(noteId) { | ||||||
|         if (this.notes[noteId] === undefined) { |         return (await this.getNotes([noteId]))[0]; | ||||||
|             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]; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     addBranch(branch) { |     addBranch(branch) { | ||||||
| @@ -61,12 +68,8 @@ class TreeCache { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     addBranchRelationship(branchId, childNoteId, parentNoteId) { |     addBranchRelationship(branchId, childNoteId, parentNoteId) { | ||||||
|         this.addParentChildRelationship(parentNoteId, childNoteId); |  | ||||||
|  |  | ||||||
|         this.childParentToBranch[childNoteId + '-' + parentNoteId] = branchId; |         this.childParentToBranch[childNoteId + '-' + parentNoteId] = branchId; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     addParentChildRelationship(parentNoteId, childNoteId) { |  | ||||||
|         this.parents[childNoteId] = this.parents[childNoteId] || []; |         this.parents[childNoteId] = this.parents[childNoteId] || []; | ||||||
|  |  | ||||||
|         if (!this.parents[childNoteId].includes(parentNoteId)) { |         if (!this.parents[childNoteId].includes(parentNoteId)) { | ||||||
| @@ -86,36 +89,46 @@ class TreeCache { | |||||||
|         this.addBranch(branch); |         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 */ |     /** @return Branch */ | ||||||
|     async getBranch(branchId) { |     async getBranch(branchId) { | ||||||
|         if (this.branches[branchId] === undefined) { |         return (await this.getBranches([branchId]))[0]; | ||||||
|             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 Branch */ |     /** @return Branch */ | ||||||
|     async getBranchByChildParent(childNoteId, parentNoteId) { |     async getBranchByChildParent(childNoteId, parentNoteId) { | ||||||
|         // this will make sure the note and its relationships are loaded |         const branchId = this.getBranchIdByChildParent(childNoteId, parentNoteId); | ||||||
|         await this.getNote(parentNoteId); |  | ||||||
|  |  | ||||||
|         const key = (childNoteId + '-' + parentNoteId); |         return await this.getBranch(branchId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     getBranchIdByChildParent(childNoteId, parentNoteId) { | ||||||
|  |         const key = childNoteId + '-' + parentNoteId; | ||||||
|         const branchId = this.childParentToBranch[key]; |         const branchId = this.childParentToBranch[key]; | ||||||
|  |  | ||||||
|         if (!branchId) { |         if (!branchId) { | ||||||
|             infoService.throwError("Cannot find branch for child-parent=" + key); |             infoService.throwError("Cannot find branch for child-parent=" + key); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return await this.getBranch(branchId); |         return branchId; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /* Move note from one parent to another. */ |     /* Move note from one parent to another. */ | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ async function getNotes(noteIds) { | |||||||
|     return notes; |     return notes; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function getParentToChildren(noteIds) { | async function getRelations(noteIds) { | ||||||
|     const questionMarks = noteIds.map(() => "?").join(","); |     const questionMarks = noteIds.map(() => "?").join(","); | ||||||
|  |  | ||||||
|     return await sql.getRows(`SELECT branchId, noteId AS 'childNoteId', parentNoteId FROM branches WHERE isDeleted = 0  |     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 notes = await getNotes(noteIds); | ||||||
|  |  | ||||||
|     const parentToChildren = await getParentToChildren(noteIds); |     const relations = await getRelations(noteIds); | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|         startNotePath: await optionService.getOption('startNotePath'), |         startNotePath: await optionService.getOption('startNotePath'), | ||||||
|         branches, |         branches, | ||||||
|         notes, |         notes, | ||||||
|         parentToChildren |         relations | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -64,12 +64,12 @@ async function load(req) { | |||||||
|  |  | ||||||
|     const notes = await getNotes(noteIds); |     const notes = await getNotes(noteIds); | ||||||
|  |  | ||||||
|     const parentToChildren = await getParentToChildren(noteIds); |     const relations = await getRelations(noteIds); | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|         branches, |         branches, | ||||||
|         notes, |         notes, | ||||||
|         parentToChildren |         relations | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user