Skip to content

Commit

Permalink
refactor: cleanup priority queue code
Browse files Browse the repository at this point in the history
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
  • Loading branch information
jerome-benoit committed May 19, 2024
1 parent ec739d0 commit 51aa64a
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 24 deletions.
28 changes: 16 additions & 12 deletions src/priority-queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface PriorityQueueNode<T> {
export class PriorityQueue<T> {
private nodeArray!: Array<PriorityQueueNode<T>>
/** Prioritized bucket size. */
private readonly k: number
private readonly bucketSize: number
/** The size of the priority queue. */
public size!: number
/** The maximum size of the priority queue. */
Expand All @@ -30,22 +30,24 @@ export class PriorityQueue<T> {
* The number of filled prioritized buckets.
*/
public get buckets(): number {
return this.k === Infinity ? 1 : Math.trunc(this.nodeArray.length / this.k)
return this.bucketSize === Infinity
? 1
: Math.trunc(this.nodeArray.length / this.bucketSize)
}

/**
* Constructs a priority queue.
*
* @param k - Prioritized bucket size. @defaultValue Infinity
* @param bucketSize - Prioritized bucket size. @defaultValue Infinity
*/
public constructor(k = Infinity) {
if (k !== Infinity && !Number.isSafeInteger(k)) {
throw new TypeError('k must be an integer')
public constructor(bucketSize = Infinity) {
if (bucketSize !== Infinity && !Number.isSafeInteger(bucketSize)) {
throw new TypeError('bucketSize must be an integer')
}
if (k < 1) {
throw new RangeError('k must be greater than or equal to 1')
if (bucketSize < 1) {
throw new RangeError('bucketSize must be greater than or equal to 1')
}
this.k = k
this.bucketSize = bucketSize
this.clear()
}

Expand All @@ -58,7 +60,9 @@ export class PriorityQueue<T> {
*/
public enqueue(data: T, priority?: number): number {
priority = priority ?? 0
const startIndex = this.k === Infinity ? 0 : this.buckets * this.k
const startIndex = this.bucketSize === Infinity
? 0
: this.buckets * this.bucketSize
let inserted = false
for (let index = startIndex; index < this.nodeArray.length; index++) {
if (this.nodeArray[index].priority > priority) {
Expand All @@ -80,9 +84,9 @@ export class PriorityQueue<T> {
* @returns The dequeued data or `undefined` if the priority queue is empty.
*/
public dequeue(bucket = 0): T | undefined {
if (this.k !== Infinity && bucket > 0) {
if (this.bucketSize !== Infinity && bucket > 0) {
while (bucket > 0) {
const index = bucket * this.k
const index = bucket * this.bucketSize
if (this.nodeArray[index] != null) {
;--this.size
return this.nodeArray.splice(index, 1)[0].data
Expand Down
4 changes: 2 additions & 2 deletions tests/pools/abstract-pool.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ Deno.test({
expect(workerNode.tasksQueue).toBeInstanceOf(PriorityQueue)
expect(workerNode.tasksQueue.size).toBe(0)
expect(workerNode.tasksQueue.maxSize).toBe(0)
expect(workerNode.tasksQueue.k).toBe(numberOfWorkers * 2)
expect(workerNode.tasksQueue.bucketSize).toBe(numberOfWorkers * 2)
}
await pool.destroy()
pool = new DynamicThreadPool(
Expand All @@ -839,7 +839,7 @@ Deno.test({
expect(workerNode.tasksQueue).toBeInstanceOf(PriorityQueue)
expect(workerNode.tasksQueue.size).toBe(0)
expect(workerNode.tasksQueue.maxSize).toBe(0)
expect(workerNode.tasksQueue.k).toBe(numberOfWorkers * 2)
expect(workerNode.tasksQueue.bucketSize).toBe(numberOfWorkers * 2)
}
await pool.destroy()
},
Expand Down
2 changes: 1 addition & 1 deletion tests/pools/worker-node.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ Deno.test({
expect(threadWorkerNode.tasksQueueBackPressureSize).toBe(12)
expect(threadWorkerNode.tasksQueue).toBeInstanceOf(PriorityQueue)
expect(threadWorkerNode.tasksQueue.size).toBe(0)
expect(threadWorkerNode.tasksQueue.k).toBe(6)
expect(threadWorkerNode.tasksQueue.bucketSize).toBe(6)
expect(threadWorkerNode.tasksQueueSize()).toBe(
threadWorkerNode.tasksQueue.size,
)
Expand Down
18 changes: 9 additions & 9 deletions tests/priority-queue.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@ import { PriorityQueue } from '../src/priority-queue.ts'
Deno.test('Priority queue test suite', async (t) => {
await t.step('Verify constructor() behavior', () => {
expect(() => new PriorityQueue('')).toThrow(
new TypeError('k must be an integer'),
new TypeError('bucketSize must be an integer'),
)
expect(() => new PriorityQueue(-1)).toThrow(
new RangeError('k must be greater than or equal to 1'),
new RangeError('bucketSize must be greater than or equal to 1'),
)
expect(() => new PriorityQueue(0)).toThrow(
new RangeError('k must be greater than or equal to 1'),
new RangeError('bucketSize must be greater than or equal to 1'),
)
let priorityQueue = new PriorityQueue()
expect(priorityQueue.k).toBe(Infinity)
expect(priorityQueue.bucketSize).toBe(Infinity)
expect(priorityQueue.buckets).toBe(1)
expect(priorityQueue.size).toBe(0)
expect(priorityQueue.maxSize).toBe(0)
expect(priorityQueue.nodeArray).toStrictEqual([])
priorityQueue = new PriorityQueue(2)
expect(priorityQueue.k).toBe(2)
expect(priorityQueue.bucketSize).toBe(2)
expect(priorityQueue.buckets).toBe(0)
expect(priorityQueue.size).toBe(0)
expect(priorityQueue.maxSize).toBe(0)
expect(priorityQueue.nodeArray).toStrictEqual([])
})

await t.step('Verify default k enqueue() behavior', () => {
await t.step('Verify default bucketSize enqueue() behavior', () => {
const priorityQueue = new PriorityQueue()
let rtSize = priorityQueue.enqueue(1)
expect(priorityQueue.buckets).toBe(1)
Expand Down Expand Up @@ -79,7 +79,7 @@ Deno.test('Priority queue test suite', async (t) => {
])
})

await t.step('Verify k=2 enqueue() behavior', () => {
await t.step('Verify bucketSize=2 enqueue() behavior', () => {
const priorityQueue = new PriorityQueue(2)
let rtSize = priorityQueue.enqueue(1)
expect(priorityQueue.buckets).toBe(0)
Expand Down Expand Up @@ -144,7 +144,7 @@ Deno.test('Priority queue test suite', async (t) => {
])
})

await t.step('Verify default k dequeue() behavior', () => {
await t.step('Verify default bucketSize dequeue() behavior', () => {
const priorityQueue = new PriorityQueue()
priorityQueue.enqueue(1)
priorityQueue.enqueue(2, -1)
Expand Down Expand Up @@ -175,7 +175,7 @@ Deno.test('Priority queue test suite', async (t) => {
expect(priorityQueue.nodeArray).toStrictEqual([])
})

await t.step('Verify k=2 dequeue() behavior', () => {
await t.step('Verify bucketSize=2 dequeue() behavior', () => {
const priorityQueue = new PriorityQueue(2)
priorityQueue.enqueue(1)
priorityQueue.enqueue(2)
Expand Down

0 comments on commit 51aa64a

Please sign in to comment.