1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
- /**
- * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- */
- export class EquivalenceClassesImpl<K, V> {
- private id = 0;
- private byHash = new Map<number, { id: number, keys: K[], value: V }[]>();
- readonly groups: K[][] = [];
- private createGroup(key: K, value: V) {
- const id = this.id++;
- const keys = [key];
- this.groups[id] = keys;
- return { id, keys, value };
- }
- // Return the group representative.
- add(key: K, a: V) {
- const hash = this.getHash(a);
- if (this.byHash.has(hash)) {
- const groups = this.byHash.get(hash)!;
- for (let i = 0, _i = groups.length; i < _i; i++) {
- const group = groups[i];
- if (this.areEqual(a, group.value)) {
- group.keys[group.keys.length] = key;
- return group.value;
- }
- }
- const group = this.createGroup(key, a);
- groups[groups.length] = group;
- return group.value;
- } else {
- const group = this.createGroup(key, a);
- this.byHash.set(hash, [group]);
- return group.value;
- }
- }
- constructor(private getHash: (v: V) => any, private areEqual: (a: V, b: V) => boolean) { }
- }
- export function EquivalenceClasses<K, V>(getHash: (x: V) => any, areEqual: (a: V, b: V) => boolean) {
- return new EquivalenceClassesImpl<K, V>(getHash, areEqual);
- }
|