Skip to content
This repository has been archived by the owner on Jan 19, 2021. It is now read-only.

Commit

Permalink
use binary search in the prioritized task executor
Browse files Browse the repository at this point in the history
  • Loading branch information
jochem-brouwer committed Sep 6, 2020
1 parent 0e6e1f7 commit 49beeca
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 17 deletions.
31 changes: 29 additions & 2 deletions src/prioritizedTaskExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,40 @@ export class PrioritizedTaskExecutor {
fn(() => {
this.currentPoolSize--
if (this.queue.length > 0) {
this.queue.sort((a, b) => b.priority - a.priority)
const item = this.queue.shift()
this.execute(item!.priority, item!.fn)
}
})
} else {
this.queue.push({ priority, fn })
if (this.queue.length == 0) {
this.queue.push({ priority, fn })
} else {
// insert the item in the queue using binary search
let left = 0
let right = this.queue.length
let mid = () => {
return Math.floor(left + (right - left) / 2)
}
while (true) {
let index = mid()
let value = this.queue[index].priority
console.log(left, right, index, value)
if (value == priority) {
this.queue.splice(index, 0, { priority, fn })
break
}
if (left == right) {
this.queue.splice(left, 0, { priority, fn })
break
}

if (value > priority) {
left = index
} else {
right = index
}
}
}
}
}

Expand Down
45 changes: 30 additions & 15 deletions test/prioritizedTaskExecutor.spec.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
import * as tape from 'tape'
import { PrioritizedTaskExecutor } from '../src/prioritizedTaskExecutor'

const taskExecutor = new PrioritizedTaskExecutor(2)
tape('prioritized task executor test', function (t: any) {
t.test('should execute tasks in the right order', (st: any) => {
const taskExecutor = new PrioritizedTaskExecutor(2)
const tasks = [1, 2, 3, 4]
const callbacks = [] as any
const executionOrder = [] as any
tasks.forEach(function (task) {
taskExecutor.execute(task, function (cb: Function) {
executionOrder.push(task)
callbacks.push(cb)
})
})

tape('prioritized task executor test', function (t) {
const tasks = [1, 2, 3, 4]
const callbacks = [] as any
const executionOrder = [] as any
tasks.forEach(function (task) {
taskExecutor.execute(task, function (cb: Function) {
executionOrder.push(task)
callbacks.push(cb)
callbacks.forEach(function (callback: Function) {
callback()
})
})

callbacks.forEach(function (callback: Function) {
callback()
const expectedExecutionOrder = [1, 2, 4, 3]
st.deepEqual(executionOrder, expectedExecutionOrder)
st.end()
})

const expectedExecutionOrder = [1, 2, 4, 3]
t.deepEqual(executionOrder, expectedExecutionOrder)
t.end()
t.test('should queue tasks in the right order', (st: any) => {
const priorityList = [0, 1, 0, 2, 0, 1, 0, 2, 2, 1]
const PTE = new PrioritizedTaskExecutor(0) // this ensures that no task actually gets executed, so this essentially just checks the sort algorithm
priorityList.map((priority) => {
PTE.execute(priority, () => {})
})
// have to cast the PTE as <any> to access the private queue
st.deepEqual(
(<any>PTE).queue.map((task: any) => task.priority),
priorityList.sort((a: any, b: any) => b - a),
)
st.end()
})
})

0 comments on commit 49beeca

Please sign in to comment.