UNPKG

spica

Version:

Supervisor, Coroutine, Channel, select, AtomicPromise, Cancellation, Cache, List, Queue, Stack, and some utils.

234 lines (203 loc) 7.55 kB
import { Heap } from './heap'; import { xorshift } from './random'; describe('Unit: lib/heap', () => { describe('Heap', () => { function inspect<T>(heap: Heap<T>) { return Object.values(heap['array']); } it('insert/extract', () => { const heap = new Heap<number>(); assert(heap.extract() === undefined); assert.deepStrictEqual(heap.insert(1, 1), { index: 1, order: 1, value: 1 }); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 1, value: 1 }, ]); assert.deepStrictEqual(heap.insert(2, 2), { index: 1, order: 2, value: 2 }); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 2, value: 2 }, { index: 2, order: 1, value: 1 }, ]); assert.deepStrictEqual(heap.insert(3, 3), { index: 1, order: 3, value: 3 }); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 3, value: 3 }, { index: 2, order: 1, value: 1 }, { index: 3, order: 2, value: 2 }, ]); assert.deepStrictEqual(heap.insert(0, 0), { index: 4, order: 0, value: 0 }); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 3, value: 3 }, { index: 2, order: 1, value: 1 }, { index: 3, order: 2, value: 2 }, { index: 4, order: 0, value: 0 }, ]); assert.deepStrictEqual(heap.insert(11, 11), { index: 1, order: 11, value: 11 }); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 11, value: 11 }, { index: 2, order: 3, value: 3 }, { index: 3, order: 2, value: 2 }, { index: 4, order: 0, value: 0 }, { index: 5, order: 1, value: 1 }, ]); assert.deepStrictEqual(heap.insert(10, 10), { index: 3, order: 10, value: 10 }); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 11, value: 11 }, { index: 2, order: 3, value: 3 }, { index: 3, order: 10, value: 10 }, { index: 4, order: 0, value: 0 }, { index: 5, order: 1, value: 1 }, { index: 6, order: 2, value: 2 }, ]); assert(heap.extract() === 11); assert(heap.extract() === 10); assert(heap.extract() === 3); assert(heap.extract() === 2); assert(heap.extract() === 1); assert(heap.extract() === 0); }); it('replace', () => { const heap = new Heap<number>(); assert(heap.replace(0, 0) === undefined); assert(heap.length === 1); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 0, value: 0 }, ]); assert(heap.replace(1, 1) === 0); assert(heap.length === 1); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 1, value: 1 }, ]); assert.deepStrictEqual(heap.insert(2, 2), { index: 1, order: 2, value: 2 }); assert.deepStrictEqual(heap.insert(3, 3), { index: 1, order: 3, value: 3 }); assert.deepStrictEqual(heap.insert(4, 4), { index: 1, order: 4, value: 4 }); assert.deepStrictEqual(heap.insert(5, 5), { index: 1, order: 5, value: 5 }); assert.deepStrictEqual(heap.insert(6, 6), { index: 1, order: 6, value: 6 }); assert.deepStrictEqual(heap.insert(7, 7), { index: 1, order: 7, value: 7 }); assert(heap.length === 7); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 7, value: 7 }, { index: 2, order: 4, value: 4 }, { index: 3, order: 6, value: 6 }, { index: 4, order: 1, value: 1 }, { index: 5, order: 3, value: 3 }, { index: 6, order: 2, value: 2 }, { index: 7, order: 5, value: 5 }, ]); assert(heap.replace(0, 0) === 7); assert(heap.length === 7); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 6, value: 6 }, { index: 2, order: 4, value: 4 }, { index: 3, order: 5, value: 5 }, { index: 4, order: 1, value: 1 }, { index: 5, order: 3, value: 3 }, { index: 6, order: 2, value: 2 }, { index: 7, order: 0, value: 0 }, ]); }); it('delete', () => { const heap = new Heap<number>(); assert(heap.extract() === undefined); const nodes = [ heap.insert(1, 1), heap.insert(2, 2), heap.insert(3, 3), heap.insert(4, 4), ]; assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 4, value: 4 }, { index: 2, order: 3, value: 3 }, { index: 3, order: 2, value: 2 }, { index: 4, order: 1, value: 1 }, ]); assert.deepStrictEqual(heap.delete(nodes[0]), 1); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 4, value: 4 }, { index: 2, order: 3, value: 3 }, { index: 3, order: 2, value: 2 }, undefined, ]); assert.deepStrictEqual(heap.delete(nodes[2]), 3); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 4, value: 4 }, { index: 2, order: 2, value: 2 }, undefined, undefined, ]); }); it('stable', () => { const heap = new Heap<number>(undefined, { stable: true }); heap.insert(1, 1); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 1, value: 1 }, ]); heap.insert(3, 3); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 3, value: 3 }, { index: 2, order: 1, value: 1 }, ]); heap.insert(2.1, 2); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 3, value: 3 }, { index: 2, order: 1, value: 1 }, { index: 3, order: 2, value: 2.1 }, ]); heap.insert(2.2, 2); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 3, value: 3 }, { index: 2, order: 2, value: 2.2 }, { index: 3, order: 2, value: 2.1 }, { index: 4, order: 1, value: 1 }, ]); assert(heap.extract() === 3); assert(heap.extract() === 2.1); assert(heap.extract() === 2.2); assert(heap.extract() === 1); heap.clear(); const nodes = [ heap.insert(0, 0), heap.insert(1, 0), heap.insert(2, 0), heap.insert(3, 0), heap.insert(4, 0), heap.insert(5, 0), heap.insert(6, 0), ]; assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 0, value: 0 }, { index: 2, order: 0, value: 1 }, { index: 3, order: 0, value: 2 }, { index: 4, order: 0, value: 3 }, { index: 5, order: 0, value: 4 }, { index: 6, order: 0, value: 5 }, { index: 7, order: 0, value: 6 }, ]); heap.update(nodes[1], 0); assert.deepStrictEqual(inspect(heap), [ { index: 1, order: 0, value: 0 }, { index: 2, order: 0, value: 1 }, { index: 3, order: 0, value: 2 }, { index: 4, order: 0, value: 3 }, { index: 5, order: 0, value: 4 }, { index: 6, order: 0, value: 5 }, { index: 7, order: 0, value: 6 }, ]); }); for (let i = 0; i < 20; ++i) it(`verify ${i}`, function () { const heap = new Heap<number>(); const size = 1e4; const random = xorshift.random(3 ** i); for (let i = 0; i < size; ++i) { const ord = random() * 1e6 | 0; heap.insert(ord, ord); } assert(heap.length === size); for (let i = 0, o = Infinity; i < size; ++i) { const node = heap.peek()!; assert(node.order <= o); o = node.order; heap.delete(node); } assert(heap.length === 0); }); }); });