caching initial noteset to improve search times

This commit is contained in:
zadam 2021-10-06 19:59:29 +02:00
parent 17fe9a6a1b
commit df8706026e
6 changed files with 40 additions and 12 deletions

View File

@ -3,6 +3,7 @@
const sql = require("../services/sql.js"); const sql = require("../services/sql.js");
const NoteRevision = require("./entities/note_revision.js"); const NoteRevision = require("./entities/note_revision.js");
const RecentNote = require("./entities/recent_note.js"); const RecentNote = require("./entities/recent_note.js");
const NoteSet = require("../services/search/note_set");
class Becca { class Becca {
constructor() { constructor() {
@ -51,6 +52,11 @@ class Becca {
} }
} }
addNote(noteId, note) {
this.notes[noteId] = note;
this.dirtyNoteSetCache();
}
getNote(noteId) { getNote(noteId) {
return this.notes[noteId]; return this.notes[noteId];
} }
@ -127,6 +133,32 @@ class Becca {
return rows.map(row => new NoteRevision(row)); return rows.map(row => new NoteRevision(row));
} }
/** Should be called when the set of all non-skeleton notes changes (added/removed) */
dirtyNoteSetCache() {
this.allNoteSetCache = null;
}
getAllNoteSet() {
// caching this since it takes 10s of milliseconds to fill this initial NoteSet for many notes
if (!this.allNoteSetCache) {
const allNotes = [];
for (const noteId in becca.notes) {
const note = becca.notes[noteId];
// in the process of loading data sometimes we create "skeleton" note instances which are expected to be filled later
// in case of inconsistent data this might not work and search will then crash on these
if (note.type !== undefined) {
allNotes.push(note);
}
}
this.allNoteSet = new NoteSet(allNotes);
}
return this.allNoteSet;
}
} }
const becca = new Becca(); const becca = new Becca();

View File

@ -113,6 +113,8 @@ eventService.subscribe([eventService.ENTITY_DELETED, eventService.ENTITY_DELETE_
function noteDeleted(noteId) { function noteDeleted(noteId) {
delete becca.notes[noteId]; delete becca.notes[noteId];
becca.dirtyNoteSetCache();
} }
function branchDeleted(branchId) { function branchDeleted(branchId) {

View File

@ -63,7 +63,7 @@ class Attribute extends AbstractEntity {
if (!(this.noteId in this.becca.notes)) { if (!(this.noteId in this.becca.notes)) {
// entities can come out of order in sync, create skeleton which will be filled later // entities can come out of order in sync, create skeleton which will be filled later
this.becca.notes[this.noteId] = new Note({noteId: this.noteId}); this.becca.addNote(this.noteId, new Note({noteId: this.noteId}));
} }
this.becca.notes[this.noteId].ownedAttributes.push(this); this.becca.notes[this.noteId].ownedAttributes.push(this);

View File

@ -81,7 +81,7 @@ class Branch extends AbstractEntity {
get childNote() { get childNote() {
if (!(this.noteId in this.becca.notes)) { if (!(this.noteId in this.becca.notes)) {
// entities can come out of order in sync, create skeleton which will be filled later // entities can come out of order in sync, create skeleton which will be filled later
this.becca.notes[this.noteId] = new Note({noteId: this.noteId}); this.becca.addNote(this.noteId, new Note({noteId: this.noteId}));
} }
return this.becca.notes[this.noteId]; return this.becca.notes[this.noteId];
@ -95,7 +95,7 @@ class Branch extends AbstractEntity {
get parentNote() { get parentNote() {
if (!(this.parentNoteId in this.becca.notes)) { if (!(this.parentNoteId in this.becca.notes)) {
// entities can come out of order in sync, create skeleton which will be filled later // entities can come out of order in sync, create skeleton which will be filled later
this.becca.notes[this.parentNoteId] = new Note({noteId: this.parentNoteId}); this.becca.addNote(this.parentNoteId, new Note({noteId: this.parentNoteId}));
} }
return this.becca.notes[this.parentNoteId]; return this.becca.notes[this.parentNoteId];

View File

@ -95,7 +95,7 @@ class Note extends AbstractEntity {
/** @param {Attribute[]} */ /** @param {Attribute[]} */
this.targetRelations = []; this.targetRelations = [];
this.becca.notes[this.noteId] = this; this.becca.addNote(this.noteId, this);
/** @param {Note[]|null} */ /** @param {Note[]|null} */
this.ancestorCache = null; this.ancestorCache = null;
@ -1087,7 +1087,7 @@ class Note extends AbstractEntity {
beforeSaving() { beforeSaving() {
super.beforeSaving(); super.beforeSaving();
this.becca.notes[this.noteId] = this; this.becca.addNote(this.noteId, this);
this.dateModified = dateUtils.localNowDateTime(); this.dateModified = dateUtils.localNowDateTime();
this.utcDateModified = dateUtils.utcNowDateTime(); this.utcDateModified = dateUtils.utcNowDateTime();

View File

@ -64,17 +64,11 @@ function loadNeededInfoFromDatabase() {
* @return {SearchResult[]} * @return {SearchResult[]}
*/ */
function findResultsWithExpression(expression, searchContext) { function findResultsWithExpression(expression, searchContext) {
let allNotes = Object.values(becca.notes);
if (searchContext.dbLoadNeeded) { if (searchContext.dbLoadNeeded) {
loadNeededInfoFromDatabase(); loadNeededInfoFromDatabase();
} }
// in the process of loading data sometimes we create "skeleton" note instances which are expected to be filled later const allNoteSet = becca.getAllNoteSet();
// in case of inconsistent data this might not work and search will then crash on these
allNotes = allNotes.filter(note => note.type !== undefined);
const allNoteSet = new NoteSet(allNotes);
const executionContext = { const executionContext = {
noteIdToNotePath: {} noteIdToNotePath: {}