UNPKG

ketama

Version:

A hash ring implementation using libketama-like hashing.

87 lines 2.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const assert = require("assert"); const _1 = require("."); const assertProbabilities = (probs, getNodes, delta = 0.05) => { const actual = {}; const samples = 1000; for (let i = 0; i < samples; i++) { for (const value of getNodes(String(i))) { if (!value) { throw new Error('unexpected undefined'); } actual[value] = (actual[value] || 0) + 1 / samples; } } for (const key of Object.keys(probs)) { if (Math.abs(actual[key] - probs[key]) > delta) { console.log('expected:', probs, 'actual:', actual); throw new Error('unexpected probability'); } } }; const assertSingleProbabilities = (r, probs) => assertProbabilities(probs, v => [r.getNode(v)]); it('constructs without weights', () => { assertSingleProbabilities(new _1.HashRing(['a', 'b', 'c']), { a: 1 / 3, b: 1 / 3, c: 1 / 3, }); }); it('constructs with weights', () => { assertSingleProbabilities(new _1.HashRing(['a', 'b', { node: 'c', weight: 2 }]), { a: 1 / 4, b: 1 / 4, c: 1 / 2, }); }); it('adds a node to the ring', () => { const r = new _1.HashRing(['a', 'b', 'c']); r.addNode('d'); assertSingleProbabilities(r, { a: 1 / 4, b: 1 / 4, c: 1 / 4, d: 1 / 4, }); }); it('updates an existing node weight', () => { const r = new _1.HashRing(['a', 'b', 'c']); r.addNode('c', 2); assertSingleProbabilities(r, { a: 1 / 4, b: 1 / 4, c: 1 / 2, }); }); it('removes a node from the ring', () => { const r = new _1.HashRing(['a', 'b', 'c']); r.removeNode('c'); assertSingleProbabilities(r, { a: 1 / 2, b: 1 / 2, }); }); it('no-ops if a node does not exist', () => { const r = new _1.HashRing(['a', 'b', 'c']); r.removeNode('q'); }); it('returns undefined from getNode on empty ring', () => { assert.strictEqual(undefined, new _1.HashRing().getNode('x')); }); it('returns all nodes when replicas insufficient ', () => { assert.deepStrictEqual([], new _1.HashRing().getNodes('x', 2)); assert.deepStrictEqual(['a'], new _1.HashRing(['a']).getNodes('x', 2)); }); it('returns replicas correctly ', () => { assert.deepStrictEqual(['b', 'c'], new _1.HashRing(['a', 'b', 'c']).getNodes('x', 2)); }); it('returns replica with correct probabilities ', () => { const r = new _1.HashRing(['a', 'b', { node: 'c', weight: 2 }]); assertProbabilities({ a: (1 / 4) * 2, b: (1 / 4) * 2, c: (1 / 2) * 2, }, v => r.getNodes(v, 2), 0.15); }); //# sourceMappingURL=index.test.js.map