diff --git a/src/structure/collections/hash-set.ts b/src/structure/collections/hash-set.ts index 8cf25df5585d98566e939beeedf6345de4e86d55..2d13b16c6b15d3837ab29a4720e85372f68ab0a9 100644 --- a/src/structure/collections/hash-set.ts +++ b/src/structure/collections/hash-set.ts @@ -42,6 +42,7 @@ class HashSetImpl<T> implements SetLike<T> { constructor(private getHash: (v: T) => any, private areEqual: (a: T, b: T) => boolean) { } } +// TODO: add implementations with multilevel hashing support? function HashSet<T>(getHash: (v: T) => any, areEqual: (a: T, b: T) => boolean): SetLike<T> { return new HashSetImpl<T>(getHash, areEqual); diff --git a/src/structure/collections/linked-index.ts b/src/structure/collections/linked-index.ts index 0f40f2d0ddafa491cf1a6ef1833c4e20a86379a3..0433ba03de4d1d5b51acab4b9368ac777c1b68ad 100644 --- a/src/structure/collections/linked-index.ts +++ b/src/structure/collections/linked-index.ts @@ -38,7 +38,7 @@ class LinkedIndexImpl implements LinkedIndex { } has(i: number) { - return this.prev[i] >= 0 || this.next[i] >= 0; + return this.prev[i] >= 0 || this.next[i] >= 0 || this.head === i; } constructor(size: number) { diff --git a/src/structure/collections/range-set.ts b/src/structure/collections/range-set.ts index 6543f94287b773d374c525ec7bbcde3a4fdb86b5..8043407324b83c08bdb6fbf9060959e9aecd7015 100644 --- a/src/structure/collections/range-set.ts +++ b/src/structure/collections/range-set.ts @@ -32,6 +32,7 @@ namespace RangeSet { if (size > 2) hash = 31 * hash + a.elementAt(size >> 1); return hash; } + // TODO: possibly add more hash functions to allow for multilevel hashing. export function areEqual(a: RangeSet, b: RangeSet) { if (a === b) return true; diff --git a/src/structure/spec/collections.spec.ts b/src/structure/spec/collections.spec.ts index 848ec48037aa608e95d1f276fcc220b6885427d2..0b5276b3665731197d24d2ac6d4ea53264b16ce1 100644 --- a/src/structure/spec/collections.spec.ts +++ b/src/structure/spec/collections.spec.ts @@ -8,6 +8,7 @@ import Iterator from '../collections/iterator' import IntPair from '../collections/int-pair' import * as Sort from '../collections/sort' import RangeSet from '../collections/range-set' +import LinkedIndex from '../collections/linked-index' describe('basic iterators', () => { function check<T>(name: string, iter: Iterator<T>, expected: T[]) { @@ -102,7 +103,7 @@ describe('qsort-dual array', () => { const cmp: Sort.Comparer<typeof data> = (data, i, j) => data.xs[i] - data.xs[j]; const swap: Sort.Swapper<typeof data> = (data, i, j) => { Sort.arraySwap(data.xs, i, j); Sort.arraySwap(data.ys, i, j); } const clone = (d: typeof data) => ({ xs: [...d.xs], ys: [...d.ys] }) - + function test(name: string, src: typeof data, randomize: boolean) { it(name, () => { // [ 3, 1, 6, 4, 4, 6, 4, 2, 6, 1, 2, 3 ]; @@ -185,4 +186,47 @@ describe('range set', () => { testEq('intersect RR2', RangeSet.intersect(range, RangeSet.ofRange(3, 5)), [3, 4]); testEq('intersect RA', RangeSet.intersect(range, arr), [1, 3]); testEq('intersect AA', RangeSet.intersect(arr, RangeSet.ofSortedArray([2, 3, 4, 6, 7])), [3, 6]); +}); + +describe('linked-index', () => { + it('initial state', () => { + const index = LinkedIndex(2); + expect(index.head).toBe(0); + expect(index.has(0)).toBe(true); + expect(index.has(1)).toBe(true); + }); + + it('singleton', () => { + const index = LinkedIndex(1); + expect(index.head).toBe(0); + expect(index.has(0)).toBe(true); + index.remove(0); + expect(index.head).toBe(-1); + expect(index.has(0)).toBe(false); + }); + + it('remove 0', () => { + const index = LinkedIndex(2); + index.remove(0); + expect(index.head).toBe(1); + expect(index.has(0)).toBe(false); + expect(index.has(1)).toBe(true); + }); + + it('remove 1', () => { + const index = LinkedIndex(2); + index.remove(1); + expect(index.head).toBe(0); + expect(index.has(0)).toBe(true); + expect(index.has(1)).toBe(false); + }); + + it('remove 01', () => { + const index = LinkedIndex(2); + index.remove(0); + index.remove(1); + expect(index.head).toBe(-1); + expect(index.has(0)).toBe(false); + expect(index.has(1)).toBe(false); + }); }); \ No newline at end of file