Skip to content
Snippets Groups Projects
Commit 5b6a6915 authored by David Sehnal's avatar David Sehnal
Browse files

tuples

parent fbd7c35f
No related branches found
No related tags found
No related merge requests found
...@@ -10,7 +10,7 @@ import { hash2 } from './hash-functions' ...@@ -10,7 +10,7 @@ import { hash2 } from './hash-functions'
* Represents a pair of two integers as a double, * Represents a pair of two integers as a double,
* Caution: === does not work, because of NaN, use IntTuple.areEqual for equality * Caution: === does not work, because of NaN, use IntTuple.areEqual for equality
*/ */
interface IntTuple extends Number { } interface IntTuple { '@type': 'int-tuple' }
namespace IntTuple { namespace IntTuple {
export interface Unpacked { fst: number, snd: number } export interface Unpacked { fst: number, snd: number }
...@@ -36,17 +36,17 @@ namespace IntTuple { ...@@ -36,17 +36,17 @@ namespace IntTuple {
export function pack(fst: number, snd: number): IntTuple { export function pack(fst: number, snd: number): IntTuple {
_int32[0] = fst; _int32[0] = fst;
_int32[1] = snd; _int32[1] = snd;
return _float64[0]; return _float64[0] as any;
} }
export function pack1(t: Unpacked): IntTuple { export function pack1(t: Unpacked): IntTuple {
_int32[0] = t.fst; _int32[0] = t.fst;
_int32[1] = t.snd; _int32[1] = t.snd;
return _float64[0]; return _float64[0] as any;
} }
export function unpack(t: IntTuple, target: Unpacked): Unpacked { export function unpack(t: IntTuple, target: Unpacked): Unpacked {
_float64[0] = t as number; _float64[0] = t as any;
target.fst = _int32[0]; target.fst = _int32[0];
target.snd = _int32[1]; target.snd = _int32[1];
return target; return target;
...@@ -57,40 +57,40 @@ namespace IntTuple { ...@@ -57,40 +57,40 @@ namespace IntTuple {
} }
export function fst(t: IntTuple): number { export function fst(t: IntTuple): number {
_float64[0] = t as number; _float64[0] = t as any;
return _int32[0]; return _int32[0];
} }
export function snd(t: IntTuple): number { export function snd(t: IntTuple): number {
_float64[0] = t as number; _float64[0] = t as any;
return _int32[1]; return _int32[1];
} }
/** Normal equality does not work, because NaN === NaN ~> false */ /** Normal equality does not work, because NaN === NaN ~> false */
export function areEqual(a: IntTuple, b: IntTuple) { export function areEqual(a: IntTuple, b: IntTuple) {
_float64[0] = a as number; _float64[0] = a as any;
_float64_1[0] = b as number; _float64_1[0] = b as any;
return _int32[0] === _int32_1[0] && _int32[1] === _int32_1[1]; return _int32[0] === _int32_1[0] && _int32[1] === _int32_1[1];
} }
export function compare(a: IntTuple, b: IntTuple) { export function compare(a: IntTuple, b: IntTuple) {
_float64[0] = a as number; _float64[0] = a as any;
_float64_1[0] = b as number; _float64_1[0] = b as any;
const x = _int32[0] - _int32_1[0]; const x = _int32[0] - _int32_1[0];
if (x !== 0) return x; if (x !== 0) return x;
return _int32[1] - _int32_1[1]; return _int32[1] - _int32_1[1];
} }
export function compareInArray(xs: ArrayLike<IntTuple>, i: number, j: number) { export function compareInArray(xs: ArrayLike<IntTuple>, i: number, j: number) {
_float64[0] = xs[i] as number; _float64[0] = xs[i] as any;
_float64_1[0] = xs[j] as number; _float64_1[0] = xs[j] as any;
const x = _int32[0] - _int32_1[0]; const x = _int32[0] - _int32_1[0];
if (x !== 0) return x; if (x !== 0) return x;
return _int32[1] - _int32_1[1]; return _int32[1] - _int32_1[1];
} }
export function hashCode(t: IntTuple) { export function hashCode(t: IntTuple) {
_float64[0] = t as number; _float64[0] = t as any;
return hash2(_int32[0], _int32[1]); return hash2(_int32[0], _int32[1]);
} }
} }
......
...@@ -210,7 +210,7 @@ function valuesI(set: MultiSetImpl): Iterator<IntTuple.Unpacked> { ...@@ -210,7 +210,7 @@ function valuesI(set: MultiSetImpl): Iterator<IntTuple.Unpacked> {
return new ElementsIterator(set as MultiSetElements); return new ElementsIterator(set as MultiSetElements);
} }
function isArrayLike(x: any): x is ArrayLike<number> { function isArrayLike(x: any): x is ArrayLike<IntTuple> {
return x && (typeof x.length === 'number' && (x instanceof Array || !!x.buffer)); return x && (typeof x.length === 'number' && (x instanceof Array || !!x.buffer));
} }
...@@ -321,10 +321,10 @@ function getOffsetIndex(xs: ArrayLike<number>, value: number) { ...@@ -321,10 +321,10 @@ function getOffsetIndex(xs: ArrayLike<number>, value: number) {
return value < xs[min] ? min - 1 : min; return value < xs[min] ? min - 1 : min;
} }
function getAtE(set: MultiSetElements, i: number) { function getAtE(set: MultiSetElements, i: number): IntTuple {
const { offsets, keys } = set; const { offsets, keys } = set;
const o = getOffsetIndex(offsets, i); const o = getOffsetIndex(offsets, i);
if (o >= offsets.length - 1) return 0; if (o >= offsets.length - 1) return 0 as any;
const k = OrderedSet.getAt(keys, o); const k = OrderedSet.getAt(keys, o);
const e = OrderedSet.getAt(set[k], i - offsets[o]); const e = OrderedSet.getAt(set[k], i - offsets[o]);
return IntTuple.pack(k, e); return IntTuple.pack(k, e);
...@@ -480,7 +480,7 @@ function findUnion(sets: ArrayLike<MultiSetImpl>) { ...@@ -480,7 +480,7 @@ function findUnion(sets: ArrayLike<MultiSetImpl>) {
if (typeof s !== 'number') unionInto(ret, s as MultiSetElements); if (typeof s !== 'number') unionInto(ret, s as MultiSetElements);
} }
if (sizeI(ns as MultiSetImpl) > 0) { if (sizeI(ns as MultiSetImpl) > 0) {
if (typeof ns === 'number') unionIntoN(ret, ns); if (typeof ns === 'number') unionIntoN(ret, ns as any);
else unionInto(ret, ns as MultiSetElements); else unionInto(ret, ns as MultiSetElements);
} }
return ofObject(ret); return ofObject(ret);
...@@ -494,14 +494,14 @@ function unionN(sets: ArrayLike<MultiSetImpl>, eCount: { count: number }) { ...@@ -494,14 +494,14 @@ function unionN(sets: ArrayLike<MultiSetImpl>, eCount: { count: number }) {
} }
eCount.count = countE; eCount.count = countE;
if (!countN) return MultiSet.Empty; if (!countN) return MultiSet.Empty;
if (countN === sets.length) return ofTuples(sets as ArrayLike<number>); if (countN === sets.length) return ofTuples(sets as ArrayLike<IntTuple>);
const packed = new Float64Array(countN); const packed = new Float64Array(countN);
let offset = 0; let offset = 0;
for (let i = 0, _i = sets.length; i < _i; i++) { for (let i = 0, _i = sets.length; i < _i; i++) {
const s = sets[i]; const s = sets[i];
if (typeof s === 'number') packed[offset++] = s; if (typeof s === 'number') packed[offset++] = s;
} }
return ofTuples(packed); return ofTuples(packed as any);
} }
function unionInto(data: { [key: number]: OrderedSet }, a: MultiSetElements) { function unionInto(data: { [key: number]: OrderedSet }, a: MultiSetElements) {
......
...@@ -269,7 +269,7 @@ function unionRR(a: Range, b: Range) { ...@@ -269,7 +269,7 @@ function unionRR(a: Range, b: Range) {
if (!sizeA) return b; if (!sizeA) return b;
if (!sizeB) return a; if (!sizeB) return a;
const minA = minR(a), minB = minR(b); const minA = minR(a), minB = minR(b);
if (areRangesIntersecting(a as number, b as number)) return OrderedSet.ofRange(Math.min(minA, minB), Math.max(maxR(a), maxR(b))); if (areRangesIntersecting(a, b)) return OrderedSet.ofRange(Math.min(minA, minB), Math.max(maxR(a), maxR(b)));
let lSize, lMin, rSize, rMin; let lSize, lMin, rSize, rMin;
if (minR(a) < minR(b)) { lSize = sizeA; lMin = minA; rSize = sizeB; rMin = minB; } if (minR(a) < minR(b)) { lSize = sizeA; lMin = minA; rSize = sizeB; rMin = minB; }
else { lSize = sizeB; lMin = minB; rSize = sizeA; rMin = minA; } else { lSize = sizeB; lMin = minB; rSize = sizeA; rMin = minA; }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment