From 1eb961114080f37bfb242632d5930e233aeabbdc Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Sun, 8 Dec 2019 01:56:59 +0100 Subject: [PATCH] Do not reparse every note on any change Earlier whenever anything changed we would discard all the Notes + NotesFolders in memory, and reconstruct the hierarchy. This would means Notes which haven't changed at all, still need to parsed all over again. Now we only reload what has actually changed. This should result in a huge performance boost. We still shouldn't be loading everything on boot, but that's a different problem. --- lib/core/notes_folder.dart | 60 ++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/lib/core/notes_folder.dart b/lib/core/notes_folder.dart index 12ac1508..69b44399 100644 --- a/lib/core/notes_folder.dart +++ b/lib/core/notes_folder.dart @@ -8,10 +8,12 @@ import 'note.dart'; import 'note_fs_entity.dart'; class NotesFolder with ChangeNotifier { - NotesFolder parent; - List _entities = []; + final NotesFolder parent; String folderPath; + List _entities = []; + Map _entityMap = {}; + NotesFolder(this.parent, this.folderPath); @override @@ -91,18 +93,25 @@ class NotesFolder with ChangeNotifier { // FIXME: This should not reconstruct the Notes or NotesFolders once constructed. Future load() async { - final dir = Directory(folderPath); - _entities.forEach((e) { - if (e.isFolder) { - e.folder.dispose(); - } else { - e.note.dispose(); - } - }); - _entities = []; + Set pathsFound = {}; + var entitiesAdded = false; + var entitiesRemoved = false; + + final dir = Directory(folderPath); var lister = dir.list(recursive: false, followLinks: false); await for (var fsEntity in lister) { + if (fsEntity is Link) { + continue; + } + + // If already seen before + var existingNoteFSEntity = _entityMap[fsEntity.path]; + if (existingNoteFSEntity != null) { + pathsFound.add(fsEntity.path); + continue; + } + if (fsEntity is Directory) { var subFolder = NotesFolder(this, fsEntity.path); if (subFolder.name.startsWith('.')) { @@ -112,6 +121,10 @@ class NotesFolder with ChangeNotifier { var noteFSEntity = NoteFSEntity(folder: subFolder); _entities.add(noteFSEntity); + _entityMap[fsEntity.path] = noteFSEntity; + + pathsFound.add(fsEntity.path); + entitiesAdded = true; continue; } @@ -123,9 +136,32 @@ class NotesFolder with ChangeNotifier { var noteFSEntity = NoteFSEntity(note: note); _entities.add(noteFSEntity); + _entityMap[fsEntity.path] = noteFSEntity; + + pathsFound.add(fsEntity.path); + entitiesAdded = true; } - if (_entities.isNotEmpty) { + Set pathsRemoved = _entityMap.keys.toSet().difference(pathsFound); + pathsRemoved.forEach((path) { + var e = _entityMap[path]; + assert(e != null); + + if (e.isFolder) { + e.folder.removeListener(_entityChanged); + } else { + e.note.removeListener(_entityChanged); + } + + _entityMap.remove(path); + }); + _entities.removeWhere((e) { + String path = e.isFolder ? e.folder.folderPath : e.note.filePath; + return pathsRemoved.contains(path); + }); + + entitiesRemoved = pathsRemoved.isNotEmpty; + if (entitiesAdded || entitiesRemoved) { notifyListeners(); } }