You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
5.3 KiB
JavaScript

import { Heap } from "../../Source/Cesium.js";
describe("Core/Heap", function () {
var length = 100;
function expectTrailingReferenceToBeRemoved(heap) {
var array = heap._array;
var length = heap._length;
var reservedLength = array.length;
for (var i = length; i < reservedLength; ++i) {
expect(array[i]).toBeUndefined();
}
}
function checkHeap(heap, comparator) {
var array = heap.internalArray;
var pass = true;
var length = heap.length;
for (var i = 0; i < length; ++i) {
var left = 2 * (i + 1) - 1;
var right = 2 * (i + 1);
if (left < heap.length) {
pass = pass && comparator(array[i], array[left]) <= 0;
}
if (right < heap.length) {
pass = pass && comparator(array[i], array[right]) <= 0;
}
}
return pass;
}
// min heap
function comparator(a, b) {
return a - b;
}
it("maintains heap property on insert", function () {
var heap = new Heap({
comparator: comparator,
});
var pass = true;
for (var i = 0; i < length; ++i) {
heap.insert(Math.random());
pass = pass && checkHeap(heap, comparator);
}
expect(pass).toBe(true);
});
it("maintains heap property on pop", function () {
var heap = new Heap({
comparator: comparator,
});
var i;
for (i = 0; i < length; ++i) {
heap.insert(Math.random());
}
var pass = true;
for (i = 0; i < length; ++i) {
heap.pop();
pass = pass && checkHeap(heap, comparator);
}
expect(pass).toBe(true);
});
it("limited by maximum length", function () {
var heap = new Heap({
comparator: comparator,
});
heap.maximumLength = length / 2;
var pass = true;
for (var i = 0; i < length; ++i) {
heap.insert(Math.random());
pass = pass && checkHeap(heap, comparator);
}
expect(pass).toBe(true);
expect(heap.length).toBeLessThanOrEqualTo(heap.maximumLength);
// allowed one extra slot for swapping
expect(heap.internalArray.length).toBeLessThanOrEqualTo(
heap.maximumLength + 1
);
});
it("pops in sorted order", function () {
var heap = new Heap({
comparator: comparator,
});
var i;
for (i = 0; i < length; ++i) {
heap.insert(Math.random());
}
var curr = heap.pop();
var pass = true;
for (i = 0; i < length - 1; ++i) {
var next = heap.pop();
pass = pass && comparator(curr, next) <= 0;
curr = next;
}
expect(pass).toBe(true);
});
it("pop removes trailing references", function () {
var heap = new Heap({
comparator: comparator,
});
for (var i = 0; i < 10; ++i) {
heap.insert(Math.random());
}
heap.pop();
heap.pop();
expectTrailingReferenceToBeRemoved(heap);
});
it("setting maximum length less than current length removes trailing references", function () {
var heap = new Heap({
comparator: comparator,
});
for (var i = 0; i < 10; ++i) {
heap.insert(Math.random());
}
heap.maximumLength = 5;
expectTrailingReferenceToBeRemoved(heap);
});
it("insert returns the removed element when maximumLength is set", function () {
var heap = new Heap({
comparator: comparator,
});
heap.maximumLength = length;
var i;
var max = 0.0;
var min = 1.0;
var values = new Array(length);
for (i = 0; i < length; ++i) {
var value = Math.random();
max = Math.max(max, value);
min = Math.min(min, value);
values[i] = value;
}
// Push 99 values
for (i = 0; i < length - 1; ++i) {
heap.insert(values[i]);
}
// Push 100th, nothing is removed so it returns undefined
var removed = heap.insert(values[length - 1]);
expect(removed).toBeUndefined();
// Insert value, an element is removed
removed = heap.insert(max - 0.1);
expect(removed).toBeDefined();
// If this value is the least priority it will be returned
removed = heap.insert(max + 0.1);
expect(removed).toBe(max + 0.1);
});
it("resort", function () {
function comparator(a, b) {
return a.distance - b.distance;
}
var i;
var heap = new Heap({
comparator: comparator,
});
for (i = 0; i < length; ++i) {
heap.insert({
distance: i / (length - 1),
id: i,
});
}
// Check that elements are initially sorted
var element;
var elements = [];
var currentId = 0;
while (heap.length > 0) {
element = heap.pop();
elements.push(element);
expect(element.id).toBeGreaterThanOrEqualTo(currentId);
currentId = element.id;
}
// Add back into heap
for (i = 0; i < length; ++i) {
heap.insert(elements[i]);
}
// Invert priority
for (i = 0; i < length; ++i) {
elements[i].distance = 1.0 - elements[i].distance;
}
// Resort and check the the elements are popped in the opposite order now
heap.resort();
while (heap.length > 0) {
element = heap.pop();
expect(element.id).toBeLessThanOrEqualTo(currentId);
currentId = element.id;
}
});
it("maximumLength setter throws if length is less than 0", function () {
var heap = new Heap({
comparator: comparator,
});
expect(function () {
heap.maximumLength = -1;
}).toThrowDeveloperError();
});
});