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 NoteRevision = require("./entities/note_revision.js");
const RecentNote = require("./entities/recent_note.js");
const NoteSet = require("../services/search/note_set");
class Becca {
constructor() {
@ -51,6 +52,11 @@ class Becca {
}
}
addNote(noteId, note) {
this.notes[noteId] = note;
this.dirtyNoteSetCache();
}
getNote(noteId) {
return this.notes[noteId];
}
@ -127,6 +133,32 @@ class Becca {
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();

View file

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

View file

@ -63,7 +63,7 @@ class Attribute extends AbstractEntity {
if (!(this.noteId in this.becca.notes)) {
// 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);

View file

@ -81,7 +81,7 @@ class Branch extends AbstractEntity {
get childNote() {
if (!(this.noteId in this.becca.notes)) {
// 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];
@ -95,7 +95,7 @@ class Branch extends AbstractEntity {
get parentNote() {
if (!(this.parentNoteId in this.becca.notes)) {
// 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];

View file

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

View file

@ -64,17 +64,11 @@ function loadNeededInfoFromDatabase() {
* @return {SearchResult[]}
*/
function findResultsWithExpression(expression, searchContext) {
let allNotes = Object.values(becca.notes);
if (searchContext.dbLoadNeeded) {
loadNeededInfoFromDatabase();
}
// 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
allNotes = allNotes.filter(note => note.type !== undefined);
const allNoteSet = new NoteSet(allNotes);
const allNoteSet = becca.getAllNoteSet();
const executionContext = {
noteIdToNotePath: {}