fix(core): improve doc meta performance (#8913)

This commit is contained in:
EYHN
2024-11-27 14:18:06 +08:00
committed by GitHub
parent 83c587f8ad
commit 3f4cb5be40
2 changed files with 36 additions and 20 deletions

View File

@@ -13,23 +13,28 @@ export class DocRecordList extends Entity {
private readonly pool = new Map<string, DocRecord>(); private readonly pool = new Map<string, DocRecord>();
public readonly docs$ = LiveData.from<DocRecord[]>( public readonly docsMap$ = LiveData.from<Map<string, DocRecord>>(
this.store.watchDocIds().pipe( this.store.watchDocIds().pipe(
map(ids => map(
ids.map(id => { ids =>
const exists = this.pool.get(id); new Map(
if (exists) { ids.map(id => {
return exists; const exists = this.pool.get(id);
} if (exists) {
const record = this.framework.createEntity(DocRecord, { id }); return [id, exists];
this.pool.set(id, record); }
return record; const record = this.framework.createEntity(DocRecord, { id });
}) this.pool.set(id, record);
return [id, record];
})
)
) )
), ),
[] new Map()
); );
public readonly docs$ = this.docsMap$.selector(d => Array.from(d.values()));
public readonly trashDocs$ = LiveData.from<DocRecord[]>( public readonly trashDocs$ = LiveData.from<DocRecord[]>(
this.store.watchTrashDocIds().pipe( this.store.watchTrashDocIds().pipe(
map(ids => map(ids =>
@@ -53,7 +58,7 @@ export class DocRecordList extends Entity {
); );
public doc$(id: string) { public doc$(id: string) {
return this.docs$.map(record => record.find(record => record.id === id)); return this.docsMap$.selector(map => map.get(id));
} }
public setPrimaryMode(id: string, mode: DocMode) { public setPrimaryMode(id: string, mode: DocMode) {

View File

@@ -32,7 +32,7 @@ export class DocsStore extends Store {
switchMap(yjsObserve), switchMap(yjsObserve),
map(meta => { map(meta => {
if (meta instanceof YArray) { if (meta instanceof YArray) {
return meta.map(v => v.get('id')); return meta.map(v => v.get('id') as string);
} else { } else {
return []; return [];
} }
@@ -59,6 +59,7 @@ export class DocsStore extends Store {
} }
watchDocMeta(id: string) { watchDocMeta(id: string) {
let docMetaIndexCache = -1;
return yjsObserveByPath( return yjsObserveByPath(
this.workspaceService.workspace.rootYDoc.getMap('meta'), this.workspaceService.workspace.rootYDoc.getMap('meta'),
'pages' 'pages'
@@ -66,13 +67,23 @@ export class DocsStore extends Store {
switchMap(yjsObserve), switchMap(yjsObserve),
map(meta => { map(meta => {
if (meta instanceof YArray) { if (meta instanceof YArray) {
let docMetaYMap = null as YMap<any> | null; if (docMetaIndexCache >= 0) {
meta.forEach(doc => { const doc = meta.get(docMetaIndexCache);
if (doc.get('id') === id) { if (doc && doc.get('id') === id) {
docMetaYMap = doc; return doc as YMap<any>;
} }
}); }
return docMetaYMap;
// meta is YArray, `for-of` is faster then `for`
let i = 0;
for (const doc of meta) {
if (doc && doc.get('id') === id) {
docMetaIndexCache = i;
return doc as YMap<any>;
}
i++;
}
return null;
} else { } else {
return null; return null;
} }