lib-utils-ts
Version:
<img src="https://img.shields.io/npm/v/lib-utils-ts"/> <img src="https://img.shields.io/snyk/vulnerabilities/npm/lib-utils-ts"/> <img src="https://img.shields.io/npm/l/lib-utils-ts"/> <img src="https://img.shields.io/github/languages/top/devGnode/lib-util
164 lines (133 loc) • 5.54 kB
text/typescript
import {Node, PipelineHelper} from "./PipelineHelper";
import {spliterator, supplier} from "../Interface";
import {Spliterator} from "../utils/Spliterator";
import {StreamShape} from "./StreamShape";
import {sink} from "./Sink";
import {terminalOps} from "./TerminalOps";
import {Supplier} from "../utils/Supplier";
import {RuntimeException} from "../Exception";
import assert = require("assert");
// @ts-ignore
export abstract class AbstractPipeline<E_IN,E_OUT,S> extends PipelineHelper<E_OUT>{
private readonly sourceStage:AbstractPipeline<E_IN,E_OUT, S>;
protected previousStage:AbstractPipeline<E_IN, E_OUT, S>;
private nextStage:AbstractPipeline<E_IN, E_OUT, S>;
private sourceSplit:spliterator<any>;
private sourceSupplier: supplier<any>;
private linkedOrConsumed:boolean = false;
protected depth:number = 0;
private combinedFlag:number = 0;
protected constructor(value:Spliterator<any>|Supplier<spliterator<any>>|AbstractPipeline<any,E_IN,any>, opFlags:number) {
super();
if( value instanceof Spliterator ){
this.sourceSplit = value;
this.sourceStage = this;
this.previousStage = this.nextStage = null;
}else if(value instanceof Supplier ){
this.sourceSplit = null;
this.sourceStage = this;
this.sourceSupplier = value;
this.previousStage = this.nextStage = null;
// upstream
}else if(value instanceof AbstractPipeline ){
value.linkedOrConsumed = true;
// @ts-ignore
value.nextStage = this;
// @ts-ignore
this.previousStage = value;
// @ts-ignore
this.sourceStage = value.sourceStage;
this.nextStage = null;
this.depth = value.depth + 1;
this.combinedFlag = opFlags;
}
}
// Parallel ??
public abstract opIsStateful():boolean;
/**
* @opWrapSink: to Implement with :
* + Head => throw
* + StateLessOp
* + StateFulOp
* */
public abstract opWrapSink(flags:number, sink:sink<E_OUT>):sink<E_IN>;
/****
* @evaluate
* @returns {R}
*/
public evaluate<R>(terminalOps: terminalOps<E_OUT, R>):R{
assert.strictEqual( this.getOutputShape().equals(terminalOps.inputShape()), true);
if(this.linkedOrConsumed) throw new RuntimeException("stream has already been operated upon or closed");
this.linkedOrConsumed=true;
return terminalOps.evaluateSequential(this,this.sourceSpliterator(terminalOps.getOpFlag()));
}
/**
* PipelineHelper Handler
* */
public getSourceShape():StreamShape{
return null;
};
/***
* @getOutputShape
* @toImplement
*/
public abstract getOutputShape():StreamShape;
/***
* @getOutputShape
* @toOverride
*/
public getStreamAndOpFlags(): number {return this.combinedFlag;}
public wrapAndCopyInto<P_IN, S extends sink<E_OUT>>(sink: S, spliterator: Spliterator<P_IN> ):S {
this.copyInto(this.wrapSink(sink),spliterator);
return sink;
}
public copyInto<P_IN>(wrappedSink: sink<P_IN>, spliterator: Spliterator<P_IN>):void{
if( this.getStreamAndOpFlags() == 1 ) this.copyIntoWithCancel(wrappedSink,spliterator);
else {
wrappedSink.begin(spliterator.estimateSize());
spliterator.forEachRemaining(wrappedSink);
wrappedSink.end();
}
}
public copyIntoWithCancel<P_IN>(wrappedSink: sink<P_IN>, spliterator: Spliterator<P_IN>) {
let tmp: AbstractPipeline<any, E_OUT, any> = this,
canceled:boolean;
while (tmp.depth > 0) tmp = tmp.previousStage;
wrappedSink.begin(spliterator.estimateSize());
// @ts-ignore
canceled = tmp.forEachWithCancel(wrappedSink,spliterator);
wrappedSink.end();
return canceled;
}
public wrapSink<P_IN>(sk:sink<E_OUT>): sink<P_IN> {
for(let ptr: AbstractPipeline<any, E_OUT, any> = this; ptr.depth > 0; ptr = ptr.previousStage ){
//console.log("======== =====================================")
// console.log(ptr.depth )
// console.log("=======================================================================================================================================")
sk = ptr.opWrapSink(0, sk);
// console.log(sk)
}
// @ts-ignore
return (<sink<P_IN>>sk);
}
public evaluateHelper<P_IN>(spliterator: Spliterator<P_IN>, flatten: boolean): Node<E_OUT> {
return undefined;
}
private sourceSpliterator(terminalFlags:number): spliterator<any>{
let tmp: spliterator<any> = null;
if(this.sourceStage.sourceSplit != null ){
tmp = this.sourceStage.sourceSplit;
this.sourceStage.sourceSplit = null;
}else if(this.sourceStage.sourceSupplier != null ){
tmp = this.sourceStage.sourceSupplier.get();
this.sourceStage.sourceSupplier=null;
}else{
throw new RuntimeException("source already consumed or closed");
}
// parallel Ctrl ...
if( terminalFlags!=0) this.combinedFlag = terminalFlags;
return tmp;
}
public abstract forEachWithCancel( sink:sink<E_OUT>, spliterator:spliterator<E_OUT>):boolean;
}
Object.package(this);