refactor: use Array.from to build Array() from Map()
[poolifier.git] / src / pools / selection-strategies / selection-strategies-utils.ts
index bed0d624ec4c6d5856baab6b42653f2c521f6093..3c7f5f4df327afcce3aaf7ee7f7ee88c397e6513 100644 (file)
@@ -10,6 +10,9 @@ import { LeastUsedWorkerChoiceStrategy } from './least-used-worker-choice-strate
 import { RoundRobinWorkerChoiceStrategy } from './round-robin-worker-choice-strategy.js'
 import {
   type IWorkerChoiceStrategy,
+  type MeasurementStatisticsRequirements,
+  type StrategyPolicy,
+  type TaskStatisticsRequirements,
   WorkerChoiceStrategies,
   type WorkerChoiceStrategy,
   type WorkerChoiceStrategyOptions
@@ -17,10 +20,6 @@ import {
 import { WeightedRoundRobinWorkerChoiceStrategy } from './weighted-round-robin-worker-choice-strategy.js'
 import type { WorkerChoiceStrategiesContext } from './worker-choice-strategies-context.js'
 
-const clone = <T>(object: T): T => {
-  return structuredClone<T>(object)
-}
-
 const estimatedCpuSpeed = (): number => {
   const runs = 150000000
   const begin = performance.now()
@@ -90,7 +89,7 @@ export const buildWorkerChoiceStrategyOptions = <
     pool: IPool<Worker, Data, Response>,
     opts?: WorkerChoiceStrategyOptions
   ): WorkerChoiceStrategyOptions => {
-  opts = clone(opts ?? {})
+  opts = structuredClone(opts ?? {})
   opts.weights = opts.weights ?? getDefaultWeights(pool.info.maxSize)
   return {
     ...{
@@ -102,6 +101,60 @@ export const buildWorkerChoiceStrategyOptions = <
   }
 }
 
+export const toggleMedianMeasurementStatisticsRequirements = (
+  measurementStatisticsRequirements: MeasurementStatisticsRequirements,
+  toggleMedian: boolean
+): void => {
+  if (measurementStatisticsRequirements.average && toggleMedian) {
+    measurementStatisticsRequirements.average = false
+    measurementStatisticsRequirements.median = toggleMedian
+  }
+  if (measurementStatisticsRequirements.median && !toggleMedian) {
+    measurementStatisticsRequirements.average = true
+    measurementStatisticsRequirements.median = toggleMedian
+  }
+}
+
+export const buildWorkerChoiceStrategiesPolicy = (
+  workerChoiceStrategies: Map<WorkerChoiceStrategy, IWorkerChoiceStrategy>
+): StrategyPolicy => {
+  const policies: StrategyPolicy[] = Array.from(
+    workerChoiceStrategies,
+    ([_, workerChoiceStrategy]) => workerChoiceStrategy.strategyPolicy
+  )
+  return {
+    dynamicWorkerUsage: policies.some(p => p.dynamicWorkerUsage),
+    dynamicWorkerReady: policies.some(p => p.dynamicWorkerReady)
+  }
+}
+
+export const buildWorkerChoiceStrategiesTaskStatisticsRequirements = (
+  workerChoiceStrategies: Map<WorkerChoiceStrategy, IWorkerChoiceStrategy>
+): TaskStatisticsRequirements => {
+  const taskStatisticsRequirements: TaskStatisticsRequirements[] = Array.from(
+    workerChoiceStrategies,
+    ([_, workerChoiceStrategy]) =>
+      workerChoiceStrategy.taskStatisticsRequirements
+  )
+  return {
+    runTime: {
+      aggregate: taskStatisticsRequirements.some(r => r.runTime.aggregate),
+      average: taskStatisticsRequirements.some(r => r.runTime.average),
+      median: taskStatisticsRequirements.some(r => r.runTime.median)
+    },
+    waitTime: {
+      aggregate: taskStatisticsRequirements.some(r => r.waitTime.aggregate),
+      average: taskStatisticsRequirements.some(r => r.waitTime.average),
+      median: taskStatisticsRequirements.some(r => r.waitTime.median)
+    },
+    elu: {
+      aggregate: taskStatisticsRequirements.some(r => r.elu.aggregate),
+      average: taskStatisticsRequirements.some(r => r.elu.average),
+      median: taskStatisticsRequirements.some(r => r.elu.median)
+    }
+  }
+}
+
 export const getWorkerChoiceStrategy = <Worker extends IWorker, Data, Response>(
   workerChoiceStrategy: WorkerChoiceStrategy,
   pool: IPool<Worker, Data, Response>,