Merge pull request #1555 from cmasone-attic/dbcleanup

JS: make sure we call close() on Database most of the time
This commit is contained in:
cmasone-attic
2016-05-20 08:18:53 -07:00
22 changed files with 339 additions and 323 deletions
+2
View File
@@ -18,6 +18,7 @@ suite('BatchStore', () => {
const chunk = await bs.get(c.ref);
assert.isTrue(c.ref.equals(chunk.ref));
await bs.close();
});
test('get after schedulePut works after flush', async () => {
@@ -34,5 +35,6 @@ suite('BatchStore', () => {
await bs.flush();
chunk = await bs.get(c.ref);
assert.isTrue(c.ref.equals(chunk.ref));
await bs.close();
});
});
+3 -1
View File
@@ -140,5 +140,7 @@ export default class BatchStore {
// TODO: Should close() call flush() and block until it's done? Maybe closing with outstanding
// requests should be an error on both sides. TBD.
close() {}
close(): Promise<void> {
return this._pendingWrites.destroy();
}
}
+3 -2
View File
@@ -57,7 +57,7 @@ suite('compare.js', () => {
});
test('total ordering', async () => {
const ds = new Database(makeTestingBatchStore());
const db = new Database(makeTestingBatchStore());
// values in increasing order. Some of these are compared by ref so changing the serialization
// might change the ordering.
@@ -67,7 +67,7 @@ suite('compare.js', () => {
'a', 'b', 'c',
// The order of these are done by the hash.
ds.writeValue(10),
db.writeValue(10),
await newSet([0, 1, 2, 3]),
await newMap([[0, 1], [2, 3]]),
boolType,
@@ -91,6 +91,7 @@ suite('compare.js', () => {
}
}
}
await db.close();
});
});
+7
View File
@@ -27,6 +27,7 @@ suite('Database', () => {
const v2 = await ds.readValue(c.ref);
assert.equal('abc', v2);
await ds.close();
});
test('commit', async () => {
@@ -101,6 +102,7 @@ suite('Database', () => {
const newDs = new Database(bs);
assert.strictEqual('d', notNull(await newDs.head(datasetID)).value);
assert.strictEqual('a', notNull(await newDs.head('otherDs')).value);
await ds.close();
});
test('concurrency', async () => {
@@ -139,6 +141,7 @@ suite('Database', () => {
}
assert.strictEqual('Merge needed', message);
assert.strictEqual('c', notNull(await ds.head(datasetID)).value);
await ds.close();
});
@@ -146,6 +149,7 @@ suite('Database', () => {
const ds = new Database(makeTestingBatchStore());
const datasets = await ds.datasets();
assert.strictEqual(0, datasets.size);
await ds.close();
});
test('head', async () => {
@@ -166,6 +170,7 @@ suite('Database', () => {
assert.isTrue(equals(fooHead, commit));
const barHead = await ds.head('bar');
assert.isNull(barHead);
await ds.close();
});
test('height of refs', async () => {
@@ -177,6 +182,7 @@ suite('Database', () => {
const r1 = ds.writeValue(v1);
assert.strictEqual(2, r1.height);
assert.strictEqual(3, ds.writeValue(r1).height);
await ds.close();
});
test('height of collections', async() => {
@@ -213,5 +219,6 @@ suite('Database', () => {
assert.strictEqual(2, ds.writeValue(l4).height);
const l5 = await newList([ds.writeValue(s1), s3]);
assert.strictEqual(2, ds.writeValue(l5).height);
await ds.close();
});
});
+2 -2
View File
@@ -154,8 +154,8 @@ export default class Database {
throw new Error('Optimistic lock failed');
}
close() {
this._vs.close();
close(): Promise<void> {
return this._vs.close();
}
}
+1
View File
@@ -57,5 +57,6 @@ suite('Dataset', () => {
const newStore = new Database(bs);
assert.strictEqual('d', notNull(await newStore.head('ds1')).value);
assert.strictEqual('a', notNull(await newStore.head('otherDs')).value);
await newStore.close();
});
});
+61 -80
View File
@@ -31,10 +31,18 @@ import Map, {newMapLeafSequence} from './map.js';
import Blob, {newBlob} from './blob.js';
// Set is already in use in this file.
import NomsSet, {newSetLeafSequence} from './set.js';
import {suite, test} from 'mocha';
import {suite, setup, teardown, test} from 'mocha';
import {equals} from './compare.js';
suite('Decode', () => {
let db;
setup(() => {
db = new Database(makeTestingBatchStore());
});
teardown((): Promise<void> => db.close());
function stringToUint8Array(s): Uint8Array {
const bytes = new Uint8Array(s.length);
for (let i = 0; i < s.length; i++) {
@@ -52,9 +60,8 @@ suite('Decode', () => {
}
test('read', () => {
const ds = new Database(makeTestingBatchStore());
const a = [1, 'hi', true];
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
assert.strictEqual(1, r.read());
assert.isFalse(r.atEnd());
@@ -67,9 +74,8 @@ suite('Decode', () => {
});
test('read type', () => {
const ds = new Database(makeTestingBatchStore());
function doTest(expected: Type, a: Array<any>) {
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const tr = r.readValue();
assert.isTrue(equals(expected, tr));
}
@@ -86,10 +92,8 @@ suite('Decode', () => {
});
test('read primitives', () => {
const ds = new Database(makeTestingBatchStore());
function doTest(expected: any, a: Array<any>): void {
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v = r.readValue();
assert.deepEqual(expected, v);
}
@@ -106,22 +110,20 @@ suite('Decode', () => {
});
test('read list of number', () => {
const ds = new Database(makeTestingBatchStore());
const a = [Kind.List, Kind.Number, false,
[Kind.Number, '0', Kind.Number, '1', Kind.Number, '2', Kind.Number, '3']];
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: List<number> = r.readValue();
invariant(v instanceof List);
const l = new List(newListLeafSequence(ds, [0, 1, 2, 3]));
const l = new List(newListLeafSequence(db, [0, 1, 2, 3]));
assert.isTrue(equals(l, v));
});
test('read list of mixed types', async () => {
const ds = new Database(makeTestingBatchStore());
const a = [Kind.List, Kind.Union, 3, Kind.Bool, Kind.Number, Kind.String, false,
[Kind.Number, '1', Kind.String, 'hi', Kind.Bool, true]];
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: List<Value> = r.readValue();
invariant(v instanceof List);
@@ -133,10 +135,9 @@ suite('Decode', () => {
});
test('read set of mixed types', async () => {
const ds = new Database(makeTestingBatchStore());
const a = [Kind.Set, Kind.Union, 3, Kind.Bool, Kind.Number, Kind.String, false,
[Kind.Bool, true, Kind.Number, '1', Kind.String, 'hi']];
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: NomsSet<boolean | number | string> = r.readValue();
invariant(v instanceof NomsSet);
@@ -148,7 +149,6 @@ suite('Decode', () => {
});
test('read map of mixed types', async () => {
const ds = new Database(makeTestingBatchStore());
const a = [
Kind.Map, Kind.Union, 2, Kind.Bool, Kind.Number,
Kind.Union, 2, Kind.Number, Kind.String, false, [
@@ -156,7 +156,7 @@ suite('Decode', () => {
Kind.Number, '2', Kind.String, 'hi',
],
];
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: Map<boolean | number, number | string> = r.readValue();
invariant(v instanceof Map);
@@ -168,28 +168,26 @@ suite('Decode', () => {
});
test('read value list of number', () => {
const ds = new Database(makeTestingBatchStore());
const a = [Kind.Value, Kind.List, Kind.Number, false,
[Kind.Number, '0', Kind.Number, '1', Kind.Number, '2']];
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v = r.readValue();
invariant(v instanceof List);
const l = new List(newListLeafSequence(ds, [0, 1, 2]));
const l = new List(newListLeafSequence(db, [0, 1, 2]));
assert.isTrue(equals(l, v));
});
test('read compound list', () => {
const ds = new Database(makeTestingBatchStore());
const r1 = ds.writeValue(new List(newListLeafSequence(ds, [0])));
const r2 = ds.writeValue(new List(newListLeafSequence(ds, [1, 2])));
const r3 = ds.writeValue(new List(newListLeafSequence(ds, [3, 4, 5])));
const r1 = db.writeValue(new List(newListLeafSequence(db, [0])));
const r2 = db.writeValue(new List(newListLeafSequence(db, [1, 2])));
const r3 = db.writeValue(new List(newListLeafSequence(db, [3, 4, 5])));
const tuples = [
new MetaTuple(r1, 1, 1),
new MetaTuple(r2, 2, 2),
new MetaTuple(r3, 3, 3),
];
const l: List<number> = new List(newListMetaSequence(ds, tuples));
const l: List<number> = new List(newListMetaSequence(db, tuples));
const a = [
Kind.List, Kind.Number, true, [
@@ -198,76 +196,71 @@ suite('Decode', () => {
Kind.Ref, Kind.List, Kind.Number, r3.targetRef.toString(), '1', Kind.Number, '3', '3',
],
];
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v = r.readValue();
invariant(v instanceof List);
assert.isTrue(v.ref.equals(l.ref));
});
test('read map of number to number', () => {
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[MapKind, NumberKind, NumberKind, false,
[NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: Map<number, number> = r.readValue();
invariant(v instanceof Map);
const m = new Map(newMapLeafSequence(ds, [[0, 1], [2, 3]]));
const m = new Map(newMapLeafSequence(db, [[0, 1], [2, 3]]));
assert.isTrue(equals(v, m));
});
test('read map of ref to number', () => {
const ds = new Database(makeTestingBatchStore());
const rv1 = ds.writeValue(true);
const rv2 = ds.writeValue('hi');
const rv1 = db.writeValue(true);
const rv2 = db.writeValue('hi');
const a = [
Kind.Map, Kind.Union, 2, Kind.Ref, Kind.String, Kind.Ref, Kind.Bool, Kind.Number, false, [
Kind.Ref, Kind.Bool, rv1.targetRef.toString(), '1', Kind.Number, '2',
Kind.Ref, Kind.String, rv2.targetRef.toString(), '1', Kind.Number, '4',
],
];
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: Map<RefValue<Value>, number> = r.readValue();
invariant(v instanceof Map);
const m = new Map(newMapLeafSequence(ds, [[rv1, 2], [rv2, 4]]));
const m = new Map(newMapLeafSequence(db, [[rv1, 2], [rv2, 4]]));
assert.isTrue(equals(v, m));
});
test('read value map of number to number', () => {
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[ValueKind, MapKind, NumberKind, NumberKind, false,
[NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: Map<number, number> = r.readValue();
invariant(v instanceof Map);
const m = new Map(newMapLeafSequence(ds, [[0, 1], [2, 3]]));
const m = new Map(newMapLeafSequence(db, [[0, 1], [2, 3]]));
assert.isTrue(equals(v, m));
});
test('read set of number', () => {
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[SetKind, NumberKind, false,
[NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: NomsSet<number> = r.readValue();
invariant(v instanceof NomsSet);
const s = new NomsSet(newSetLeafSequence(ds, [0, 1, 2, 3]));
const s = new NomsSet(newSetLeafSequence(db, [0, 1, 2, 3]));
assert.isTrue(equals(v, s));
});
test('read compound set', () => {
const ds = new Database(makeTestingBatchStore());
const r1 = ds.writeValue(new NomsSet(newSetLeafSequence(ds, [0, 1])));
const r2 = ds.writeValue(new NomsSet(newSetLeafSequence(ds, [2, 3, 4])));
const r1 = db.writeValue(new NomsSet(newSetLeafSequence(db, [0, 1])));
const r2 = db.writeValue(new NomsSet(newSetLeafSequence(db, [2, 3, 4])));
const tuples = [
new MetaTuple(r1, 1, 2),
new MetaTuple(r2, 4, 3),
];
const l: NomsSet<number> = new NomsSet(newSetMetaSequence(ds, tuples));
const l: NomsSet<number> = new NomsSet(newSetMetaSequence(db, tuples));
const a = parseJson(`[
SetKind, NumberKind, true, [
@@ -275,21 +268,20 @@ suite('Decode', () => {
RefKind, SetKind, NumberKind, "%s", "1", NumberKind, "4", "3"
]
]`, r1.targetRef.toString(), r2.targetRef.toString());
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v = r.readValue();
invariant(v instanceof NomsSet);
assert.isTrue(v.ref.equals(l.ref));
});
test('read value set of number', () => {
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[ValueKind, SetKind, NumberKind, false,
[NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: NomsSet<number> = r.readValue();
invariant(v instanceof NomsSet);
const s = new NomsSet(newSetLeafSequence(ds, [0, 1, 2, 3]));
const s = new NomsSet(newSetLeafSequence(db, [0, 1, 2, 3]));
assert.isTrue(equals(v, s));
});
@@ -305,7 +297,6 @@ suite('Decode', () => {
}
test('test read struct', () => {
const ds = new Database(makeTestingBatchStore());
const tr = makeStructType('A1', {
'x': numberType,
's': stringType,
@@ -314,7 +305,7 @@ suite('Decode', () => {
const a = parseJson(`[StructKind, "A1", ["b", BoolKind, "s", StringKind, "x", NumberKind],
BoolKind, true, StringKind, "hi", NumberKind, "42"]`);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v = r.readValue();
assertStruct(v, tr.desc, {
@@ -325,7 +316,6 @@ suite('Decode', () => {
});
test('test read struct with list', () => {
const ds = new Database(makeTestingBatchStore());
const ltr = makeListType(numberType);
const tr = makeStructType('A4', {
'b': boolType,
@@ -346,18 +336,17 @@ suite('Decode', () => {
NumberKind, "2"
],
StringKind, "hi"]`);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v = r.readValue();
assertStruct(v, tr.desc, {
b: true,
l: new List(newListLeafSequence(ds, [0, 1, 2])),
l: new List(newListLeafSequence(db, [0, 1, 2])),
s: 'hi',
});
});
test('test read value struct', () => {
const ds = new Database(makeTestingBatchStore());
const tr = makeStructType('A1', {
'x': numberType,
's': stringType,
@@ -375,7 +364,7 @@ suite('Decode', () => {
NumberKind, "42"
]`);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v = r.readValue();
assertStruct(v, tr.desc, {
@@ -386,7 +375,6 @@ suite('Decode', () => {
});
test('test read map of string to struct', async () => {
const ds = new Database(makeTestingBatchStore());
const tr = makeStructType('s', {
'b': boolType,
'i': numberType,
@@ -403,7 +391,7 @@ suite('Decode', () => {
]
]`);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: Map<string, Struct> = r.readValue();
invariant(v instanceof Map);
@@ -414,21 +402,21 @@ suite('Decode', () => {
});
test('decodeNomsValue', () => {
const ds = new Database(makeTestingBatchStore());
const chunk = Chunk.fromString(
`t [${Kind.Value},${Kind.Set},${Kind.Number},false,[${Kind.Number},"0",${
Kind.Number},"1",${Kind.Number},"2",${Kind.Number},"3"]]`);
const v = decodeNomsValue(chunk, new Database(makeTestingBatchStore()));
const v = decodeNomsValue(chunk, db);
invariant(v instanceof NomsSet);
const s: NomsSet<number> = new NomsSet(newSetLeafSequence(ds, [0, 1, 2, 3]));
const s: NomsSet<number> = new NomsSet(newSetLeafSequence(db, [0, 1, 2, 3]));
assert.isTrue(equals(v, s));
});
test('decodeNomsValue: counter with one commit', async () => {
await db.close();
const bs = makeTestingBatchStore();
const ds = new Database(bs);
db = new Database(bs);
const makeChunk = a => Chunk.fromString(`t ${JSON.stringify(a)}`);
@@ -469,16 +457,16 @@ suite('Decode', () => {
bs.schedulePut(rootChunk, new Set());
await bs.flush();
const rootMap = await ds.readValue(rootRef);
const rootMap = await db.readValue(rootRef);
const counterRef = await rootMap.get('counter');
const commit = await counterRef.targetValue(ds);
const commit = await counterRef.targetValue(db);
assert.strictEqual(1, await commit.value);
});
test('out of line blob', async () => {
const chunk = Chunk.fromString('b hi');
const blob = decodeNomsValue(chunk, new Database(makeTestingBatchStore()));
const blob = decodeNomsValue(chunk, db);
invariant(blob instanceof Blob);
const r = await blob.getReader().read();
assert.isFalse(r.done);
@@ -496,7 +484,7 @@ suite('Decode', () => {
}
const chunk2 = new Chunk(data);
const blob2 = decodeNomsValue(chunk2, new Database(makeTestingBatchStore()));
const blob2 = decodeNomsValue(chunk2, db);
invariant(blob2 instanceof Blob);
const r2 = await blob2.getReader().read();
assert.isFalse(r2.done);
@@ -506,11 +494,10 @@ suite('Decode', () => {
});
test('inline blob', async () => {
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[
ListKind, BlobKind, false, [BlobKind, false, "%s", BlobKind, false, "%s"]
]`, encodeBase64(stringToUint8Array('hello')), encodeBase64(stringToUint8Array('world')));
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: List<Blob> = r.readValue();
invariant(v instanceof List);
@@ -523,10 +510,8 @@ suite('Decode', () => {
});
test('compound blob', async () => {
const ds = new Database(makeTestingBatchStore());
const r1 = ds.writeValue(await newBlob(stringToUint8Array('hi')));
const r2 = ds.writeValue(await newBlob(stringToUint8Array('world')));
const r1 = db.writeValue(await newBlob(stringToUint8Array('hi')));
const r2 = db.writeValue(await newBlob(stringToUint8Array('world')));
const a = parseJson(`[
BlobKind, true, [
@@ -534,7 +519,7 @@ suite('Decode', () => {
RefKind, BlobKind, "%s", "1", NumberKind, "5", "5"
]
]`, r1.targetRef, r2.targetRef);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v: Blob = r.readValue();
invariant(v instanceof Blob);
@@ -546,8 +531,6 @@ suite('Decode', () => {
});
test('recursive struct', () => {
const db = new Database(makeTestingBatchStore());
// struct A {
// b: struct B {
// a: List<A>
@@ -599,21 +582,19 @@ suite('Decode', () => {
});
test('read union list', async () => {
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[ListKind, UnionKind, 2, StringKind, NumberKind,
false, [StringKind, "hi", NumberKind, "42"]]`);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v = r.readValue();
const v2 = new List(newListLeafSequence(ds, ['hi', 42]));
const v2 = new List(newListLeafSequence(db, ['hi', 42]));
assert.isTrue(equals(v, v2));
});
test('read empty union list', async () => {
const ds = new Database(makeTestingBatchStore());
const a = parseJson(`[ListKind, UnionKind, 0, false, []]`);
const r = new JsonArrayReader(a, ds);
const r = new JsonArrayReader(a, db);
const v = r.readValue();
const v2 = new List(newListLeafSequence(ds, []));
const v2 = new List(newListLeafSequence(db, []));
assert.isTrue(equals(v, v2));
});
});
+60 -73
View File
@@ -1,7 +1,7 @@
// @flow
import {assert} from 'chai';
import {suite, test} from 'mocha';
import {suite, setup, teardown, test} from 'mocha';
import {makeTestingBatchStore} from './batch-store-adaptor.js';
import Ref from './ref.js';
@@ -32,10 +32,17 @@ import Database from './database.js';
import type {valueOrPrimitive} from './value.js';
suite('Encode', () => {
let db;
setup(() => {
db = new Database(makeTestingBatchStore());
});
teardown((): Promise<void> => db.close());
test('write primitives', () => {
function f(k: NomsKind, v: valueOrPrimitive, ex: valueOrPrimitive) {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
w.writeValue(v);
assert.deepEqual([k, ex], w.array);
}
@@ -53,28 +60,25 @@ suite('Encode', () => {
});
test('write simple blob', async () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const blob = await newBlob(new Uint8Array([0x00, 0x01]));
w.writeValue(blob);
assert.deepEqual([Kind.Blob, false, 'AAE='], w.array);
});
test('write list', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const l = new List(newListLeafSequence(ds, [0, 1, 2, 3]));
const l = new List(newListLeafSequence(db, [0, 1, 2, 3]));
w.writeValue(l);
assert.deepEqual([Kind.List, Kind.Number, false,
[Kind.Number, '0', Kind.Number, '1', Kind.Number, '2', Kind.Number, '3']], w.array);
});
test('write list of value', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const l = new List(newListLeafSequence(ds, ['0', 1, '2', true]));
const l = new List(newListLeafSequence(db, ['0', 1, '2', true]));
w.writeValue(l);
assert.deepEqual([Kind.List, Kind.Union, 3, Kind.Bool, Kind.Number, Kind.String, false, [
Kind.String, '0',
@@ -85,12 +89,11 @@ suite('Encode', () => {
});
test('write list of list', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const v = new List(newListLeafSequence(ds, [
new List(newListLeafSequence(ds, [0])),
new List(newListLeafSequence(ds, [1, 2, 3])),
const v = new List(newListLeafSequence(db, [
new List(newListLeafSequence(db, [0])),
new List(newListLeafSequence(db, [1, 2, 3])),
]));
w.writeValue(v);
assert.deepEqual([Kind.List, Kind.List, Kind.Number, false, [
@@ -100,27 +103,25 @@ suite('Encode', () => {
});
test('write leaf set', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const v = new Set(newSetLeafSequence(ds, [0, 1, 2, 3]));
const v = new Set(newSetLeafSequence(db, [0, 1, 2, 3]));
w.writeValue(v);
assert.deepEqual([Kind.Set, Kind.Number, false,
[Kind.Number, '0', Kind.Number, '1', Kind.Number, '2', Kind.Number, '3']], w.array);
});
test('write compound set', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const r1 = ds.writeValue(new Set(newSetLeafSequence(ds, [0])));
const r2 = ds.writeValue(new Set(newSetLeafSequence(ds, [1, 2])));
const r3 = ds.writeValue(new Set(newSetLeafSequence(ds, [3, 4, 5])));
const w = new JsonArrayWriter(db);
const r1 = db.writeValue(new Set(newSetLeafSequence(db, [0])));
const r2 = db.writeValue(new Set(newSetLeafSequence(db, [1, 2])));
const r3 = db.writeValue(new Set(newSetLeafSequence(db, [3, 4, 5])));
const tuples = [
new MetaTuple(r1, 0, 1),
new MetaTuple(r2, 2, 2),
new MetaTuple(r3, 5, 3),
];
const l = new Set(newSetMetaSequence(ds, tuples));
const l = new Set(newSetMetaSequence(db, tuples));
w.writeValue(l);
assert.deepEqual([
@@ -133,12 +134,11 @@ suite('Encode', () => {
});
test('write set of set', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const v = new Set(newSetLeafSequence(ds, [
new Set(newSetLeafSequence(ds, [0])),
new Set(newSetLeafSequence(ds, [1, 2, 3])),
const v = new Set(newSetLeafSequence(db, [
new Set(newSetLeafSequence(db, [0])),
new Set(newSetLeafSequence(db, [1, 2, 3])),
]));
w.writeValue(v);
@@ -149,23 +149,21 @@ suite('Encode', () => {
});
test('write map', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const v = new Map(newMapLeafSequence(ds, [['a', false], ['b', true]]));
const v = new Map(newMapLeafSequence(db, [['a', false], ['b', true]]));
w.writeValue(v);
assert.deepEqual([Kind.Map, Kind.String, Kind.Bool, false,
[Kind.String, 'a', Kind.Bool, false, Kind.String, 'b', Kind.Bool, true]], w.array);
});
test('write map of map', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
// Map<Map<String, Number>, Set<Bool>>({{'a': 0}: {true}})
const s = new Set(newSetLeafSequence(ds, [true]));
const m1 = new Map(newMapLeafSequence(ds, [['a', 0]]));
const v = new Map(newMapLeafSequence(ds, [[m1, s]]));
const s = new Set(newSetLeafSequence(db, [true]));
const m1 = new Map(newMapLeafSequence(db, [['a', 0]]));
const v = new Map(newMapLeafSequence(db, [[m1, s]]));
w.writeValue(v);
assert.deepEqual([Kind.Map,
Kind.Map, Kind.String, Kind.Number,
@@ -175,8 +173,7 @@ suite('Encode', () => {
});
test('write empty struct', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const v = newStruct('S', {});
@@ -185,8 +182,7 @@ suite('Encode', () => {
});
test('write struct', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const v = newStruct('S', {x: 42, b: true});
w.writeValue(v);
@@ -195,24 +191,22 @@ suite('Encode', () => {
});
test('write struct with list', () => {
const ds = new Database(makeTestingBatchStore());
let w = new JsonArrayWriter(ds);
let w = new JsonArrayWriter(db);
let v = newStruct('S', {l: new List(newListLeafSequence(ds, ['a', 'b']))});
let v = newStruct('S', {l: new List(newListLeafSequence(db, ['a', 'b']))});
w.writeValue(v);
assert.deepEqual([Kind.Struct, 'S', ['l', Kind.List, Kind.String],
Kind.List, Kind.String, false, [Kind.String, 'a', Kind.String, 'b']], w.array);
v = newStruct('S', {l: new List(newListLeafSequence(ds, []))});
w = new JsonArrayWriter(ds);
v = newStruct('S', {l: new List(newListLeafSequence(db, []))});
w = new JsonArrayWriter(db);
w.writeValue(v);
assert.deepEqual([Kind.Struct, 'S', ['l', Kind.List, Kind.Union, 0],
Kind.List, Kind.Union, 0, false, []], w.array);
});
test('write struct with struct', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const v = newStruct('S', {s: newStruct('S2', {x: 42})});
w.writeValue(v);
@@ -222,17 +216,16 @@ suite('Encode', () => {
});
test('write compound list', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const r1 = ds.writeValue(new List(newListLeafSequence(ds, [0])));
const r2 = ds.writeValue(new List(newListLeafSequence(ds, [1, 2])));
const r3 = ds.writeValue(new List(newListLeafSequence(ds, [3, 4, 5])));
const w = new JsonArrayWriter(db);
const r1 = db.writeValue(new List(newListLeafSequence(db, [0])));
const r2 = db.writeValue(new List(newListLeafSequence(db, [1, 2])));
const r3 = db.writeValue(new List(newListLeafSequence(db, [3, 4, 5])));
const tuples = [
new MetaTuple(r1, 1, 1),
new MetaTuple(r2, 2, 2),
new MetaTuple(r3, 3, 3),
];
const l = new List(newListMetaSequence(ds, tuples));
const l = new List(newListMetaSequence(db, tuples));
w.writeValue(l);
assert.deepEqual([
@@ -245,15 +238,14 @@ suite('Encode', () => {
});
test('write compound set with bool', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const r1 = ds.writeValue(new Set(newSetLeafSequence(ds, [true])));
const r2 = ds.writeValue(new Set(newSetLeafSequence(ds, [false])));
const w = new JsonArrayWriter(db);
const r1 = db.writeValue(new Set(newSetLeafSequence(db, [true])));
const r2 = db.writeValue(new Set(newSetLeafSequence(db, [false])));
const tuples = [
new MetaTuple(r1, true, 1),
new MetaTuple(r2, false, 1),
];
const l = new Set(newSetMetaSequence(ds, tuples));
const l = new Set(newSetMetaSequence(db, tuples));
w.writeValue(l);
assert.deepEqual([
@@ -265,10 +257,9 @@ suite('Encode', () => {
});
test('write type value', () => {
const ds = new Database(makeTestingBatchStore());
const test = (expected: Array<any>, v: Type) => {
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
w.writeValue(v);
assert.deepEqual(w.array, expected);
};
@@ -313,10 +304,9 @@ suite('Encode', () => {
return bytes;
}
const ds = new Database(makeTestingBatchStore());
const blob = await newBlob(stringToUint8Array('hi'));
const chunk = encodeNomsValue(blob, ds);
const chunk = encodeNomsValue(blob, db);
assert.equal(4, chunk.data.length);
assert.deepEqual(stringToUint8Array('b hi'), chunk.data);
@@ -330,14 +320,13 @@ suite('Encode', () => {
view.setUint8(2 + i, i);
}
const blob2 = await newBlob(bytes);
const chunk2 = encodeNomsValue(blob2, ds);
const chunk2 = encodeNomsValue(blob2, db);
assert.equal(buffer2.byteLength, chunk2.data.buffer.byteLength);
assert.deepEqual(buffer2, chunk2.data.buffer);
});
test('write ref', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const w = new JsonArrayWriter(db);
const ref = Ref.parse('sha1-0123456789abcdef0123456789abcdef01234567');
const t = makeRefType(blobType);
const v = constructRefValue(t, ref, 1);
@@ -347,18 +336,16 @@ suite('Encode', () => {
});
test('write union list', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const v = new List(newListLeafSequence(ds, ['hi', 42]));
const w = new JsonArrayWriter(db);
const v = new List(newListLeafSequence(db, ['hi', 42]));
w.writeValue(v);
assert.deepEqual([Kind.List, Kind.Union, 2, Kind.Number, Kind.String,
false, [Kind.String, 'hi', Kind.Number, '42']], w.array);
});
test('write empty union list', () => {
const ds = new Database(makeTestingBatchStore());
const w = new JsonArrayWriter(ds);
const v = new List(newListLeafSequence(ds, []));
const w = new JsonArrayWriter(db);
const v = new List(newListLeafSequence(db, []));
w.writeValue(v);
assert.deepEqual([Kind.List, Kind.Union, 0, false, []], w.array);
});
+36 -26
View File
@@ -1,7 +1,7 @@
// @flow
import {assert} from 'chai';
import {suite, test} from 'mocha';
import {suite, setup, teardown, test} from 'mocha';
import Database from './database.js';
import {makeTestingBatchStore} from './batch-store-adaptor.js';
@@ -194,12 +194,12 @@ suite('List', () => {
});
test('LONG: write, read, modify, read', async () => {
const ds = new Database(makeTestingBatchStore());
const db = new Database(makeTestingBatchStore());
const nums = intSequence(testListSize);
const s = await newList(nums);
const r = ds.writeValue(s).targetRef;
const s2 = await ds.readValue(r);
const r = db.writeValue(s).targetRef;
const s2 = await db.readValue(r);
const outNums = await s2.toJS();
assert.deepEqual(nums, outNums);
@@ -208,21 +208,27 @@ suite('List', () => {
const outNums2 = await s3.toJS();
nums.splice(testListSize - 1, 1);
assert.deepEqual(nums, outNums2);
await db.close();
});
});
suite('ListLeafSequence', () => {
let db;
setup(() => {
db = new Database(makeTestingBatchStore());
});
teardown((): Promise<void> => db.close());
test('Empty list isEmpty', () => {
const ds = new Database(makeTestingBatchStore());
const newList = items => new List(newListLeafSequence(ds, items));
const newList = items => new List(newListLeafSequence(db, items));
assert.isTrue(newList([]).isEmpty());
});
test('iterator', async () => {
const ds = new Database(makeTestingBatchStore());
const test = async items => {
const l = new List(newListLeafSequence(ds, items));
const l = new List(newListLeafSequence(db, items));
assert.deepEqual(items, await flatten(l.iterator()));
assert.deepEqual(items, await flattenParallel(l.iterator(), items.length));
};
@@ -233,10 +239,8 @@ suite('ListLeafSequence', () => {
});
test('iteratorAt', async () => {
const ds = new Database(makeTestingBatchStore());
const test = async items => {
const l = new List(newListLeafSequence(ds, items));
const l = new List(newListLeafSequence(db, items));
for (let i = 0; i <= items.length; i++) {
const slice = items.slice(i);
assert.deepEqual(slice, await flatten(l.iteratorAt(i)));
@@ -251,25 +255,31 @@ suite('ListLeafSequence', () => {
});
suite('CompoundList', () => {
let db;
setup(() => {
db = new Database(makeTestingBatchStore());
});
teardown((): Promise<void> => db.close());
function build(): List {
const ds = new Database(makeTestingBatchStore());
const l1 = new List(newListLeafSequence(ds, ['a', 'b']));
const r1 = ds.writeValue(l1);
const l2 = new List(newListLeafSequence(ds, ['e', 'f']));
const r2 = ds.writeValue(l2);
const l3 = new List(newListLeafSequence(ds, ['h', 'i']));
const r3 = ds.writeValue(l3);
const l4 = new List(newListLeafSequence(ds, ['m', 'n']));
const r4 = ds.writeValue(l4);
const l1 = new List(newListLeafSequence(db, ['a', 'b']));
const r1 = db.writeValue(l1);
const l2 = new List(newListLeafSequence(db, ['e', 'f']));
const r2 = db.writeValue(l2);
const l3 = new List(newListLeafSequence(db, ['h', 'i']));
const r3 = db.writeValue(l3);
const l4 = new List(newListLeafSequence(db, ['m', 'n']));
const r4 = db.writeValue(l4);
const m1 = new List(newListMetaSequence(ds, [new MetaTuple(r1, 2, 2),
const m1 = new List(newListMetaSequence(db, [new MetaTuple(r1, 2, 2),
new MetaTuple(r2, 2, 2)]));
const rm1 = ds.writeValue(m1);
const m2 = new List(newListMetaSequence(ds, [new MetaTuple(r3, 2, 2),
const rm1 = db.writeValue(m1);
const m2 = new List(newListMetaSequence(db, [new MetaTuple(r3, 2, 2),
new MetaTuple(r4, 2, 2)]));
const rm2 = ds.writeValue(m2);
const rm2 = db.writeValue(m2);
const l = new List(newListMetaSequence(ds, [new MetaTuple(rm1, 4, 4),
const l = new List(newListMetaSequence(db, [new MetaTuple(rm1, 4, 4),
new MetaTuple(rm2, 4, 4)]));
return l;
}
+50 -50
View File
@@ -1,7 +1,7 @@
// @flow
import {assert} from 'chai';
import {suite, test} from 'mocha';
import {suite, setup, teardown, test} from 'mocha';
import Database from './database.js';
import MemoryStore from './memory-store.js';
@@ -151,7 +151,7 @@ suite('BuildMap', () => {
});
test('LONG: write, read, modify, read', async () => {
const ds = new Database(makeTestingBatchStore());
const db = new Database(makeTestingBatchStore());
const kvs = [];
for (let i = 0; i < testMapSize; i++) {
@@ -160,8 +160,8 @@ suite('BuildMap', () => {
const m = await newMap(kvs);
const r = ds.writeValue(m).targetRef;
const m2 = await ds.readValue(r);
const r = db.writeValue(m).targetRef;
const m2 = await db.readValue(r);
const outKvs = [];
await m2.forEach((v, k) => outKvs.push([k, v]));
assert.deepEqual(kvs, outKvs);
@@ -174,10 +174,11 @@ suite('BuildMap', () => {
kvs.splice(testMapSize * 1 - 1, 1);
assert.deepEqual(kvs, outKvs2);
assert.strictEqual(testMapSize - 1, m3.size);
await db.close();
});
test('LONG: union write, read, modify, read', async () => {
const ds = new Database(makeTestingBatchStore());
const db = new Database(makeTestingBatchStore());
const keys = [];
const kvs = [];
@@ -214,8 +215,8 @@ suite('BuildMap', () => {
assert.isTrue(await m.has(keys[i]));
}
const r = ds.writeValue(m).targetRef;
const m2 = await ds.readValue(r);
const r = db.writeValue(m).targetRef;
const m2 = await db.readValue(r);
const outVals = [];
const outKeys = [];
await m2.forEach((v, k) => {
@@ -258,14 +259,22 @@ suite('BuildMap', () => {
const v = await m3.get(k);
assertEqualVal(k, v);
}
await db.close();
});
});
suite('MapLeaf', () => {
let db;
setup(() => {
db = new Database(makeTestingBatchStore());
});
teardown((): Promise<void> => db.close());
test('isEmpty/size', () => {
const ds = new Database(makeTestingBatchStore());
const newMap = entries => new Map(newMapLeafSequence(ds, entries));
const newMap = entries => new Map(newMapLeafSequence(db, entries));
let m = newMap([]);
assert.isTrue(m.isEmpty());
assert.strictEqual(0, m.size);
@@ -275,9 +284,8 @@ suite('MapLeaf', () => {
});
test('has', async () => {
const ds = new Database(makeTestingBatchStore());
const m = new Map(
newMapLeafSequence(ds, [['a', false], ['k', true]]));
newMapLeafSequence(db, [['a', false], ['k', true]]));
assert.isTrue(await m.has('a'));
assert.isFalse(await m.has('b'));
assert.isTrue(await m.has('k'));
@@ -285,9 +293,7 @@ suite('MapLeaf', () => {
});
test('first/last/get', async () => {
const ds = new Database(makeTestingBatchStore());
const m = new Map(
newMapLeafSequence(ds, [['a', 4], ['k', 8]]));
const m = new Map(newMapLeafSequence(db, [['a', 4], ['k', 8]]));
assert.deepEqual(['a', 4], await m.first());
assert.deepEqual(['k', 8], await m.last());
@@ -299,9 +305,7 @@ suite('MapLeaf', () => {
});
test('forEach', async () => {
const ds = new Database(makeTestingBatchStore());
const m = new Map(
newMapLeafSequence(ds, [['a', 4], ['k', 8]]));
const m = new Map(newMapLeafSequence(db, [['a', 4], ['k', 8]]));
const kv = [];
await m.forEach((v, k) => { kv.push(k, v); });
@@ -309,10 +313,9 @@ suite('MapLeaf', () => {
});
test('iterator', async () => {
const ds = new Database(makeTestingBatchStore());
const test = async entries => {
const m = new Map(newMapLeafSequence(ds, entries));
const m = new Map(newMapLeafSequence(db, entries));
assert.deepEqual(entries, await flatten(m.iterator()));
assert.deepEqual(entries, await flattenParallel(m.iterator(), entries.length));
};
@@ -323,8 +326,7 @@ suite('MapLeaf', () => {
});
test('LONG: iteratorAt', async () => {
const ds = new Database(makeTestingBatchStore());
const build = entries => new Map(newMapLeafSequence(ds, entries));
const build = entries => new Map(newMapLeafSequence(db, entries));
assert.deepEqual([], await flatten(build([]).iteratorAt('a')));
@@ -346,13 +348,12 @@ suite('MapLeaf', () => {
});
test('chunks', () => {
const ds = new Database(makeTestingBatchStore());
const r1 = ds.writeValue('x');
const r2 = ds.writeValue(true);
const r3 = ds.writeValue('b');
const r4 = ds.writeValue(false);
const m = new Map(
newMapLeafSequence(ds, [[r1, r2], [r3, r4]]));
const r1 = db.writeValue('x');
const r2 = db.writeValue(true);
const r3 = db.writeValue('b');
const r4 = db.writeValue(false);
const m = new Map(newMapLeafSequence(db, [[r1, r2], [r3, r4]]));
assert.strictEqual(4, m.chunks.length);
assert.isTrue(equals(r1, m.chunks[0]));
assert.isTrue(equals(r2, m.chunks[1]));
@@ -363,6 +364,14 @@ suite('MapLeaf', () => {
});
suite('CompoundMap', () => {
let db;
setup(() => {
db = new Database(makeTestingBatchStore());
});
teardown((): Promise<void> => db.close());
function build(vwr: ValueReadWriter): Array<Map> {
const l1 = new Map(newMapLeafSequence(vwr, [['a', false], ['b', false]]));
const r1 = vwr.writeValue(l1);
@@ -386,15 +395,13 @@ suite('CompoundMap', () => {
}
test('isEmpty/size', () => {
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const [c] = build(db);
assert.isFalse(c.isEmpty());
assert.strictEqual(8, c.size);
});
test('get', async () => {
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const [c] = build(db);
assert.strictEqual(false, await c.get('a'));
assert.strictEqual(false, await c.get('b'));
@@ -413,8 +420,7 @@ suite('CompoundMap', () => {
});
test('first/last/has', async () => {
const ds = new Database(makeTestingBatchStore());
const [c, m1, m2] = build(ds);
const [c, m1, m2] = build(db);
assert.deepEqual(['a', false], await c.first());
assert.deepEqual(['n', false], await c.last());
@@ -440,8 +446,7 @@ suite('CompoundMap', () => {
});
test('forEach', async () => {
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const [c] = build(db);
const kv = [];
await c.forEach((v, k) => { kv.push(k, v); });
@@ -450,8 +455,7 @@ suite('CompoundMap', () => {
});
test('iterator', async () => {
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const [c] = build(db);
const expected = [['a', false], ['b', false], ['e', true], ['f', true], ['h', false],
['i', true], ['m', true], ['n', false]];
assert.deepEqual(expected, await flatten(c.iterator()));
@@ -459,8 +463,7 @@ suite('CompoundMap', () => {
});
test('LONG: iteratorAt', async () => {
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const [c] = build(db);
const entries = [['a', false], ['b', false], ['e', true], ['f', true], ['h', false],
['i', true], ['m', true], ['n', false]];
const offsets = {
@@ -482,8 +485,7 @@ suite('CompoundMap', () => {
});
test('iterator return', async () => {
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const [c] = build(db);
const iter = c.iterator();
const values = [];
for (let res = await iter.next(); !res.done; res = await iter.next()) {
@@ -497,8 +499,7 @@ suite('CompoundMap', () => {
});
test('iterator return parallel', async () => {
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const [c] = build(db);
const iter = c.iterator();
const values = await Promise.all([iter.next(), iter.next(), iter.return(), iter.next()]);
assert.deepEqual([{done: false, value: ['a', false]},
@@ -508,8 +509,7 @@ suite('CompoundMap', () => {
});
test('chunks', () => {
const ds = new Database(makeTestingBatchStore());
const [c] = build(ds);
const [c] = build(db);
assert.strictEqual(2, c.chunks.length);
});
@@ -545,13 +545,14 @@ suite('CompoundMap', () => {
}
const ms = new CountingMemoryStore();
const ds = new Database(new BatchStore(3, new BatchStoreAdaptorDelegate(ms)));
[m1, m2] = await Promise.all([m1, m2].map(s => ds.readValue(ds.writeValue(s).targetRef)));
const db = new Database(new BatchStore(3, new BatchStoreAdaptorDelegate(ms)));
[m1, m2] = await Promise.all([m1, m2].map(s => db.readValue(db.writeValue(s).targetRef)));
assert.deepEqual([[], [], []], await m1.diff(m1));
assert.deepEqual([[], [], []], await m2.diff(m2));
assert.deepEqual([removed, added, modified], await m1.diff(m2));
assert.deepEqual([added, removed, modified], await m2.diff(m1));
await db.close();
}
async function testSmallRandomDiff(inM1: number, inM2: number, inBoth: number) {
@@ -595,8 +596,7 @@ suite('CompoundMap', () => {
test('LONG: random map diff 0.1/0.9/0', () => testRandomDiff(randomMapSize, 0.1, 0.9, 0));
test('chunks', () => {
const ds = new Database(makeTestingBatchStore());
const m = build(ds)[1];
const m = build(db)[1];
const chunks = m.chunks;
const sequence = m.sequence;
assert.equal(2, chunks.length);
+13 -9
View File
@@ -1,7 +1,7 @@
// @flow
import {assert} from 'chai';
import {suite, test} from 'mocha';
import {suite, setup, teardown, test} from 'mocha';
import {makeTestingBatchStore} from './batch-store-adaptor.js';
import Database from './database.js';
@@ -13,11 +13,17 @@ import Set, {newSetLeafSequence} from './set.js';
import {Kind} from './noms-kind.js';
suite('MetaSequence', () => {
test('calculate ordered sequence MetaTuple height', async () => {
const ds = new Database(makeTestingBatchStore());
let db;
const set1 = new Set(newSetLeafSequence(ds, ['bar', 'baz']));
const set2 = new Set(newSetLeafSequence(ds, ['foo', 'qux', 'zoo']));
setup(() => {
db = new Database(makeTestingBatchStore());
});
teardown((): Promise<void> => db.close());
test('calculate ordered sequence MetaTuple height', async () => {
const set1 = new Set(newSetLeafSequence(db, ['bar', 'baz']));
const set2 = new Set(newSetLeafSequence(db, ['foo', 'qux', 'zoo']));
const mt1 = new MetaTuple(new RefValue(set1), 'baz', 2, set1);
const mt2 = new MetaTuple(new RefValue(set2), 'zoo', 3, set2);
@@ -34,10 +40,8 @@ suite('MetaSequence', () => {
});
test('calculate indexed sequence MetaTuple height', async () => {
const ds = new Database(makeTestingBatchStore());
const list1 = new List(newListLeafSequence(ds, ['bar', 'baz']));
const list2 = new List(newListLeafSequence(ds, ['foo', 'qux', 'zoo']));
const list1 = new List(newListLeafSequence(db, ['bar', 'baz']));
const list2 = new List(newListLeafSequence(db, ['foo', 'qux', 'zoo']));
const mt1 = new MetaTuple(new RefValue(list1), 2, 2, list1);
const mt2 = new MetaTuple(new RefValue(list2), 3, 3, list2);
+2
View File
@@ -38,7 +38,9 @@ export default class OrderedPutCache {
}
_init(): Promise<DbCollection> {
// invariant(false === true);
return makeTempDir().then((dir): Promise<DbCollection> => {
// console.log('creating', dir);
this._folder = dir;
const coll = new DbCollection(dir);
return coll.ensureIndex({hash: 1}, {unique: true}).then(() => coll);
+53 -59
View File
@@ -1,7 +1,7 @@
// @flow
import {assert} from 'chai';
import {suite, test} from 'mocha';
import {suite, setup, teardown, test} from 'mocha';
import Chunk from './chunk.js';
import Database from './database.js';
@@ -128,12 +128,12 @@ suite('BuildSet', () => {
});
test('LONG: write, read, modify, read', async () => {
const ds = new Database(makeTestingBatchStore());
const db = new Database(makeTestingBatchStore());
const nums = firstNNumbers(testSetSize);
const s = await newSet(nums);
const r = ds.writeValue(s).targetRef;
const s2 = await ds.readValue(r);
const r = db.writeValue(s).targetRef;
const s2 = await db.readValue(r);
const outNums = [];
await s2.forEach(k => outNums.push(k));
assert.deepEqual(nums, outNums);
@@ -146,11 +146,12 @@ suite('BuildSet', () => {
nums.splice(testSetSize - 1, 1);
assert.deepEqual(nums, outNums2);
assert.strictEqual(testSetSize - 1, s3.size);
await db.close();
});
test('LONG: union write, read, modify, read', async () => {
const ds = new Database(makeTestingBatchStore());
const db = new Database(makeTestingBatchStore());
const tmp = firstNNumbers(testSetSize);
const numbers = [];
@@ -185,8 +186,8 @@ suite('BuildSet', () => {
assert.isTrue(await s.has(vals1[i]));
}
const r = ds.writeValue(s).targetRef;
const s2 = await ds.readValue(r);
const r = db.writeValue(s).targetRef;
const s2 = await db.readValue(r);
const outVals = [];
await s2.forEach(k => outVals.push(k));
assert.equal(testSetSize, s2.size);
@@ -203,13 +204,21 @@ suite('BuildSet', () => {
for (let i = vals2.length - 1; i >= 0; i -= 5) {
assert.isTrue(equals(vals2[i], outVals2[i]));
}
await db.close();
});
});
suite('SetLeaf', () => {
let db;
setup(() => {
db = new Database(makeTestingBatchStore());
});
teardown((): Promise<void> => db.close());
test('isEmpty/size', () => {
const ds = new Database(makeTestingBatchStore());
const newSet = items => new Set(newSetLeafSequence(ds, items));
const newSet = items => new Set(newSetLeafSequence(db, items));
let s = newSet([]);
assert.isTrue(s.isEmpty());
assert.strictEqual(0, s.size);
@@ -219,8 +228,7 @@ suite('SetLeaf', () => {
});
test('first/last/has', async () => {
const ds = new Database(makeTestingBatchStore());
const s = new Set(newSetLeafSequence(ds, ['a', 'k']));
const s = new Set(newSetLeafSequence(db, ['a', 'k']));
assert.strictEqual('a', await s.first());
assert.strictEqual('k', await s.last());
@@ -232,8 +240,7 @@ suite('SetLeaf', () => {
});
test('forEach', async () => {
const ds = new Database(makeTestingBatchStore());
const m = new Set(newSetLeafSequence(ds, ['a', 'b']));
const m = new Set(newSetLeafSequence(db, ['a', 'b']));
const values = [];
await m.forEach((k) => { values.push(k); });
@@ -241,10 +248,8 @@ suite('SetLeaf', () => {
});
test('iterator', async () => {
const ds = new Database(makeTestingBatchStore());
const test = async items => {
const m = new Set(newSetLeafSequence(ds, items));
const m = new Set(newSetLeafSequence(db, items));
assert.deepEqual(items, await flatten(m.iterator()));
assert.deepEqual(items, await flattenParallel(m.iterator(), items.length));
};
@@ -255,8 +260,7 @@ suite('SetLeaf', () => {
});
test('LONG: iteratorAt', async () => {
const ds = new Database(makeTestingBatchStore());
const build = items => new Set(newSetLeafSequence(ds, items));
const build = items => new Set(newSetLeafSequence(db, items));
assert.deepEqual([], await flatten(build([]).iteratorAt('a')));
@@ -272,11 +276,10 @@ suite('SetLeaf', () => {
});
test('chunks', () => {
const ds = new Database(makeTestingBatchStore());
const r1 = ds.writeValue('x');
const r2 = ds.writeValue('a');
const r3 = ds.writeValue('b');
const l = new Set(newSetLeafSequence(ds, ['z', r1, r2, r3]));
const r1 = db.writeValue('x');
const r2 = db.writeValue('a');
const r3 = db.writeValue('b');
const l = new Set(newSetLeafSequence(db, ['z', r1, r2, r3]));
assert.strictEqual(3, l.chunks.length);
assert.isTrue(equals(r1, l.chunks[0]));
assert.isTrue(equals(r2, l.chunks[1]));
@@ -285,6 +288,14 @@ suite('SetLeaf', () => {
});
suite('CompoundSet', () => {
let db;
setup(() => {
db = new Database(makeTestingBatchStore());
});
teardown((): Promise<void> => db.close());
function build(vwr: ValueReadWriter, values: Array<string>): Set {
assert.isTrue(values.length > 1 && Math.log2(values.length) % 1 === 0);
@@ -312,15 +323,13 @@ suite('CompoundSet', () => {
}
test('isEmpty/size', () => {
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
assert.isFalse(c.isEmpty());
assert.strictEqual(8, c.size);
});
test('first/last/has', async () => {
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
assert.strictEqual('a', await c.first());
assert.strictEqual('n', await c.last());
assert.isTrue(await c.has('a'));
@@ -340,25 +349,22 @@ suite('CompoundSet', () => {
});
test('forEach', async () => {
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const values = [];
await c.forEach((k) => { values.push(k); });
assert.deepEqual(['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n'], values);
});
test('iterator', async () => {
const ds = new Database(makeTestingBatchStore());
const values = ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n'];
const c = build(ds, values);
const c = build(db, values);
assert.deepEqual(values, await flatten(c.iterator()));
assert.deepEqual(values, await flattenParallel(c.iterator(), values.length));
});
test('LONG: iteratorAt', async () => {
const ds = new Database(makeTestingBatchStore());
const values = ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n'];
const c = build(ds, values);
const c = build(db, values);
const offsets = {
_: 0, a: 0,
b: 1,
@@ -378,9 +384,8 @@ suite('CompoundSet', () => {
});
test('iterator return', async () => {
const ds = new Database(makeTestingBatchStore());
const values = ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n'];
const c = build(ds, values);
const c = build(db, values);
const iter = c.iterator();
const values2 = [];
for (let res = await iter.next(); !res.done; res = await iter.next()) {
@@ -393,8 +398,7 @@ suite('CompoundSet', () => {
});
test('iterator return parallel', async () => {
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const iter = c.iterator();
const values = await Promise.all([iter.next(), iter.next(), iter.return(), iter.next()]);
assert.deepEqual(
@@ -403,21 +407,18 @@ suite('CompoundSet', () => {
});
test('chunks', () => {
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
assert.strictEqual(2, c.chunks.length);
});
test('map', async () => {
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const values = await c.map((k) => k + '*');
assert.deepEqual(['a*', 'b*', 'e*', 'f*', 'h*', 'i*', 'm*', 'n*'], values);
});
test('map async', async () => {
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const values = await c.map((k) => Promise.resolve(k + '*'));
assert.deepEqual(['a*', 'b*', 'e*', 'f*', 'h*', 'i*', 'm*', 'n*'], values);
});
@@ -434,9 +435,7 @@ suite('CompoundSet', () => {
}
test('advanceTo', async () => {
const ds = new Database(makeTestingBatchStore());
const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']);
invariant(c.sequence instanceof OrderedSequence);
let cursor = await c.sequence.newCursorAt(null);
@@ -476,12 +475,10 @@ suite('CompoundSet', () => {
});
async function testIntersect(expect: Array<string>, seqs: Array<Array<string>>) {
const ds = new Database(makeTestingBatchStore());
const first = build(ds, seqs[0]);
const first = build(db, seqs[0]);
const sets:Array<Set> = [];
for (let i = 1; i < seqs.length; i++) {
sets.push(build(ds, seqs[i]));
sets.push(build(db, seqs[i]));
}
const result = await first.intersect(...sets);
@@ -505,10 +502,8 @@ suite('CompoundSet', () => {
});
test('iterator at 0', async () => {
const ds = new Database(makeTestingBatchStore());
const test = async (expected, items) => {
const set = new Set(newSetLeafSequence(ds, items));
const set = new Set(newSetLeafSequence(db, items));
const iter = set.iteratorAt(0);
assert.deepEqual(expected, await flatten(iter));
};
@@ -526,9 +521,8 @@ suite('CompoundSet', () => {
});
test('LONG: canned set diff', async () => {
const ds = new Database(makeTestingBatchStore());
const s1 = await newSet(
firstNNumbers(testSetSize)).then(s => ds.readValue(ds.writeValue(s).targetRef));
firstNNumbers(testSetSize)).then(s => db.readValue(db.writeValue(s).targetRef));
{
// Insert/remove at start.
@@ -578,13 +572,14 @@ suite('CompoundSet', () => {
}
const ms = new CountingMemoryStore();
const ds = new Database(new BatchStore(3, new BatchStoreAdaptorDelegate(ms)));
[s1, s2] = await Promise.all([s1, s2].map(s => ds.readValue(ds.writeValue(s).targetRef)));
const db = new Database(new BatchStore(3, new BatchStoreAdaptorDelegate(ms)));
[s1, s2] = await Promise.all([s1, s2].map(s => db.readValue(db.writeValue(s).targetRef)));
assert.deepEqual([[], []], await s1.diff(s1));
assert.deepEqual([[], []], await s2.diff(s2));
assert.deepEqual([removed, added], await s1.diff(s2));
assert.deepEqual([added, removed], await s2.diff(s1));
await db.close();
}
function testSmallRandomDiff(inS1: number, inS2: number): Promise<void> {
@@ -617,8 +612,7 @@ suite('CompoundSet', () => {
test('LONG: random set diff 0.1/0.9', () => testRandomDiff(randomSetSize, 0.1, 0.9));
test('chunks', () => {
const ds = new Database(makeTestingBatchStore());
const s = build(ds, ['a', 'b', 'c', 'd']);
const s = build(db, ['a', 'b', 'c', 'd']);
const chunks = s.chunks;
const sequence = s.sequence;
assert.equal(2, chunks.length);
+13 -7
View File
@@ -11,7 +11,7 @@ import {assert} from 'chai';
import {suite, test} from 'mocha';
suite('Specs', () => {
test('DatabaseSpec', () => {
test('DatabaseSpec', async () => {
const notAllowed = ['mem:', 'mem:stuff', 'http:', 'https:', 'random:', 'random:random'];
notAllowed.forEach(s => assert.isNull(DatabaseSpec.parse(s)));
@@ -19,16 +19,20 @@ suite('Specs', () => {
invariant(spec);
assert.equal(spec.scheme, 'mem');
assert.equal(spec.path, '');
assert.instanceOf(spec.store(), Database);
assert.instanceOf(spec.store()._vs._bs, BatchStoreAdaptor);
let store = spec.store();
assert.instanceOf(store, Database);
assert.instanceOf(store._vs._bs, BatchStoreAdaptor);
await store.close();
spec = DatabaseSpec.parse('http://foo');
invariant(spec);
assert.isNotNull(spec);
assert.equal(spec.scheme, 'http');
assert.equal(spec.path, '//foo');
assert.instanceOf(spec.store(), Database);
assert.instanceOf(spec.store()._vs._bs, HttpBatchStore);
store = spec.store();
assert.instanceOf(store, Database);
assert.instanceOf(store._vs._bs, HttpBatchStore);
await store.close();
spec = DatabaseSpec.parse('https://foo');
invariant(spec);
@@ -37,7 +41,7 @@ suite('Specs', () => {
assert.equal(spec.path, '//foo');
});
test('DataSetSpec', () => {
test('DataSetSpec', async () => {
const invalid = ['mem', 'mem:', 'http', 'http:', 'http://foo', 'monkey', 'monkey:balls'];
invalid.forEach(s => assert.isNull(DatasetSpec.parse(s)));
@@ -49,6 +53,7 @@ suite('Specs', () => {
let ds = spec.set();
assert.instanceOf(ds, Dataset);
assert.instanceOf(ds.store._vs._bs, BatchStoreAdaptor);
await ds.store.close();
spec = DatasetSpec.parse('http://localhost:8000/foo:ds');
invariant(spec);
@@ -58,9 +63,10 @@ suite('Specs', () => {
ds = spec.set();
assert.instanceOf(ds, Dataset);
assert.instanceOf(ds.store._vs._bs, HttpBatchStore);
await ds.store.close();
});
test('RefSpec', () => {
test('RefSpec', async () => {
const testRef = new Ref('sha1-0000000000000000000000000000000000000000');
const invalid = [
'mem', 'mem:', 'http', 'http:', 'http://foo', 'monkey', 'monkey:balls',
+4 -1
View File
@@ -92,6 +92,8 @@ export class DatasetSpec {
// Returns the value at the HEAD of this dataset, if any, or null otherwise.
value(): Promise<any> {
// Hm. Calling set() creates a Database that we then toss into the ether, which means we can't
// call close() on it. Ideally, we'd fix that.
return this.set().head()
.then(commit => commit && commit.value);
}
@@ -135,7 +137,8 @@ export class RefSpec {
// Returns the value for the spec'd reference, if any, or null otherwise.
value(): Promise<any> {
return this.store.store().readValue(this.ref);
const store = this.store.store();
return store.readValue(this.ref).then(v => store.close().then(() => v));
}
}
+3 -2
View File
@@ -34,13 +34,14 @@ suite('Struct', () => {
});
test('chunks', () => {
const ds = new Database(makeTestingBatchStore());
const db = new Database(makeTestingBatchStore());
const b = true;
const r = ds.writeValue(b);
const r = db.writeValue(b);
const s1 = newStruct('S1', {r: r});
assert.strictEqual(1, s1.chunks.length);
assert.isTrue(equals(r, s1.chunks[0]));
return db.close();
});
test('new', () => {
+1
View File
@@ -60,6 +60,7 @@ export async function testRoundTripAndValidate<T: valueOrPrimitive>(v: T,
assert.strictEqual(v2, v);
}
await validateFn(v2);
await ds2.close();
}
export function chunkDiffCount(v1: valueOrPrimitive, v2: valueOrPrimitive): number {
+8 -7
View File
@@ -19,7 +19,7 @@ import {equals} from './compare.js';
suite('Type', () => {
test('types', async () => {
const ds = new Database(makeTestingBatchStore());
const db = new Database(makeTestingBatchStore());
const mapType = makeMapType(stringType, numberType);
const setType = makeSetType(stringType);
@@ -28,13 +28,14 @@ suite('Type', () => {
'Field2': boolType,
});
const mapRef = ds.writeValue(mapType).targetRef;
const setRef = ds.writeValue(setType).targetRef;
const mahRef = ds.writeValue(mahType).targetRef;
const mapRef = db.writeValue(mapType).targetRef;
const setRef = db.writeValue(setType).targetRef;
const mahRef = db.writeValue(mahType).targetRef;
assert.isTrue(equals(mapType, await ds.readValue(mapRef)));
assert.isTrue(equals(setType, await ds.readValue(setRef)));
assert.isTrue(equals(mahType, await ds.readValue(mahRef)));
assert.isTrue(equals(mapType, await db.readValue(mapRef)));
assert.isTrue(equals(setType, await db.readValue(setRef)));
assert.isTrue(equals(mahType, await db.readValue(mahRef)));
await db.close();
});
test('type Type', () => {
+7
View File
@@ -30,6 +30,7 @@ suite('ValueStore', () => {
ms.put(c);
const v2 = await vs.readValue(c.ref);
assert.equal('abc', v2);
await vs.close();
});
test('writeValue primitives', async () => {
@@ -45,6 +46,7 @@ suite('ValueStore', () => {
assert.equal(false, v2);
const v3 = await vs.readValue(r3);
assert.equal(2, v3);
await vs.close();
});
test('writeValue rejects invalid', async () => {
@@ -62,6 +64,7 @@ suite('ValueStore', () => {
ex = e;
}
assert.instanceOf(ex, Error);
await vs.close();
});
test('write coalescing', async () => {
@@ -72,6 +75,7 @@ suite('ValueStore', () => {
(bs: any).schedulePut = () => { assert.fail('unreachable'); };
const r2 = vs.writeValue('hello').targetRef;
assert.isTrue(r1.equals(r2));
await vs.close();
});
test('read caching', async () => {
@@ -84,6 +88,7 @@ suite('ValueStore', () => {
(bs: any).get = () => { throw new Error(); };
const v2 = await vs.readValue(r1);
assert.equal(v1, v2);
await vs.close();
});
test('caching eviction', async () => {
@@ -108,6 +113,7 @@ suite('ValueStore', () => {
ex = e;
}
assert.instanceOf(ex, Error);
await vs.close();
});
test('hints on cache', async () => {
@@ -119,5 +125,6 @@ suite('ValueStore', () => {
const v = await vs.readValue(r.targetRef);
assert.isTrue(equals(l, v));
await vs.close();
});
});
+2 -2
View File
@@ -90,8 +90,8 @@ export default class ValueStore {
return this._bs.flush();
}
close() {
this._bs.close();
close(): Promise<void> {
return this._bs.close();
}
}
+7 -2
View File
@@ -16,13 +16,18 @@ import {newMap} from './map.js';
import {newSet} from './set.js';
import walk from './walk.js';
import {suite, test} from 'mocha';
import {suite, suiteSetup, suiteTeardown, test} from 'mocha';
import {assert} from 'chai';
import type {valueOrPrimitive} from './value.js';
suite('walk', () => {
const ds = new Database(new BatchStoreAdaptor(new MemoryStore()));
let ds;
suiteSetup(() => {
ds = new Database(new BatchStoreAdaptor(new MemoryStore()));
});
suiteTeardown((): Promise<void> => ds.close());
test('primitives', async () => {
await Promise.all([true, false, 42, 88.8, 'hello!', ''].map(async v => {
+1
View File
@@ -29,6 +29,7 @@ suite('cross platform test', () => {
assert.strictEqual(v2, t._value, t._description);
assert.strictEqual(t._value, v2, t._description);
assert.strictEqual(t._expectedRef, r.targetRef.toString(), t._description);
return db.close();
}
async function testTypes(testValues: Array<TestValue>): Promise<void> {