From f12182ad6dc553c7a5dfeee01bcde65c0177f671 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Tue, 21 May 2024 21:38:17 +0200 Subject: [PATCH] perf: use optimized circular buffer implementation to store measurements history MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .eslintrc.cjs | 1 + package.json | 3 +- pnpm-lock.yaml | 88 +++++----- src/circular-array.ts | 111 ------------- src/circular-buffer.ts | 56 +++++++ src/index.ts | 2 +- src/pools/abstract-pool.ts | 32 +++- src/pools/utils.ts | 10 +- src/pools/worker-node.ts | 19 +-- src/pools/worker.ts | 9 +- tests/circular-array.test.mjs | 152 ------------------ tests/circular-buffer.test.mjs | 60 +++++++ tests/pools/abstract-pool.test.mjs | 74 ++++----- .../selection-strategies.test.mjs | 130 +++++++-------- tests/pools/utils.test.mjs | 32 ++-- tests/pools/worker-node.test.mjs | 42 ++--- 16 files changed, 332 insertions(+), 489 deletions(-) delete mode 100644 src/circular-array.ts create mode 100644 src/circular-buffer.ts delete mode 100644 tests/circular-array.test.mjs create mode 100644 tests/circular-buffer.test.mjs diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 80b400b6..a28991af 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -64,6 +64,7 @@ module.exports = defineConfig({ 'fp', 'fs', 'func', + 'idx', 'inheritDoc', 'javascript', 'jsdoc', diff --git a/package.json b/package.json index 2bd516ba..fa276bb3 100644 --- a/package.json +++ b/package.json @@ -127,8 +127,7 @@ "eslint-plugin-tsdoc": "^0.2.17", "expect": "^29.7.0", "husky": "^9.0.11", - "lint-staged": "^15.2.2", - "microtime": "^3.1.1", + "lint-staged": "^15.2.4", "mocha": "^10.4.0", "mochawesome": "^7.1.3", "prettier": "^3.2.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f3e2c5cd..1e0ba7cb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,11 +90,8 @@ importers: specifier: ^9.0.11 version: 9.0.11 lint-staged: - specifier: ^15.2.2 - version: 15.2.2 - microtime: - specifier: ^3.1.1 - version: 3.1.1 + specifier: ^15.2.4 + version: 15.2.4 mocha: specifier: ^10.4.0 version: 10.4.0 @@ -984,9 +981,9 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -2082,20 +2079,20 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lilconfig@3.0.0: - resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + lilconfig@3.1.1: + resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} engines: {node: '>=14'} lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@15.2.2: - resolution: {integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==} + lint-staged@15.2.4: + resolution: {integrity: sha512-3F9KRQIS2fVDGtCkBp4Bx0jswjX7zUcKx6OF0ZeY1prksUyKPRIIUqZhIUYAstJfvj6i48VFs4dwVIbCYwvTYQ==} engines: {node: '>=18.12.0'} hasBin: true - listr2@8.0.1: - resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==} + listr2@8.2.1: + resolution: {integrity: sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==} engines: {node: '>=18.0.0'} locate-path@6.0.0: @@ -2217,14 +2214,10 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + micromatch@4.0.6: + resolution: {integrity: sha512-Y4Ypn3oujJYxJcMacVgcs92wofTHxp9FzfDpQON4msDefoC0lb3ETvQLOdLcbhSwU1bz8HrL/1sygfBIHudrkQ==} engines: {node: '>=8.6'} - microtime@3.1.1: - resolution: {integrity: sha512-to1r7o24cDsud9IhN6/8wGmMx5R2kT0w2Xwm5okbYI3d1dk6Xv0m+Z+jg2vS9pt+ocgQHTCtgs/YuyJhySzxNg==} - engines: {node: '>= 14.13.0'} - mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -2301,9 +2294,6 @@ packages: nise@6.0.0: resolution: {integrity: sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==} - node-addon-api@5.1.0: - resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} - node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -2312,10 +2302,6 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - node-gyp-build@4.8.1: - resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} - hasBin: true - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -2489,6 +2475,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} @@ -3120,9 +3110,10 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - yaml@2.3.4: - resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} + yaml@2.4.2: + resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} engines: {node: '>= 14'} + hasBin: true yargs-parser@20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} @@ -4077,7 +4068,7 @@ snapshots: colorette@2.0.20: {} - commander@11.1.0: {} + commander@12.1.0: {} commander@2.20.3: {} @@ -4663,7 +4654,7 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.6 fast-json-stable-stringify@2.1.0: {} @@ -5239,7 +5230,7 @@ snapshots: '@types/stack-utils': 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 - micromatch: 4.0.5 + micromatch: 4.0.6 pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.6 @@ -5308,26 +5299,26 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lilconfig@3.0.0: {} + lilconfig@3.1.1: {} lines-and-columns@1.2.4: {} - lint-staged@15.2.2: + lint-staged@15.2.4: dependencies: chalk: 5.3.0 - commander: 11.1.0 + commander: 12.1.0 debug: 4.3.4(supports-color@8.1.1) execa: 8.0.1 - lilconfig: 3.0.0 - listr2: 8.0.1 - micromatch: 4.0.5 + lilconfig: 3.1.1 + listr2: 8.2.1 + micromatch: 4.0.6 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.3.4 + yaml: 2.4.2 transitivePeerDependencies: - supports-color - listr2@8.0.1: + listr2@8.2.1: dependencies: cli-truncate: 4.0.0 colorette: 2.0.20 @@ -5428,15 +5419,10 @@ snapshots: merge2@1.4.1: {} - micromatch@4.0.5: + micromatch@4.0.6: dependencies: braces: 3.0.3 - picomatch: 2.3.1 - - microtime@3.1.1: - dependencies: - node-addon-api: 5.1.0 - node-gyp-build: 4.8.1 + picomatch: 4.0.2 mime-db@1.52.0: {} @@ -5540,8 +5526,6 @@ snapshots: just-extend: 6.2.0 path-to-regexp: 6.2.2 - node-addon-api@5.1.0: {} - node-domexception@1.0.0: {} node-fetch@3.3.2: @@ -5550,8 +5534,6 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 - node-gyp-build@4.8.1: {} - normalize-path@3.0.0: {} normalize-url@8.0.1: {} @@ -5745,6 +5727,8 @@ snapshots: picomatch@2.3.1: {} + picomatch@4.0.2: {} + pidtree@0.6.0: {} possible-typed-array-names@1.0.0: {} @@ -6446,7 +6430,7 @@ snapshots: y18n@5.0.8: {} - yaml@2.3.4: {} + yaml@2.4.2: {} yargs-parser@20.2.4: {} diff --git a/src/circular-array.ts b/src/circular-array.ts deleted file mode 100644 index 23473279..00000000 --- a/src/circular-array.ts +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright Jerome Benoit. 2021-2024. All Rights Reserved. - -export const DEFAULT_CIRCULAR_ARRAY_SIZE = 385 - -/** - * Array with a maximum length and shifting items when full. - * - * @typeParam T - Type of items. - * @internal - */ -export class CircularArray extends Array { - public size: number - - constructor (size: number = DEFAULT_CIRCULAR_ARRAY_SIZE, ...items: T[]) { - super() - this.checkSize(size) - this.size = size - if (arguments.length > 1) { - this.push(...items) - } - } - - /** @inheritDoc */ - public push (...items: T[]): number { - const length = super.push(...items) - if (length > this.size) { - super.splice(0, length - this.size) - } - return this.length - } - - /** @inheritDoc */ - public unshift (...items: T[]): number { - const length = super.unshift(...items) - if (length > this.size) { - super.splice(this.size, items.length) - } - return this.length - } - - /** @inheritDoc */ - public concat (...items: Array>): CircularArray { - const concatenatedCircularArray = super.concat( - items as T[] - ) as CircularArray - concatenatedCircularArray.size = this.size - if (concatenatedCircularArray.length > concatenatedCircularArray.size) { - concatenatedCircularArray.splice( - 0, - concatenatedCircularArray.length - concatenatedCircularArray.size - ) - } - return concatenatedCircularArray - } - - /** @inheritDoc */ - public splice ( - start: number, - deleteCount?: number, - ...items: T[] - ): CircularArray { - let itemsRemoved: T[] = [] - if (arguments.length >= 3 && deleteCount != null) { - itemsRemoved = super.splice(start, deleteCount, ...items) - if (this.length > this.size) { - const itemsOverflowing = super.splice(0, this.length - this.size) - itemsRemoved = new CircularArray( - itemsRemoved.length + itemsOverflowing.length, - ...itemsRemoved, - ...itemsOverflowing - ) - } - } else if (arguments.length === 2) { - itemsRemoved = super.splice(start, deleteCount) - } else { - itemsRemoved = super.splice(start) - } - return itemsRemoved as CircularArray - } - - public resize (size: number): void { - this.checkSize(size) - if (size === 0) { - this.length = 0 - } else if (size < this.size) { - for (let i = size; i < this.size; i++) { - super.pop() - } - } - this.size = size - } - - public empty (): boolean { - return this.length === 0 - } - - public full (): boolean { - return this.length === this.size - } - - private checkSize (size: number): void { - if (!Number.isSafeInteger(size)) { - throw new TypeError( - `Invalid circular array size: ${size} is not a safe integer` - ) - } - if (size < 0) { - throw new RangeError(`Invalid circular array size: ${size} < 0`) - } - } -} diff --git a/src/circular-buffer.ts b/src/circular-buffer.ts new file mode 100644 index 00000000..cbe733d8 --- /dev/null +++ b/src/circular-buffer.ts @@ -0,0 +1,56 @@ +/** + * Default buffer size + */ +export const defaultBufferSize = 2048 + +/** + * Circular buffer + */ +export class CircularBuffer { + private readonly readIdx: number + private writeIdx: number + private items: Array + private readonly maxArrayIdx: number + + /** + * @param size - Buffer size + * @returns CircularBuffer + */ + constructor (size: number = defaultBufferSize) { + this.checkSize(size) + this.readIdx = 0 + this.writeIdx = 0 + this.maxArrayIdx = size - 1 + this.items = new Array(size) + } + + /** + * Puts data into buffer + * + * @param data - Data to push + */ + public put (data: T): void { + this.items[this.writeIdx] = data + this.writeIdx = this.writeIdx === this.maxArrayIdx ? 0 : this.writeIdx + 1 + } + + /** + * Returns buffer as array + * + * @returns T[] + */ + public toArray (): T[] { + return this.items.filter(item => item != null) as T[] + } + + private checkSize (size: number): void { + if (!Number.isSafeInteger(size)) { + throw new TypeError( + `Invalid circular buffer size: ${size} is not an integer` + ) + } + if (size < 0) { + throw new RangeError(`Invalid circular buffer size: ${size} < 0`) + } + } +} diff --git a/src/index.ts b/src/index.ts index cba06414..fae19abd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -export type { CircularArray } from './circular-array.js' +export type { CircularBuffer } from './circular-buffer.js' export type { AbstractPool } from './pools/abstract-pool.js' export { DynamicClusterPool } from './pools/cluster/dynamic.js' export type { ClusterPoolOptions } from './pools/cluster/fixed.js' diff --git a/src/pools/abstract-pool.ts b/src/pools/abstract-pool.ts index a23c7983..a7d3e944 100644 --- a/src/pools/abstract-pool.ts +++ b/src/pools/abstract-pool.ts @@ -395,7 +395,9 @@ export abstract class AbstractPool< average( this.workerNodes.reduce( (accumulator, workerNode) => - accumulator.concat(workerNode.usage.runTime.history), + accumulator.concat( + workerNode.usage.runTime.history.toArray() + ), [] ) ) @@ -407,7 +409,9 @@ export abstract class AbstractPool< median( this.workerNodes.reduce( (accumulator, workerNode) => - accumulator.concat(workerNode.usage.runTime.history), + accumulator.concat( + workerNode.usage.runTime.history.toArray() + ), [] ) ) @@ -440,7 +444,9 @@ export abstract class AbstractPool< average( this.workerNodes.reduce( (accumulator, workerNode) => - accumulator.concat(workerNode.usage.waitTime.history), + accumulator.concat( + workerNode.usage.waitTime.history.toArray() + ), [] ) ) @@ -452,7 +458,9 @@ export abstract class AbstractPool< median( this.workerNodes.reduce( (accumulator, workerNode) => - accumulator.concat(workerNode.usage.waitTime.history), + accumulator.concat( + workerNode.usage.waitTime.history.toArray() + ), [] ) ) @@ -488,7 +496,9 @@ export abstract class AbstractPool< average( this.workerNodes.reduce( (accumulator, workerNode) => - accumulator.concat(workerNode.usage.elu.idle.history), + accumulator.concat( + workerNode.usage.elu.idle.history.toArray() + ), [] ) ) @@ -500,7 +510,9 @@ export abstract class AbstractPool< median( this.workerNodes.reduce( (accumulator, workerNode) => - accumulator.concat(workerNode.usage.elu.idle.history), + accumulator.concat( + workerNode.usage.elu.idle.history.toArray() + ), [] ) ) @@ -532,7 +544,9 @@ export abstract class AbstractPool< average( this.workerNodes.reduce( (accumulator, workerNode) => - accumulator.concat(workerNode.usage.elu.active.history), + accumulator.concat( + workerNode.usage.elu.active.history.toArray() + ), [] ) ) @@ -544,7 +558,9 @@ export abstract class AbstractPool< median( this.workerNodes.reduce( (accumulator, workerNode) => - accumulator.concat(workerNode.usage.elu.active.history), + accumulator.concat( + workerNode.usage.elu.active.history.toArray() + ), [] ) ) diff --git a/src/pools/utils.ts b/src/pools/utils.ts index e69725df..f2ede8b6 100644 --- a/src/pools/utils.ts +++ b/src/pools/utils.ts @@ -233,14 +233,18 @@ const updateMeasurementStatistics = ( measurementStatistics.maximum ?? Number.NEGATIVE_INFINITY ) if (measurementRequirements.average || measurementRequirements.median) { - measurementStatistics.history.push(measurementValue) + measurementStatistics.history.put(measurementValue) if (measurementRequirements.average) { - measurementStatistics.average = average(measurementStatistics.history) + measurementStatistics.average = average( + measurementStatistics.history.toArray() + ) } else if (measurementStatistics.average != null) { delete measurementStatistics.average } if (measurementRequirements.median) { - measurementStatistics.median = median(measurementStatistics.history) + measurementStatistics.median = median( + measurementStatistics.history.toArray() + ) } else if (measurementStatistics.median != null) { delete measurementStatistics.median } diff --git a/src/pools/worker-node.ts b/src/pools/worker-node.ts index c1c1e0a9..d87a79c0 100644 --- a/src/pools/worker-node.ts +++ b/src/pools/worker-node.ts @@ -1,7 +1,7 @@ import { EventEmitter } from 'node:events' import { MessageChannel } from 'node:worker_threads' -import { CircularArray } from '../circular-array.js' +import { CircularBuffer } from '../circular-buffer.js' import { PriorityQueue } from '../priority-queue.js' import type { Task } from '../utility-types.js' import { DEFAULT_TASK_NAME } from '../utils.js' @@ -15,6 +15,7 @@ import { type EventHandler, type IWorker, type IWorkerNode, + MeasurementHistorySize, type StrategyData, type WorkerInfo, type WorkerNodeOptions, @@ -239,17 +240,17 @@ export class WorkerNode failed: 0 }, runTime: { - history: new CircularArray() + history: new CircularBuffer(MeasurementHistorySize) }, waitTime: { - history: new CircularArray() + history: new CircularBuffer(MeasurementHistorySize) }, elu: { idle: { - history: new CircularArray() + history: new CircularBuffer(MeasurementHistorySize) }, active: { - history: new CircularArray() + history: new CircularBuffer(MeasurementHistorySize) } } } @@ -282,17 +283,17 @@ export class WorkerNode failed: 0 }, runTime: { - history: new CircularArray() + history: new CircularBuffer(MeasurementHistorySize) }, waitTime: { - history: new CircularArray() + history: new CircularBuffer(MeasurementHistorySize) }, elu: { idle: { - history: new CircularArray() + history: new CircularBuffer(MeasurementHistorySize) }, active: { - history: new CircularArray() + history: new CircularBuffer(MeasurementHistorySize) } } } diff --git a/src/pools/worker.ts b/src/pools/worker.ts index 99c0d9a6..7d9f3de9 100644 --- a/src/pools/worker.ts +++ b/src/pools/worker.ts @@ -1,7 +1,7 @@ import type { EventEmitter } from 'node:events' import type { MessageChannel, WorkerOptions } from 'node:worker_threads' -import type { CircularArray } from '../circular-array.js' +import type { CircularBuffer } from '../circular-buffer.js' import type { Task, TaskFunctionProperties } from '../utility-types.js' /** @@ -52,6 +52,11 @@ export type EventHandler = | ErrorHandler | ExitHandler +/** + * Measurement history size. + */ +export const MeasurementHistorySize = 386 + /** * Measurement statistics. * @@ -81,7 +86,7 @@ export interface MeasurementStatistics { /** * Measurement history. */ - readonly history: CircularArray + readonly history: CircularBuffer } /** diff --git a/tests/circular-array.test.mjs b/tests/circular-array.test.mjs deleted file mode 100644 index a6f2f693..00000000 --- a/tests/circular-array.test.mjs +++ /dev/null @@ -1,152 +0,0 @@ -import { expect } from 'expect' - -import { - CircularArray, - DEFAULT_CIRCULAR_ARRAY_SIZE -} from '../lib/circular-array.cjs' - -describe('Circular array test suite', () => { - it('Verify that circular array can be instantiated', () => { - const circularArray = new CircularArray() - expect(circularArray).toBeInstanceOf(CircularArray) - }) - - it('Verify circular array default size at instance creation', () => { - const circularArray = new CircularArray() - expect(circularArray.size).toBe(DEFAULT_CIRCULAR_ARRAY_SIZE) - }) - - it('Verify that circular array size can be set at instance creation', () => { - const circularArray = new CircularArray(1000) - expect(circularArray.size).toBe(1000) - }) - - it('Verify that circular array size and items can be set at instance creation', () => { - let circularArray = new CircularArray(1000, 1, 2, 3, 4, 5) - expect(circularArray.size).toBe(1000) - expect(circularArray.length).toBe(5) - circularArray = new CircularArray(4, 1, 2, 3, 4, 5) - expect(circularArray.size).toBe(4) - expect(circularArray.length).toBe(4) - }) - - it('Verify that circular array size is valid at instance creation', () => { - expect(() => new CircularArray(0.25)).toThrow( - new TypeError('Invalid circular array size: 0.25 is not a safe integer') - ) - expect(() => new CircularArray(-1)).toThrow( - new RangeError('Invalid circular array size: -1 < 0') - ) - expect(() => new CircularArray(Number.MAX_SAFE_INTEGER + 1)).toThrow( - new TypeError( - `Invalid circular array size: ${ - Number.MAX_SAFE_INTEGER + 1 - } is not a safe integer` - ) - ) - }) - - it('Verify that circular array empty works as intended', () => { - const circularArray = new CircularArray() - expect(circularArray.empty()).toBe(true) - }) - - it('Verify that circular array full works as intended', () => { - const circularArray = new CircularArray(5, 1, 2, 3, 4, 5) - expect(circularArray.full()).toBe(true) - }) - - it('Verify that circular array push works as intended', () => { - let circularArray = new CircularArray(4) - let arrayLength = circularArray.push(1, 2, 3, 4, 5) - expect(arrayLength).toBe(circularArray.size) - expect(circularArray.length).toBe(circularArray.size) - expect(circularArray).toStrictEqual(new CircularArray(4, 2, 3, 4, 5)) - arrayLength = circularArray.push(6, 7) - expect(arrayLength).toBe(circularArray.size) - expect(circularArray.length).toBe(circularArray.size) - expect(circularArray).toStrictEqual(new CircularArray(4, 4, 5, 6, 7)) - circularArray = new CircularArray(100) - arrayLength = circularArray.push(1, 2, 3, 4, 5) - expect(arrayLength).toBe(5) - expect(circularArray.size).toBe(100) - expect(circularArray.length).toBe(5) - expect(circularArray).toStrictEqual(new CircularArray(100, 1, 2, 3, 4, 5)) - }) - - it('Verify that circular array splice works as intended', () => { - let circularArray = new CircularArray(1000, 1, 2, 3, 4, 5) - let deletedItems = circularArray.splice(2) - expect(deletedItems).toStrictEqual(new CircularArray(3, 3, 4, 5)) - expect(circularArray.length).toBe(2) - expect(circularArray).toStrictEqual(new CircularArray(1000, 1, 2)) - circularArray = new CircularArray(1000, 1, 2, 3, 4, 5) - deletedItems = circularArray.splice(2, 1) - expect(deletedItems).toStrictEqual(new CircularArray(1, 3)) - expect(circularArray.length).toBe(4) - expect(circularArray).toStrictEqual(new CircularArray(1000, 1, 2, 4, 5)) - circularArray = new CircularArray(4, 1, 2, 3, 4) - deletedItems = circularArray.splice(2, 1, 5, 6) - expect(deletedItems).toStrictEqual(new CircularArray(2, 3, 1)) - expect(circularArray.length).toBe(4) - expect(circularArray).toStrictEqual(new CircularArray(4, 2, 5, 6, 4)) - }) - - it('Verify that circular array concat works as intended', () => { - let circularArray = new CircularArray(5, 1, 2, 3, 4, 5) - circularArray = circularArray.concat(6, 7) - expect(circularArray.length).toBe(5) - expect(circularArray).toStrictEqual(new CircularArray(5, 3, 4, 5, 6, 7)) - circularArray = new CircularArray(1) - circularArray = circularArray.concat(6, 7) - expect(circularArray.length).toBe(1) - expect(circularArray).toStrictEqual(new CircularArray(1, 7)) - }) - - it('Verify that circular array unshift works as intended', () => { - let circularArray = new CircularArray(5, 1, 2, 3, 4, 5) - let arrayLength = circularArray.unshift(6, 7) - expect(arrayLength).toBe(5) - expect(circularArray.length).toBe(5) - expect(circularArray).toStrictEqual(new CircularArray(5, 6, 7, 1, 2, 3)) - circularArray = new CircularArray(1) - arrayLength = circularArray.unshift(6, 7) - expect(arrayLength).toBe(1) - expect(circularArray.length).toBe(1) - expect(circularArray).toStrictEqual(new CircularArray(1, 6)) - }) - - it('Verify that circular array resize works as intended', () => { - expect(() => new CircularArray().resize(0.25)).toThrow( - new TypeError('Invalid circular array size: 0.25 is not a safe integer') - ) - expect(() => new CircularArray().resize(-1)).toThrow( - new RangeError('Invalid circular array size: -1 < 0') - ) - expect(() => - new CircularArray().resize(Number.MAX_SAFE_INTEGER + 1) - ).toThrow( - new TypeError( - `Invalid circular array size: ${ - Number.MAX_SAFE_INTEGER + 1 - } is not a safe integer` - ) - ) - let circularArray = new CircularArray(5, 1, 2, 3, 4, 5) - circularArray.resize(0) - expect(circularArray.size).toBe(0) - expect(circularArray).toStrictEqual(new CircularArray(0)) - circularArray = new CircularArray(5, 1, 2, 3, 4, 5) - circularArray.resize(1) - expect(circularArray.size).toBe(1) - expect(circularArray).toStrictEqual(new CircularArray(1, 1)) - circularArray = new CircularArray(5, 1, 2, 3, 4, 5) - circularArray.resize(3) - expect(circularArray.size).toBe(3) - expect(circularArray).toStrictEqual(new CircularArray(3, 1, 2, 3)) - circularArray = new CircularArray(5, 1, 2, 3, 4, 5) - circularArray.resize(8) - expect(circularArray.size).toBe(8) - expect(circularArray).toStrictEqual(new CircularArray(8, 1, 2, 3, 4, 5)) - }) -}) diff --git a/tests/circular-buffer.test.mjs b/tests/circular-buffer.test.mjs new file mode 100644 index 00000000..ec86ca2a --- /dev/null +++ b/tests/circular-buffer.test.mjs @@ -0,0 +1,60 @@ +import { expect } from 'expect' + +import { CircularBuffer, defaultBufferSize } from '../lib/circular-buffer.cjs' + +describe('Circular buffer test suite', t => { + it('Verify that circular buffer can be instantiated', () => { + const circularBuffer = new CircularBuffer() + expect(circularBuffer).toBeInstanceOf(CircularBuffer) + expect(circularBuffer.readIdx).toBe(0) + expect(circularBuffer.writeIdx).toBe(0) + expect(circularBuffer.maxArrayIdx).toBe(defaultBufferSize - 1) + expect(circularBuffer.items).toBeInstanceOf(Array) + expect(circularBuffer.items.length).toBe(defaultBufferSize) + }) + + it('Verify that circular buffer size can be set at instance creation', () => { + const circularBuffer = new CircularBuffer(1000) + expect(circularBuffer.maxArrayIdx).toBe(999) + expect(circularBuffer.items).toBeInstanceOf(Array) + expect(circularBuffer.items.length).toBe(1000) + }) + + it('Verify that circular buffer size is valid at instance creation', () => { + expect(() => new CircularBuffer(0.25)).toThrow( + new TypeError('Invalid circular buffer size: 0.25 is not an integer') + ) + expect(() => new CircularBuffer(-1)).toThrow( + new RangeError('Invalid circular buffer size: -1 < 0') + ) + expect(() => new CircularBuffer(Number.MAX_SAFE_INTEGER + 1)).toThrow( + new TypeError( + `Invalid circular buffer size: ${ + Number.MAX_SAFE_INTEGER + 1 + } is not an integer` + ) + ) + }) + + it('Verify that circular buffer put() works as intended', () => { + const circularBuffer = new CircularBuffer(4) + circularBuffer.put(1) + expect(circularBuffer.items).toMatchObject([1]) + expect(circularBuffer.writeIdx).toBe(1) + circularBuffer.put(2) + expect(circularBuffer.items).toMatchObject([1, 2]) + expect(circularBuffer.writeIdx).toBe(2) + circularBuffer.put(3) + expect(circularBuffer.items).toMatchObject([1, 2, 3]) + expect(circularBuffer.writeIdx).toBe(3) + circularBuffer.put(4) + expect(circularBuffer.items).toMatchObject([1, 2, 3, 4]) + expect(circularBuffer.writeIdx).toBe(0) + circularBuffer.put(5) + expect(circularBuffer.items).toMatchObject([5, 2, 3, 4]) + expect(circularBuffer.writeIdx).toBe(1) + circularBuffer.put(6) + expect(circularBuffer.items).toMatchObject([5, 6, 3, 4]) + expect(circularBuffer.writeIdx).toBe(2) + }) +}) diff --git a/tests/pools/abstract-pool.test.mjs b/tests/pools/abstract-pool.test.mjs index 441e7ffc..0c913497 100644 --- a/tests/pools/abstract-pool.test.mjs +++ b/tests/pools/abstract-pool.test.mjs @@ -8,7 +8,7 @@ import { fileURLToPath } from 'node:url' import { expect } from 'expect' import { restore, stub } from 'sinon' -import { CircularArray } from '../../lib/circular-array.cjs' +import { CircularBuffer } from '../../lib/circular-buffer.cjs' import { DynamicClusterPool, DynamicThreadPool, @@ -761,17 +761,17 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -933,17 +933,17 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, waitTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, elu: { idle: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, active: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) } } }) @@ -961,17 +961,17 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, waitTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, elu: { idle: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, active: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) } } }) @@ -1003,17 +1003,17 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, waitTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, elu: { idle: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, active: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) } } }) @@ -1021,10 +1021,6 @@ describe('Abstract pool test suite', () => { expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( numberOfWorkers * maxMultiplier ) - expect(workerNode.usage.runTime.history.length).toBe(0) - expect(workerNode.usage.waitTime.history.length).toBe(0) - expect(workerNode.usage.elu.idle.history.length).toBe(0) - expect(workerNode.usage.elu.active.history.length).toBe(0) } pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) for (const workerNode of pool.workerNodes) { @@ -1039,17 +1035,17 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, waitTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, elu: { idle: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, active: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) } } }) @@ -1057,10 +1053,6 @@ describe('Abstract pool test suite', () => { expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( numberOfWorkers * maxMultiplier ) - expect(workerNode.usage.runTime.history.length).toBe(0) - expect(workerNode.usage.waitTime.history.length).toBe(0) - expect(workerNode.usage.elu.idle.history.length).toBe(0) - expect(workerNode.usage.elu.active.history.length).toBe(0) } await pool.destroy() }) @@ -1452,17 +1444,17 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: expect.objectContaining({ idle: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), active: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }) }) }) @@ -1683,17 +1675,17 @@ describe('Abstract pool test suite', () => { stolen: 0 }, runTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, waitTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, elu: { idle: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, active: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) } } }) @@ -1752,17 +1744,17 @@ describe('Abstract pool test suite', () => { stolen: 0 }, runTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, waitTime: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, elu: { idle: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }, active: { - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) } } }) diff --git a/tests/pools/selection-strategies/selection-strategies.test.mjs b/tests/pools/selection-strategies/selection-strategies.test.mjs index e4d1dd07..3f2f2e81 100644 --- a/tests/pools/selection-strategies/selection-strategies.test.mjs +++ b/tests/pools/selection-strategies/selection-strategies.test.mjs @@ -2,7 +2,7 @@ import { randomInt } from 'node:crypto' import { expect } from 'expect' -import { CircularArray } from '../../../lib/circular-array.cjs' +import { CircularBuffer } from '../../../lib/circular-buffer.cjs' import { DynamicClusterPool, DynamicThreadPool, @@ -258,17 +258,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -314,17 +314,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -532,17 +532,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -591,17 +591,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -731,17 +731,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), waitTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -800,17 +800,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), waitTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -950,17 +950,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: expect.objectContaining({ idle: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), active: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }) }) }) @@ -1025,17 +1025,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: expect.objectContaining({ idle: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), active: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }) }) }) @@ -1181,17 +1181,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), waitTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), elu: expect.objectContaining({ idle: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), active: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }) }) }) @@ -1277,17 +1277,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), waitTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), elu: expect.objectContaining({ idle: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), active: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }) }) }) @@ -1378,17 +1378,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), waitTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), elu: expect.objectContaining({ idle: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), active: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }) }) }) @@ -1589,17 +1589,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), waitTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -1673,17 +1673,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), waitTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -1762,17 +1762,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), waitTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -2000,17 +2000,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), waitTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -2104,17 +2104,17 @@ describe('Selection strategies test suite', () => { failed: 0 }, runTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), waitTime: expect.objectContaining({ - history: expect.any(CircularArray) + history: expect.any(CircularBuffer) }), elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) diff --git a/tests/pools/utils.test.mjs b/tests/pools/utils.test.mjs index 3842c8c5..3d9634ff 100644 --- a/tests/pools/utils.test.mjs +++ b/tests/pools/utils.test.mjs @@ -3,10 +3,7 @@ import { Worker as ThreadWorker } from 'node:worker_threads' import { expect } from 'expect' -import { - CircularArray, - DEFAULT_CIRCULAR_ARRAY_SIZE -} from '../../lib/circular-array.cjs' +import { CircularBuffer } from '../../lib/circular-buffer.cjs' import { WorkerTypes } from '../../lib/index.cjs' import { createWorker, @@ -16,6 +13,7 @@ import { getWorkerType, updateMeasurementStatistics } from '../../lib/pools/utils.cjs' +import { MeasurementHistorySize } from '../../lib/pools/worker.cjs' describe('Pool utils test suite', () => { it('Verify DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS values', () => { @@ -38,8 +36,9 @@ describe('Pool utils test suite', () => { }) it('Verify updateMeasurementStatistics() behavior', () => { + const circularBuffer = new CircularBuffer(MeasurementHistorySize) const measurementStatistics = { - history: new CircularArray() + history: circularBuffer } updateMeasurementStatistics( measurementStatistics, @@ -50,7 +49,7 @@ describe('Pool utils test suite', () => { aggregate: 0.01, maximum: 0.01, minimum: 0.01, - history: new CircularArray() + history: circularBuffer }) updateMeasurementStatistics( measurementStatistics, @@ -61,7 +60,7 @@ describe('Pool utils test suite', () => { aggregate: 0.03, maximum: 0.02, minimum: 0.01, - history: new CircularArray() + history: circularBuffer }) updateMeasurementStatistics( measurementStatistics, @@ -73,7 +72,7 @@ describe('Pool utils test suite', () => { maximum: 0.02, minimum: 0.001, average: 0.001, - history: new CircularArray(DEFAULT_CIRCULAR_ARRAY_SIZE, 0.001) + history: circularBuffer }) updateMeasurementStatistics( measurementStatistics, @@ -85,7 +84,7 @@ describe('Pool utils test suite', () => { maximum: 0.02, minimum: 0.001, average: 0.002, - history: new CircularArray(DEFAULT_CIRCULAR_ARRAY_SIZE, 0.001, 0.003) + history: circularBuffer }) updateMeasurementStatistics( measurementStatistics, @@ -97,12 +96,7 @@ describe('Pool utils test suite', () => { maximum: 0.02, minimum: 0.001, median: 0.003, - history: new CircularArray( - DEFAULT_CIRCULAR_ARRAY_SIZE, - 0.001, - 0.003, - 0.006 - ) + history: circularBuffer }) updateMeasurementStatistics( measurementStatistics, @@ -114,13 +108,7 @@ describe('Pool utils test suite', () => { maximum: 0.02, minimum: 0.001, average: 0.005, - history: new CircularArray( - DEFAULT_CIRCULAR_ARRAY_SIZE, - 0.001, - 0.003, - 0.006, - 0.01 - ) + history: circularBuffer }) }) diff --git a/tests/pools/worker-node.test.mjs b/tests/pools/worker-node.test.mjs index c4f84a51..54a69ca4 100644 --- a/tests/pools/worker-node.test.mjs +++ b/tests/pools/worker-node.test.mjs @@ -3,7 +3,7 @@ import { MessageChannel, Worker as ThreadWorker } from 'node:worker_threads' import { expect } from 'expect' -import { CircularArray } from '../../lib/circular-array.cjs' +import { CircularBuffer } from '../../lib/circular-buffer.cjs' import { WorkerTypes } from '../../lib/index.cjs' import { WorkerNode } from '../../lib/pools/worker-node.cjs' import { PriorityQueue } from '../../lib/priority-queue.cjs' @@ -206,17 +206,17 @@ describe('Worker node test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -252,17 +252,17 @@ describe('Worker node test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -314,17 +314,17 @@ describe('Worker node test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -338,17 +338,17 @@ describe('Worker node test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) @@ -362,17 +362,17 @@ describe('Worker node test suite', () => { failed: 0 }, runTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, waitTime: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, elu: { idle: { - history: new CircularArray() + history: expect.any(CircularBuffer) }, active: { - history: new CircularArray() + history: expect.any(CircularBuffer) } } }) -- 2.34.1