perf: O(1) title lookup in markdown import merge (#13117)

collectDocumentsAndAttachments merged a folder/file sharing a title by scanning
the sibling list with out.find(d => d.title === child.title) once per child —
O(n²) over the number of siblings in one directory, which for a flat import can
be large. Index the siblings by title in a Map and look up in O(1). First
occurrence wins, matching find; the merge still mutates the same object.
This commit is contained in:
yoominho
2026-07-29 23:04:08 -04:00
committed by GitHub
parent d54281cdb6
commit 647352f6a0
+12 -1
View File
@@ -665,6 +665,16 @@ export default class MarkdownAPIImportTask extends APIImportTask<Markdown> {
manifest: MarkdownAttachmentManifestItem[];
markdownByNode: Map<ZipTreeNode, string>;
}): void {
// Index existing docs by title so the folder/file merge lookup below is O(1)
// instead of an `out.find` scan per child (O(n²) over the number of siblings
// in a single directory). First occurrence wins, mirroring `find`.
const byTitle = new Map<string, DiscoveredDocument>();
for (const doc of out) {
if (!byTitle.has(doc.title)) {
byTitle.set(doc.title, doc);
}
}
for (const child of children) {
if (child.children.length > 0 && this.isAttachmentFolder(child)) {
this.collectAttachments(child, manifest);
@@ -691,7 +701,7 @@ export default class MarkdownAPIImportTask extends APIImportTask<Markdown> {
// Folder-and-file with the same title (a "name.md" alongside a "name/"
// directory) is merged onto a single document: the folder body picks up
// the file's markdown text, and the folder's contents become children.
const sibling = out.find((d) => d.title === child.title);
const sibling = byTitle.get(child.title);
if (sibling) {
if (sibling.markdownText === "" && markdownText) {
@@ -720,6 +730,7 @@ export default class MarkdownAPIImportTask extends APIImportTask<Markdown> {
children: [],
};
out.push(node);
byTitle.set(node.title, node);
if (isFolder) {
this.collectDocumentsAndAttachments({