feat: add utilization to pool information
[poolifier.git] / src / utils.ts
CommitLineData
51474716 1import os from 'node:os'
3c93feb9
JB
2import type {
3 MeasurementStatisticsRequirements,
4 WorkerChoiceStrategyOptions
5} from './pools/selection-strategies/selection-strategies-types'
bbeadd16 6
6e9d10db
JB
7/**
8 * An intentional empty function.
9 */
4f3c3d89 10export const EMPTY_FUNCTION: () => void = Object.freeze(() => {
6e9d10db 11 /* Intentionally empty */
4f3c3d89 12})
78099a15
JB
13
14/**
bbeadd16
JB
15 * Default worker choice strategy options.
16 */
17export const DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS: WorkerChoiceStrategyOptions =
18 {
932fc8be 19 runTime: { median: false },
5df69fab
JB
20 waitTime: { median: false },
21 elu: { median: false }
bbeadd16
JB
22 }
23
3c93feb9
JB
24/**
25 * Default measurement statistics requirements.
26 */
27export const DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS: MeasurementStatisticsRequirements =
28 {
29 aggregate: false,
30 average: false,
31 median: false
32 }
33
51474716 34/**
ab80dc46
JB
35 * Returns safe host OS optimized estimate of the default amount of parallelism a pool should use.
36 * Always returns a value greater than zero.
37 *
38 * @returns The host OS optimized maximum pool size.
51474716
JB
39 */
40export const availableParallelism = (): number => {
41 let availableParallelism = 1
42 try {
43 availableParallelism = os.availableParallelism()
44 } catch {
45 const cpus = os.cpus()
46 if (Array.isArray(cpus) && cpus.length > 0) {
47 availableParallelism = cpus.length
48 }
49 }
50 return availableParallelism
51}
52
bbeadd16 53/**
afe0d5bf 54 * Computes the median of the given data set.
78099a15
JB
55 *
56 * @param dataSet - Data set.
57 * @returns The median of the given data set.
58 */
59export const median = (dataSet: number[]): number => {
4a45e8d2
JB
60 if (Array.isArray(dataSet) && dataSet.length === 0) {
61 return 0
62 }
78099a15
JB
63 if (Array.isArray(dataSet) && dataSet.length === 1) {
64 return dataSet[0]
65 }
c6f42dd6
JB
66 const sortedDataSet = dataSet.slice().sort((a, b) => a - b)
67 return (
68 (sortedDataSet[(sortedDataSet.length - 1) >> 1] +
69 sortedDataSet[sortedDataSet.length >> 1]) /
70 2
71 )
78099a15 72}
0d80593b 73
afe0d5bf
JB
74/**
75 * Rounds the given number to the given scale.
76 *
77 * @param num - The number to round.
78 * @param scale - The scale to round to.
79 * @returns The rounded number.
80 */
81export const round = (num: number, scale = 2): number => {
82 const rounder = Math.pow(10, scale)
83 return Math.round(num * rounder * (1 + Number.EPSILON)) / rounder
84}
85
3c653a03
JB
86/**
87 * Is the given object a plain object?
88 *
89 * @param obj - The object to check.
90 * @returns `true` if the given object is a plain object, `false` otherwise.
91 */
0d80593b
JB
92export const isPlainObject = (obj: unknown): boolean =>
93 typeof obj === 'object' &&
94 obj !== null &&
95 obj?.constructor === Object &&
96 Object.prototype.toString.call(obj) === '[object Object]'