spica
Version:
Supervisor, Coroutine, Channel, select, AtomicPromise, Cancellation, Cache, List, Queue, Stack, and some utils.
156 lines (136 loc) • 5.03 kB
text/typescript
import { Clock } from './clock';
import { LRU } from './lru';
import { xorshift } from './random';
import zipfian from 'zipfian-integer';
describe('Unit: lib/clock', () => {
describe('Clock', () => {
it('get/set', function () {
const capacity = 96;
const clock = new Clock<number, number>(capacity - 1);
assert(clock['capacity'] === capacity);
for (let i = 0; i < capacity * 2; ++i) {
clock.set(i, i);
}
assert(clock['values'].length === capacity);
for (let i = capacity; i < capacity * 2; ++i) {
assert(clock.get(i) === i);
}
for (let i = 0; i < capacity; ++i) {
clock.set(i, i);
}
for (let i = 0; i < capacity; ++i) {
assert(clock.get(i) === i);
}
});
it('delete', function () {
const capacity = 32;
const clock = new Clock<number, number>(capacity);
for (let i = 0; i < capacity; ++i) {
clock.set(i, i);
}
assert(clock.delete(0) === true);
clock.set(0, 0);
assert(clock.get(1) === 1);
assert(clock.delete(1) === true);
clock.set(1, 1);
assert(clock.get(2) === 2);
assert(clock.delete(2) === true);
clock.set(2, 2);
assert(clock.delete(31) === true);
clock.set(32, 32);
assert(clock.get(3) === 3);
assert(clock.length === 32);
assert(clock.delete(30) === true);
assert(clock.delete(29) === true);
clock.set(33, 33);
clock.set(34, 34);
assert(clock.get(4) === 4);
assert(clock.get(5) === undefined);
assert(clock.length === 31);
});
for (let i = 0; i < 10; ++i) it(`verify ${i}`, function () {
this.timeout(10 * 1e3);
const capacity = 32 * (i % 3 + 1);
const clock = new Clock<number, number>(capacity);
const trials = capacity * 1000;
const random = xorshift.random(i + 1);
for (let i = 0; i < trials; ++i) {
const key = random() * capacity * 2 | 0;
if (clock.has(key)) {
assert(clock.get(key) === ~key);
}
else {
clock.add(key, ~key);
}
assert(clock.length <= capacity);
assert(clock['values'].length === clock.length);
assert(clock['values'].length === clock['dict'].size);
}
assert(clock.length === capacity);
});
class Stats {
clock = 0;
lru = 0;
}
it('even 128', function () {
this.timeout(10 * 1e3);
const capacity = 128;
const clock = new Clock<number, 1>(capacity);
const lru = new LRU<number, 1>(capacity);
const trials = capacity * 1000;
const random = xorshift.random(1);
const stats = new Stats();
for (let i = 0; i < trials; ++i) {
const key = random() * capacity * 10 | 0;
stats.clock += clock.get(key) ?? +clock.set(key, 1) & 0;
stats.lru += lru.get(key) ?? +lru.set(key, 1) & 0;
}
console.debug('Clock even 128');
console.debug('LRU hits', stats.lru);
console.debug('Clock hits', stats.clock);
console.debug('Clock / LRU hit ratio', `${stats.clock / stats.lru * 100 | 0}%`);
assert(stats.clock / stats.lru * 100 >>> 0 === 99);
assert(clock['values'].length === capacity);
});
it('zipf 128', function () {
this.timeout(10 * 1e3);
const capacity = 128;
const clock = new Clock<number, 1>(capacity);
const lru = new LRU<number, 1>(capacity);
const trials = capacity * 1000;
const random = zipfian(1, capacity * 1e3, 0.8, xorshift.random(1));
const stats = new Stats();
for (let i = 0; i < trials; ++i) {
const key = random();
stats.clock += clock.get(key) ?? +clock.set(key, 1) & 0;
stats.lru += lru.get(key) ?? +lru.set(key, 1) & 0;
}
console.debug('Clock zipf 128');
console.debug('LRU hits', stats.lru);
console.debug('Clock hits', stats.clock);
console.debug('Clock / LRU hit ratio', `${stats.clock / stats.lru * 100 | 0}%`);
assert(stats.clock / stats.lru * 100 >>> 0 === 108);
assert(clock['values'].length === capacity);
});
it('zipf 1024', function () {
this.timeout(60 * 1e3);
const capacity = 1024;
const clock = new Clock<number, 1>(capacity);
const lru = new LRU<number, 1>(capacity);
const trials = capacity * 100;
const random = zipfian(1, capacity * 1e3, 0.8, xorshift.random(1));
const stats = new Stats();
for (let i = 0; i < trials; ++i) {
const key = random();
stats.clock += clock.get(key) ?? +clock.set(key, 1) & 0;
stats.lru += lru.get(key) ?? +lru.set(key, 1) & 0;
}
console.debug('Clock zipf 1024');
console.debug('LRU hits', stats.lru);
console.debug('Clock hits', stats.clock);
console.debug('Clock / LRU hit ratio', `${stats.clock / stats.lru * 100 | 0}%`);
assert(stats.clock / stats.lru * 100 >>> 0 === 105);
assert(clock['values'].length === capacity);
});
});
});