From 70cfd4d2efba0bd90c9fff4dc8d072f6a8d9a544 Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Sat, 21 Oct 2017 16:13:00 +0200 Subject: [PATCH] collections --- src/structure/collections/hash-set.ts | 1 + src/structure/collections/linked-index.ts | 2 +- src/structure/collections/range-set.ts | 1 + src/structure/spec/collections.spec.ts | 46 ++++++++++++++++++++++- 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/structure/collections/hash-set.ts b/src/structure/collections/hash-set.ts index 8cf25df55..2d13b16c6 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 0f40f2d0d..0433ba03d 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 6543f9428..804340732 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 848ec4803..0b5276b36 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 -- GitLab