Merge branch 'master' into worker-info
[poolifier.git] / src / utils.ts
1 import os from 'node:os'
2 import type {
3 MeasurementStatisticsRequirements,
4 WorkerChoiceStrategyOptions
5 } from './pools/selection-strategies/selection-strategies-types'
6
7 /**
8 * An intentional empty function.
9 */
10 export const EMPTY_FUNCTION: () => void = Object.freeze(() => {
11 /* Intentionally empty */
12 })
13
14 /**
15 * Default worker choice strategy options.
16 */
17 export const DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS: WorkerChoiceStrategyOptions =
18 {
19 runTime: { median: false },
20 waitTime: { median: false },
21 elu: { median: false }
22 }
23
24 /**
25 * Default measurement statistics requirements.
26 */
27 export const DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS: MeasurementStatisticsRequirements =
28 {
29 aggregate: false,
30 average: false,
31 median: false
32 }
33
34 /**
35 * Safe helper to get the host OS optimized maximum pool size.
36 */
37 export const availableParallelism = (): number => {
38 let availableParallelism = 1
39 try {
40 availableParallelism = os.availableParallelism()
41 } catch {
42 const cpus = os.cpus()
43 if (Array.isArray(cpus) && cpus.length > 0) {
44 availableParallelism = cpus.length
45 }
46 }
47 return availableParallelism
48 }
49
50 /**
51 * Compute the median of the given data set.
52 *
53 * @param dataSet - Data set.
54 * @returns The median of the given data set.
55 */
56 export const median = (dataSet: number[]): number => {
57 if (Array.isArray(dataSet) && dataSet.length === 0) {
58 return 0
59 }
60 if (Array.isArray(dataSet) && dataSet.length === 1) {
61 return dataSet[0]
62 }
63 const sortedDataSet = dataSet.slice().sort((a, b) => a - b)
64 return (
65 (sortedDataSet[(sortedDataSet.length - 1) >> 1] +
66 sortedDataSet[sortedDataSet.length >> 1]) /
67 2
68 )
69 }
70
71 /**
72 * Is the given object a plain object?
73 *
74 * @param obj - The object to check.
75 * @returns `true` if the given object is a plain object, `false` otherwise.
76 */
77 export const isPlainObject = (obj: unknown): boolean =>
78 typeof obj === 'object' &&
79 obj !== null &&
80 obj?.constructor === Object &&
81 Object.prototype.toString.call(obj) === '[object Object]'