mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-12 02:58:53 -06:00
Make sequence chunker function return (meta tuple, collection) pair (#1540)
Both Go and JS. Currently they return (any, value), but it's useful to have the more specific return type.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
[ignore]
|
||||
.*/dist
|
||||
.*/node_modules/babel.*
|
||||
.*/node_modules/babylon/.*
|
||||
.*/node_modules/d3/.*
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
// @flow
|
||||
|
||||
import {suite, test} from 'mocha';
|
||||
import {assert} from 'chai';
|
||||
import {SequenceChunker} from './sequence-chunker.js';
|
||||
|
||||
class ModBoundaryChecker {
|
||||
mod: number;
|
||||
|
||||
constructor(mod: number) {
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
get windowSize(): number {
|
||||
return 1;
|
||||
}
|
||||
|
||||
write(item: number): boolean {
|
||||
return item % this.mod === 0;
|
||||
}
|
||||
}
|
||||
|
||||
function sumChunker(items: Array<number>): [number, any] {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
sum += items[i];
|
||||
}
|
||||
|
||||
return [sum, items];
|
||||
}
|
||||
|
||||
suite('SequenceChunker', () => {
|
||||
|
||||
async function testChunking(expect: Array<number>, from: number, to: number) {
|
||||
const seq = new SequenceChunker(null, sumChunker, sumChunker,
|
||||
new ModBoundaryChecker(3), () => new ModBoundaryChecker(5));
|
||||
|
||||
for (let i = from; i <= to; i++) {
|
||||
seq.append(i);
|
||||
}
|
||||
|
||||
assert.deepEqual(expect, await seq.done());
|
||||
}
|
||||
|
||||
test('mod', async () => {
|
||||
await testChunking([1], 1, 1);
|
||||
await testChunking([3], 3, 3);
|
||||
await testChunking([1, 2], 1, 2);
|
||||
await testChunking([3, 4], 3, 4); // XX
|
||||
await testChunking([1, 2, 3], 1, 3);
|
||||
await testChunking([6, 4], 1, 4);
|
||||
await testChunking([6, 15], 1, 6);
|
||||
await testChunking([21, 7], 1, 7);
|
||||
});
|
||||
});
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
import type {Sequence} from './sequence.js'; // eslint-disable-line no-unused-vars
|
||||
import {invariant, notNull} from './assert.js';
|
||||
import type {Collection} from './collection.js';
|
||||
import type {MetaSequence, MetaTuple} from './meta-sequence.js';
|
||||
import type {SequenceCursor} from './sequence.js';
|
||||
|
||||
export type BoundaryChecker<T> = {
|
||||
@@ -9,18 +11,18 @@ export type BoundaryChecker<T> = {
|
||||
windowSize: number;
|
||||
}
|
||||
|
||||
export type NewBoundaryCheckerFn<T> = () => BoundaryChecker<T>;
|
||||
export type NewBoundaryCheckerFn = () => BoundaryChecker<MetaTuple>;
|
||||
|
||||
export type makeChunkFn = (items: Array<any>) => [any, any];
|
||||
export type makeChunkFn<T: Collection> = (items: Array<any>) => [MetaTuple, T];
|
||||
|
||||
export async function chunkSequence<S, T>(
|
||||
export async function chunkSequence<C: Collection, S>(
|
||||
cursor: ?SequenceCursor,
|
||||
insert: Array<S>,
|
||||
remove: number,
|
||||
makeChunk: makeChunkFn,
|
||||
parentMakeChunk: makeChunkFn,
|
||||
makeChunk: makeChunkFn<C>,
|
||||
parentMakeChunk: makeChunkFn<C>,
|
||||
boundaryChecker: BoundaryChecker<S>,
|
||||
newBoundaryChecker: NewBoundaryCheckerFn<T>): Promise<any> {
|
||||
newBoundaryChecker: NewBoundaryCheckerFn): Promise<C> {
|
||||
|
||||
const chunker = new SequenceChunker(cursor, makeChunk, parentMakeChunk, boundaryChecker,
|
||||
newBoundaryChecker);
|
||||
@@ -42,21 +44,21 @@ export async function chunkSequence<S, T>(
|
||||
return await chunker.done();
|
||||
}
|
||||
|
||||
export class SequenceChunker<S, T, U:Sequence, V:Sequence> {
|
||||
export class SequenceChunker<C: Collection, S, U:Sequence> {
|
||||
_cursor: ?SequenceCursor<S, U>;
|
||||
_isOnChunkBoundary: boolean;
|
||||
_parent: ?SequenceChunker<T, T, V, V>;
|
||||
_parent: ?SequenceChunker<C, MetaTuple, MetaSequence>;
|
||||
_current: Array<S>;
|
||||
_makeChunk: makeChunkFn;
|
||||
_parentMakeChunk: makeChunkFn;
|
||||
_makeChunk: makeChunkFn<C>;
|
||||
_parentMakeChunk: makeChunkFn<C>;
|
||||
_boundaryChecker: BoundaryChecker<S>;
|
||||
_newBoundaryChecker: NewBoundaryCheckerFn<T>;
|
||||
_newBoundaryChecker: NewBoundaryCheckerFn;
|
||||
_used: boolean;
|
||||
|
||||
constructor(cursor: ?SequenceCursor, makeChunk: makeChunkFn,
|
||||
parentMakeChunk: makeChunkFn,
|
||||
boundaryChecker: BoundaryChecker<S>,
|
||||
newBoundaryChecker: NewBoundaryCheckerFn<T>) {
|
||||
newBoundaryChecker: NewBoundaryCheckerFn) {
|
||||
this._cursor = cursor;
|
||||
this._isOnChunkBoundary = false;
|
||||
this._parent = null;
|
||||
@@ -125,18 +127,19 @@ export class SequenceChunker<S, T, U:Sequence, V:Sequence> {
|
||||
|
||||
handleChunkBoundary() {
|
||||
invariant(this._current.length > 0);
|
||||
if (!this._parent) {
|
||||
const parent = this._parent;
|
||||
if (!parent) {
|
||||
invariant(!this._isOnChunkBoundary);
|
||||
this._isOnChunkBoundary = true;
|
||||
} else {
|
||||
invariant(this._current.length > 0);
|
||||
const chunk = this._makeChunk(this._current)[0];
|
||||
notNull(this._parent).append(chunk);
|
||||
parent.append(chunk);
|
||||
this._current = [];
|
||||
}
|
||||
}
|
||||
|
||||
async done(): Promise<any> {
|
||||
async done(): Promise<C> {
|
||||
if (this._cursor) {
|
||||
await this.finalizeCursor();
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ func newBlobLeafBoundaryChecker() boundaryChecker {
|
||||
}
|
||||
|
||||
func newBlobLeafChunkFn(vr ValueReader) makeChunkFn {
|
||||
return func(items []sequenceItem) (sequenceItem, Value) {
|
||||
return func(items []sequenceItem) (metaTuple, Collection) {
|
||||
buff := make([]byte, len(items))
|
||||
|
||||
for i, v := range items {
|
||||
|
||||
@@ -102,7 +102,7 @@ func newIndexedMetaSequenceBoundaryChecker() boundaryChecker {
|
||||
// If |sink| is not nil, chunks will be eagerly written as they're created. Otherwise they are
|
||||
// written when the root is written.
|
||||
func newIndexedMetaSequenceChunkFn(kind NomsKind, source ValueReader, sink ValueWriter) makeChunkFn {
|
||||
return func(items []sequenceItem) (sequenceItem, Value) {
|
||||
return func(items []sequenceItem) (metaTuple, Collection) {
|
||||
tuples := make(metaSequenceData, len(items))
|
||||
numLeaves := uint64(0)
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ func newListLeafBoundaryChecker() boundaryChecker {
|
||||
// If |sink| is not nil, chunks will be eagerly written as they're created. Otherwise they are
|
||||
// written when the root is written.
|
||||
func makeListLeafChunkFn(vr ValueReader, sink ValueWriter) makeChunkFn {
|
||||
return func(items []sequenceItem) (sequenceItem, Value) {
|
||||
return func(items []sequenceItem) (metaTuple, Collection) {
|
||||
values := make([]Value, len(items))
|
||||
|
||||
for i, v := range items {
|
||||
|
||||
@@ -218,7 +218,7 @@ func newMapLeafBoundaryChecker() boundaryChecker {
|
||||
}
|
||||
|
||||
func makeMapLeafChunkFn(vr ValueReader) makeChunkFn {
|
||||
return func(items []sequenceItem) (sequenceItem, Value) {
|
||||
return func(items []sequenceItem) (metaTuple, Collection) {
|
||||
mapData := make([]mapEntry, len(items), len(items))
|
||||
|
||||
for i, v := range items {
|
||||
|
||||
@@ -134,7 +134,7 @@ func newOrderedMetaSequenceBoundaryChecker() boundaryChecker {
|
||||
}
|
||||
|
||||
func newOrderedMetaSequenceChunkFn(kind NomsKind, vr ValueReader) makeChunkFn {
|
||||
return func(items []sequenceItem) (sequenceItem, Value) {
|
||||
return func(items []sequenceItem) (metaTuple, Collection) {
|
||||
tuples := make(metaSequenceData, len(items))
|
||||
numLeaves := uint64(0)
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ type sequenceChunker struct {
|
||||
}
|
||||
|
||||
// makeChunkFn takes a sequence of items to chunk, and returns the result of chunking those items, a tuple of a reference to that chunk which can itself be chunked + its underlying value.
|
||||
type makeChunkFn func(values []sequenceItem) (sequenceItem, Value)
|
||||
type makeChunkFn func(values []sequenceItem) (metaTuple, Collection)
|
||||
|
||||
func newEmptySequenceChunker(makeChunk, parentMakeChunk makeChunkFn, boundaryChk boundaryChecker, newBoundaryChecker newBoundaryCheckerFn) *sequenceChunker {
|
||||
return newSequenceChunker(nil, makeChunk, parentMakeChunk, boundaryChk, newBoundaryChecker)
|
||||
|
||||
@@ -192,7 +192,7 @@ func newSetLeafBoundaryChecker() boundaryChecker {
|
||||
}
|
||||
|
||||
func makeSetLeafChunkFn(vr ValueReader) makeChunkFn {
|
||||
return func(items []sequenceItem) (sequenceItem, Value) {
|
||||
return func(items []sequenceItem) (metaTuple, Collection) {
|
||||
setData := make([]Value, len(items), len(items))
|
||||
|
||||
for i, v := range items {
|
||||
|
||||
Reference in New Issue
Block a user