@rimbu/stream
Version:
Efficient structure representing a sequence of elements, with powerful operations for TypeScript
572 lines • 18.2 kB
JavaScript
var _TransformerFastIterator_done, _TransformerFastIterator_currentValues;
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
import { Token } from '@rimbu/base';
import { CollectFun, OptLazy, TraverseState } from '@rimbu/common';
import {} from '@rimbu/stream';
import {} from '@rimbu/stream';
import { fromStreamSource, } from '@rimbu/stream/custom';
export const fixedDoneIteratorResult = Object.freeze({
done: true,
value: undefined,
});
export const emptyFastIterator = Object.freeze({
fastNext(otherwise) {
return OptLazy(otherwise);
},
next() {
return fixedDoneIteratorResult;
},
});
export function isFastIterator(iterator) {
return `fastNext` in iterator;
}
/**
* A base class for `FastIterator` instances, that takes implements the default `next`
* function based on the abstract `fastNext` function.
*/
export class FastIteratorBase {
next() {
const done = Symbol('Done');
const value = this.fastNext(done);
if (done === value)
return fixedDoneIteratorResult;
return { value, done: false };
}
}
export class ReducerFastIterator extends FastIteratorBase {
constructor(sourceIterator, reducerInstance) {
super();
this.sourceIterator = sourceIterator;
this.reducerInstance = reducerInstance;
}
fastNext(otherwise) {
if (this.reducerInstance.halted) {
return OptLazy(otherwise);
}
const done = Symbol('done');
const nextInput = this.sourceIterator.fastNext(done);
if (done === nextInput) {
this.reducerInstance.halt();
return OptLazy(otherwise);
}
this.reducerInstance.next(nextInput);
return this.reducerInstance.getOutput();
}
}
export class TransformerFastIterator extends FastIteratorBase {
constructor(sourceIterator, transformerInstance) {
super();
this.sourceIterator = sourceIterator;
this.transformerInstance = transformerInstance;
_TransformerFastIterator_done.set(this, false);
_TransformerFastIterator_currentValues.set(this, void 0);
}
fastNext(otherwise) {
if (__classPrivateFieldGet(this, _TransformerFastIterator_done, "f")) {
return OptLazy(otherwise);
}
const done = Symbol('done');
let nextValue;
while (undefined === __classPrivateFieldGet(this, _TransformerFastIterator_currentValues, "f") ||
done === (nextValue = __classPrivateFieldGet(this, _TransformerFastIterator_currentValues, "f").fastNext(done))) {
if (this.transformerInstance.halted) {
__classPrivateFieldSet(this, _TransformerFastIterator_done, true, "f");
return OptLazy(otherwise);
}
const nextSource = this.sourceIterator.fastNext(done);
if (done === nextSource) {
if (this.transformerInstance.halted) {
__classPrivateFieldSet(this, _TransformerFastIterator_done, true, "f");
return OptLazy(otherwise);
}
__classPrivateFieldSet(this, _TransformerFastIterator_done, true, "f");
this.transformerInstance.halt();
}
else {
this.transformerInstance.next(nextSource);
}
const nextValuesSource = this.transformerInstance.getOutput();
__classPrivateFieldSet(this, _TransformerFastIterator_currentValues, fromStreamSource(nextValuesSource)[Symbol.iterator](), "f");
}
return nextValue;
}
}
_TransformerFastIterator_done = new WeakMap(), _TransformerFastIterator_currentValues = new WeakMap();
export class ConcatIterator extends FastIteratorBase {
constructor(source, otherSources, streamSourceHelpers) {
super();
this.source = source;
this.otherSources = otherSources;
this.streamSourceHelpers = streamSourceHelpers;
this.sourceIndex = 0;
this.iterator = source[Symbol.iterator]();
}
fastNext(otherwise) {
const done = Symbol('Done');
let value;
const length = this.otherSources.length;
const { streamSourceHelpers } = this;
while (done === (value = this.iterator.fastNext(done))) {
if (this.sourceIndex >= length)
return OptLazy(otherwise);
let nextSource = this.otherSources[this.sourceIndex++];
while (streamSourceHelpers.isEmptyStreamSourceInstance(nextSource)) {
if (this.sourceIndex >= length) {
return OptLazy(otherwise);
}
nextSource = this.otherSources[this.sourceIndex++];
}
this.iterator = streamSourceHelpers
.fromStreamSource(nextSource)[Symbol.iterator]();
}
return value;
}
}
export class IndexedIterator extends FastIteratorBase {
constructor(source, startIndex) {
super();
this.source = source;
this.startIndex = startIndex;
this.index = this.startIndex;
}
fastNext(otherwise) {
const done = Symbol('Done');
const value = this.source.fastNext(done);
if (done === value) {
return OptLazy(otherwise);
}
return [this.index++, value];
}
}
export class FilterIterator extends FastIteratorBase {
constructor(source, pred, negate) {
super();
this.source = source;
this.pred = pred;
this.negate = negate;
this.state = TraverseState();
}
fastNext(otherwise) {
const state = this.state;
if (state.halted)
return OptLazy(otherwise);
const done = Symbol('Done');
let value;
const source = this.source;
const pred = this.pred;
const halt = state.halt;
const negate = this.negate;
while (!state.halted && done !== (value = source.fastNext(done))) {
if (pred(value, state.nextIndex(), halt) !== negate)
return value;
}
return OptLazy(otherwise);
}
}
export class FilterPureIterator extends FastIteratorBase {
constructor(source, pred, args, negate) {
super();
this.source = source;
this.pred = pred;
this.args = args;
this.negate = negate;
}
fastNext(otherwise) {
const done = Symbol('Done');
let value;
const source = this.source;
const pred = this.pred;
const args = this.args;
const negate = this.negate;
while (done !== (value = source.fastNext(done))) {
if (pred(value, ...args) !== negate)
return value;
}
return OptLazy(otherwise);
}
}
export class CollectIterator extends FastIteratorBase {
constructor(source, collectFun) {
super();
this.source = source;
this.collectFun = collectFun;
this.state = TraverseState();
}
fastNext(otherwise) {
const state = this.state;
if (state.halted)
return OptLazy(otherwise);
const { halt } = state;
const done = Symbol('Done');
let value;
const source = this.source;
const collectFun = this.collectFun;
while (!state.halted && done !== (value = source.fastNext(done))) {
const result = collectFun(value, state.nextIndex(), CollectFun.Skip, halt);
if (CollectFun.Skip === result)
continue;
return result;
}
return OptLazy(otherwise);
}
}
export class DropWhileIterator extends FastIteratorBase {
constructor(source, pred, negate) {
super();
this.source = source;
this.pred = pred;
this.negate = negate;
this.pass = false;
this.index = 0;
}
fastNext(otherwise) {
const source = this.source;
if (this.pass)
return source.fastNext(otherwise);
const done = Symbol('Done');
let value;
const negate = this.negate;
while (done !== (value = source.fastNext(done))) {
this.pass = this.pred(value, this.index++) === negate;
if (this.pass)
return value;
}
return OptLazy(otherwise);
}
}
export class TakeIterator extends FastIteratorBase {
constructor(source, amount) {
super();
this.source = source;
this.amount = amount;
this.i = 0;
}
fastNext(otherwise) {
if (this.i++ >= this.amount)
return OptLazy(otherwise);
return this.source.fastNext(otherwise);
}
}
export class DropIterator extends FastIteratorBase {
constructor(source, amount) {
super();
this.source = source;
this.amount = amount;
this.remain = amount;
}
fastNext(otherwise) {
const source = this.source;
if (this.remain <= 0)
return source.fastNext(otherwise);
const done = Symbol('Done');
let value;
while (done !== (value = source.fastNext(done))) {
if (this.remain-- <= 0)
return value;
}
return OptLazy(otherwise);
}
}
export class RepeatIterator extends FastIteratorBase {
constructor(source, amount) {
super();
this.source = source;
this.amount = amount;
this.isEmpty = true;
this.iterator = source[Symbol.iterator]();
this.remain = amount;
}
fastNext(otherwise) {
const done = Symbol('Done');
let value = this.iterator.fastNext(done);
if (done !== value) {
this.isEmpty = false;
return value;
}
if (this.isEmpty)
return OptLazy(otherwise);
if (undefined !== this.remain) {
this.remain--;
if (this.remain <= 0)
return OptLazy(otherwise);
}
this.iterator = this.source[Symbol.iterator]();
value = this.iterator.fastNext(done);
if (done === value)
return OptLazy(otherwise);
return value;
}
}
export class ArrayIterator extends FastIteratorBase {
constructor(array, startIndex, endIndex) {
super();
this.array = array;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.i = startIndex;
}
fastNext(otherwise) {
if (this.i > this.endIndex)
return OptLazy(otherwise);
return this.array[this.i++];
}
}
export class ArrayReverseIterator extends FastIteratorBase {
constructor(array, startIndex, endIndex) {
super();
this.array = array;
this.startIndex = startIndex;
this.i = endIndex;
}
fastNext(otherwise) {
if (this.i < this.startIndex)
return OptLazy(otherwise);
return this.array[this.i--];
}
}
export class AlwaysIterator extends FastIteratorBase {
constructor(value) {
super();
this.value = value;
}
fastNext() {
return this.value;
}
}
export class MapApplyIterator extends FastIteratorBase {
constructor(source, f, args, streamSourceHelpers) {
super();
this.f = f;
this.args = args;
this.iter = streamSourceHelpers.fromStreamSource(source)[Symbol.iterator]();
}
fastNext(otherwise) {
const done = Symbol();
const next = this.iter.fastNext(done);
const args = this.args;
if (done === next)
return OptLazy(otherwise);
return this.f(...next, ...args);
}
}
export class FilterApplyIterator extends FastIteratorBase {
constructor(source, pred, args, negate, streamSourceHelpers) {
super();
this.pred = pred;
this.args = args;
this.negate = negate;
this.iter = streamSourceHelpers.fromStreamSource(source)[Symbol.iterator]();
}
fastNext(otherwise) {
const done = Symbol();
let next;
const pred = this.pred;
const iter = this.iter;
const args = this.args;
const negate = this.negate;
while (done !== (next = iter.fastNext(done))) {
if (pred(...next, ...args) !== negate)
return next;
}
return OptLazy(otherwise);
}
}
export class RangeUpIterator extends FastIteratorBase {
constructor(start = 0, end, delta) {
super();
this.start = start;
this.end = end;
this.delta = delta;
this.state = start;
}
fastNext(otherwise) {
if (undefined !== this.end) {
if (this.state > this.end) {
return OptLazy(otherwise);
}
}
const currentState = this.state;
this.state += this.delta;
return currentState;
}
}
export class RangeDownIterator extends FastIteratorBase {
constructor(start = 0, end, delta) {
super();
this.start = start;
this.end = end;
this.delta = delta;
this.state = start;
}
fastNext(otherwise) {
if (undefined !== this.end) {
if (this.state < this.end) {
return OptLazy(otherwise);
}
}
const currentState = this.state;
this.state += this.delta;
return currentState;
}
}
export class RandomIterator extends FastIteratorBase {
fastNext() {
return Math.random();
}
}
export class RandomIntIterator extends FastIteratorBase {
constructor(min, max) {
super();
this.min = min;
this.max = max;
this.width = max - min;
}
fastNext() {
return this.min + Math.round(Math.random() * this.width);
}
}
export class UnfoldIterator extends FastIteratorBase {
constructor(init, getNext) {
super();
this.getNext = getNext;
this.index = 0;
this.current = init;
}
fastNext(otherwise) {
const current = this.current;
if (Token === current)
return OptLazy(otherwise);
if (this.index === 0) {
this.index++;
return current;
}
const next = this.getNext(current, this.index++, Token);
this.current = next;
if (Token === next)
return OptLazy(otherwise);
return next;
}
}
export class ZipWithIterator extends FastIteratorBase {
constructor(iterables, zipFun, streamSourceHelpers) {
super();
this.iterables = iterables;
this.zipFun = zipFun;
this.sources = iterables.map((source) => streamSourceHelpers.fromStreamSource(source)[Symbol.iterator]());
}
fastNext(otherwise) {
const result = [];
let sourceIndex = -1;
const sources = this.sources;
const done = Symbol('Done');
while (++sourceIndex < sources.length) {
const value = sources[sourceIndex].fastNext(done);
if (done === value)
return OptLazy(otherwise);
result.push(value);
}
return this.zipFun(...result);
}
}
export class ZipAllWithItererator extends FastIteratorBase {
constructor(fillValue, iters, zipFun, streamSourceHelpers) {
super();
this.fillValue = fillValue;
this.iters = iters;
this.zipFun = zipFun;
this.allDone = false;
this.sources = iters.map((o) => streamSourceHelpers.fromStreamSource(o)[Symbol.iterator]());
}
fastNext(otherwise) {
if (this.allDone)
return OptLazy(otherwise);
const result = [];
let sourceIndex = -1;
const sources = this.sources;
const done = Symbol('Done');
let anyNotDone = false;
const fillValue = this.fillValue;
while (++sourceIndex < sources.length) {
const value = sources[sourceIndex].fastNext(done);
if (done === value) {
result.push(OptLazy(fillValue));
}
else {
anyNotDone = true;
result.push(value);
}
}
if (!anyNotDone) {
this.allDone = true;
return OptLazy(otherwise);
}
return this.zipFun(...result);
}
}
export class PrependIterator extends FastIteratorBase {
constructor(source, item) {
super();
this.source = source;
this.item = item;
this.prependDone = false;
}
fastNext(otherwise) {
if (this.prependDone) {
return this.source.fastNext(otherwise);
}
this.prependDone = true;
return OptLazy(this.item);
}
}
export class AppendIterator extends FastIteratorBase {
constructor(source, item) {
super();
this.source = source;
this.item = item;
this.appendDone = false;
}
fastNext(otherwise) {
if (this.appendDone)
return OptLazy(otherwise);
const done = Symbol('Done');
const value = this.source.fastNext(done);
if (done !== value)
return value;
this.appendDone = true;
return OptLazy(this.item);
}
}
export class MapIterator extends FastIteratorBase {
constructor(source, mapFun) {
super();
this.source = source;
this.mapFun = mapFun;
this.state = TraverseState();
}
fastNext(otherwise) {
const state = this.state;
if (state.halted)
return OptLazy(otherwise);
const done = Symbol('Done');
const next = this.source.fastNext(done);
if (done === next)
return OptLazy(otherwise);
return this.mapFun(next, state.nextIndex());
}
}
export class MapPureIterator extends FastIteratorBase {
constructor(source, mapFun, args) {
super();
this.source = source;
this.mapFun = mapFun;
this.args = args;
}
fastNext(otherwise) {
const done = Symbol('Done');
const next = this.source.fastNext(done);
if (done === next)
return OptLazy(otherwise);
return this.mapFun(next, ...this.args);
}
}
//# sourceMappingURL=fast-iterator-custom.mjs.map