From af778246185de53479007eb9d857766e5d6ca4ba Mon Sep 17 00:00:00 2001 From: Dmitry S Date: Thu, 25 Aug 2022 01:22:53 -0400 Subject: [PATCH] (core) Add caching for measuring data size in DocStorage, when data isn't changing Summary: getDataSize() call can be expensive and involve lots of disk reading. We can avoid doing it repeatedly when the document isn't actually changing. Test Plan: Should have no change in behavior except for timings. Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3605 --- app/server/lib/DocStorage.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/server/lib/DocStorage.ts b/app/server/lib/DocStorage.ts index 24291cb3..844c40ca 100644 --- a/app/server/lib/DocStorage.ts +++ b/app/server/lib/DocStorage.ts @@ -645,6 +645,8 @@ export class DocStorage implements ISQLiteDB, OnDemandStorage { // tables (obtained from auto-generated schema.js). private _docSchema: {[tableId: string]: {[colId: string]: string}}; + private _cachedDataSize: number|null = null; + public constructor(public storageManager: IDocStorageManager, public docName: string) { this.docPath = this.storageManager.getPath(docName); this._db = null; @@ -1518,7 +1520,20 @@ export class DocStorage implements ISQLiteDB, OnDemandStorage { } } + /** + * Return the total size of data in the user + meta tables of the SQLite doc (excluding gristsys + * tables). Uses cached results if possible. Any change to data invalidates the cache, via + * _markAsChanged(). + */ public async getDataSize(): Promise { + return this._cachedDataSize ?? (this._cachedDataSize = await this.getDataSizeUncached()); + } + + /** + * Measure and return the total size of data in the user + meta tables of the SQLite doc + * (excluding gristsys tables). Note that this operation involves reading the entire database. + */ + public async getDataSizeUncached(): Promise { const result = await this.get(` SELECT SUM(pgsize - unused) AS totalSize FROM dbstat @@ -1534,6 +1549,7 @@ export class DocStorage implements ISQLiteDB, OnDemandStorage { try { return await promise; } finally { + this._cachedDataSize = null; this.storageManager.markAsChanged(this.docName); } }