mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-11 02:59:34 -06:00
@@ -511,33 +511,6 @@ suite('CompoundSet', () => {
|
||||
});
|
||||
});
|
||||
|
||||
async function testIntersect(expect: Array<string>, seqs: Array<Array<string>>) {
|
||||
const first = build(db, seqs[0]);
|
||||
const sets:Array<Set> = [];
|
||||
for (let i = 1; i < seqs.length; i++) {
|
||||
sets.push(build(db, seqs[i]));
|
||||
}
|
||||
|
||||
const result = await first.intersect(...sets);
|
||||
const actual = [];
|
||||
await result.forEach(v => { actual.push(v); });
|
||||
assert.deepEqual(expect, actual);
|
||||
}
|
||||
|
||||
test('LONG: intersect', async () => {
|
||||
await testIntersect(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
|
||||
[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
|
||||
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']]);
|
||||
await testIntersect(['a', 'h'], [['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
|
||||
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], ['a', 'h', 'i', 'j', 'k', 'l', 'm', 'n']]);
|
||||
await testIntersect(['d', 'e', 'f', 'g', 'h'], [['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
|
||||
['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k']]);
|
||||
await testIntersect(['h'], [['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
|
||||
['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], ['h', 'i', 'j', 'k', 'l', 'm', 'n', 'o']]);
|
||||
await testIntersect([], [['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
|
||||
['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], ['i', 'j', 'k', 'l', 'm', 'n', 'o', 'p']]);
|
||||
});
|
||||
|
||||
test('iterator at 0', async () => {
|
||||
const test = async (expected, items) => {
|
||||
const set = new Set(items);
|
||||
@@ -679,36 +652,4 @@ suite('CompoundSet', () => {
|
||||
await t(10, SetLeafSequence);
|
||||
await t(100, OrderedMetaSequence);
|
||||
});
|
||||
|
||||
test('Type after mutations - interesect', async () => {
|
||||
async function t(n, c) {
|
||||
const nums: any = intSequence(n);
|
||||
const strings = nums.map(n => String.fromCodePoint(n));
|
||||
const combined = nums.concat(strings);
|
||||
|
||||
const numSet = new Set(nums);
|
||||
assert.equal(numSet.size, n);
|
||||
assert.instanceOf(numSet.sequence, c);
|
||||
assert.isTrue(equals(numSet.type, makeSetType(numberType)));
|
||||
|
||||
const stringSet = new Set(strings);
|
||||
assert.equal(stringSet.size, n);
|
||||
assert.instanceOf(stringSet.sequence, c);
|
||||
assert.isTrue(equals(stringSet.type, makeSetType(stringType)));
|
||||
|
||||
const combinedSet = new Set(combined);
|
||||
assert.equal(combinedSet.size, 2 * n);
|
||||
assert.instanceOf(combinedSet.sequence, c);
|
||||
assert.isTrue(equals(combinedSet.type, makeSetType(makeUnionType([numberType, stringType]))));
|
||||
|
||||
const s = await combinedSet.intersect(numSet);
|
||||
assert.isTrue(equals(s, numSet));
|
||||
|
||||
const s2 = await combinedSet.intersect(stringSet);
|
||||
assert.isTrue(equals(s2, stringSet));
|
||||
}
|
||||
|
||||
await t(10, SetLeafSequence);
|
||||
await t(100, OrderedMetaSequence);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -155,37 +155,6 @@ export default class Set<T: Value> extends Collection<OrderedSequence> {
|
||||
return this.sequence.numLeaves;
|
||||
}
|
||||
|
||||
async intersect(...sets: Array<Set<T>>): Promise<Set<T>> {
|
||||
if (sets.length === 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
let cursor = await this.sequence.newCursorAt(null);
|
||||
if (!cursor.valid) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const values: Array<T> = [];
|
||||
|
||||
for (let i = 0; cursor.valid && i < sets.length; i++) {
|
||||
const first = cursor.getCurrent();
|
||||
const next = await sets[i].sequence.newCursorAt(first);
|
||||
if (!next.valid) {
|
||||
break;
|
||||
}
|
||||
|
||||
cursor = new SetIntersectionCursor(cursor, next);
|
||||
await cursor.align();
|
||||
}
|
||||
|
||||
while (cursor.valid) {
|
||||
values.push(cursor.getCurrent());
|
||||
await cursor.advance();
|
||||
}
|
||||
|
||||
return new Set(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a 2-tuple [added, removed] sorted values.
|
||||
*/
|
||||
@@ -211,63 +180,3 @@ export class SetLeafSequence<K: Value> extends OrderedSequence<K, K> {
|
||||
return getValueChunks(this.items);
|
||||
}
|
||||
}
|
||||
|
||||
type OrderedCursor<K: Value> = {
|
||||
valid: boolean;
|
||||
getCurrent(): K;
|
||||
advanceTo(key: K): Promise<boolean>;
|
||||
advance(): Promise<boolean>;
|
||||
}
|
||||
|
||||
class SetIntersectionCursor<K: Value> {
|
||||
s1: OrderedCursor<K>;
|
||||
s2: OrderedCursor<K>;
|
||||
valid: boolean;
|
||||
|
||||
constructor(s1: OrderedCursor<K>, s2: OrderedCursor<K>) {
|
||||
invariant(s1.valid && s2.valid);
|
||||
this.s1 = s1;
|
||||
this.s2 = s2;
|
||||
this.valid = true;
|
||||
}
|
||||
|
||||
getCurrent(): K {
|
||||
invariant(this.valid);
|
||||
return this.s1.getCurrent();
|
||||
}
|
||||
|
||||
async align(): Promise<boolean> {
|
||||
let v1 = this.s1.getCurrent();
|
||||
let v2 = this.s2.getCurrent();
|
||||
|
||||
let i;
|
||||
while ((i = compare(v1, v2)) !== 0) {
|
||||
if (i < 0) {
|
||||
if (!await this.s1.advanceTo(v2)) {
|
||||
return this.valid = false;
|
||||
}
|
||||
|
||||
v1 = this.s1.getCurrent();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!await this.s2.advanceTo(v1)) {
|
||||
return this.valid = false;
|
||||
}
|
||||
|
||||
v2 = this.s2.getCurrent();
|
||||
}
|
||||
|
||||
return this.valid = true;
|
||||
}
|
||||
|
||||
async advanceTo(key: K): Promise<boolean> {
|
||||
invariant(this.valid);
|
||||
return this.valid = await this.s1.advanceTo(key) && await this.align();
|
||||
}
|
||||
|
||||
async advance(): Promise<boolean> {
|
||||
invariant(this.valid);
|
||||
return this.valid = await this.s1.advance() && await this.align();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user