From db57e97e1bb0a728f478f65fab9c5a31dcd050c1 Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Sun, 29 Dec 2024 18:26:05 +0800 Subject: [PATCH] perf(model): add caching for data keys --- src/model.ts | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/model.ts b/src/model.ts index a61fef5..b4f523a 100644 --- a/src/model.ts +++ b/src/model.ts @@ -22,6 +22,9 @@ class Model extends EventEmitter { Query; _database: Database; + _dataKeys: string[] = []; + dirty = false; + /** * Model constructor. * @@ -82,6 +85,17 @@ class Model extends EventEmitter { Object.assign(_Document.prototype, schema.methods); } + /** + * Returns the cached data keys. + */ + get dataKeys(): string[] { + if (this.dirty) { + this._dataKeys = Object.keys(this.data); + this.dirty = false; + } + return this._dataKeys; + } + /** * Creates a new document. * @@ -168,6 +182,7 @@ class Model extends EventEmitter { // Pre-hooks return execHooks(schema, 'pre', 'save', data).then(data => { // Insert data + this.dirty = true; this.data[id] = result; this.length++; @@ -258,6 +273,7 @@ class Model extends EventEmitter { // Pre-hooks return execHooks(schema, 'pre', 'save', doc).then(data => { // Update data + this.dirty = true; this.data[id] = result; this.emit('update', data); @@ -319,6 +335,7 @@ class Model extends EventEmitter { // Pre-hooks return execHooks(schema, 'pre', 'save', data).then(data => { // Replace data + this.dirty = true; this.data[id] = result; this.emit('update', data); @@ -369,6 +386,7 @@ class Model extends EventEmitter { // Pre-hooks return execHooks(schema, 'pre', 'remove', data).then(data => { // Remove data + this.dirty = true; this.data[id] = null; this.length--; @@ -422,7 +440,7 @@ class Model extends EventEmitter { * @param {object} [options] See {@link Model#findById}. */ forEach(iterator: (value: any, index: number) => void, options?: Options): void { - const keys = Object.keys(this.data); + const keys = this.dataKeys; let num = 0; for (let i = 0, len = keys.length; i < len; i++) { @@ -461,7 +479,7 @@ class Model extends EventEmitter { find(query: object, options: Options): Query | T[]; find(query: object, options: Options = {}): Query | T[] { const filter = this.schema._execQuery(query); - const keys = Object.keys(this.data); + const keys = this.dataKeys; const len = keys.length; let limit = options.limit || this.length; let skip = options.skip; @@ -528,7 +546,7 @@ class Model extends EventEmitter { eq(i_: number, options?: Options): Document | Record { let index = i_ < 0 ? this.length + i_ : i_; const data = this.data; - const keys = Object.keys(data); + const keys = this.dataKeys; for (let i = 0, len = keys.length; i < len; i++) { const key = keys[i]; @@ -586,7 +604,7 @@ class Model extends EventEmitter { if (!len) return new this.Query([]); const arr = new Array(len); - const keys = Object.keys(this.data); + const keys = this.dataKeys; const keysLen = keys.length; let num = 0; @@ -651,7 +669,7 @@ class Model extends EventEmitter { */ map(iterator: (value: any, index: number) => T, options?: Options): T[] { const result = new Array(this.length); - const keys = Object.keys(this.data); + const keys = this.dataKeys; const len = keys.length; for (let i = 0, num = 0; i < len; i++) { @@ -747,7 +765,7 @@ class Model extends EventEmitter { * @return {Boolean} */ every(iterator: (value: any, index: number) => any): boolean { - const keys = Object.keys(this.data); + const keys = this.dataKeys; const len = keys.length; let num = 0; @@ -772,7 +790,7 @@ class Model extends EventEmitter { * @return {Boolean} */ some(iterator: (value: any, index: number) => any): boolean { - const keys = Object.keys(this.data); + const keys = this.dataKeys; const len = keys.length; let num = 0; @@ -925,6 +943,7 @@ class Model extends EventEmitter { for (let i = 0; i < len; i++) { const item = arr[i]; + this.dirty = true; data[item._id] = schema._parseDatabase(item) as T; } @@ -944,7 +963,7 @@ class Model extends EventEmitter { toJSON(): any[] { const result = new Array(this.length); const { data, schema } = this; - const keys = Object.keys(data); + const keys = this.dataKeys; const { length } = keys; for (let i = 0, num = 0; i < length; i++) {