@effect-ts/system
Version:
Effect-TS is a zero dependency set of libraries to write highly productive, purely functional TypeScript at scale.
258 lines (218 loc) • 10.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.zipAllSortedByKeyWithExec = zipAllSortedByKeyWithExec;
exports.zipAllSortedByKeyWithExec_ = zipAllSortedByKeyWithExec_;
var A = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../../../Collections/Immutable/Chunk/index.js"));
var Tp = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../../../Collections/Immutable/Tuple/index.js"));
var T = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../../../Effect/index.js"));
var Ex = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../../../Exit/index.js"));
var O = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../../../Option/index.js"));
var CombineChunks = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("../_internal/api/combineChunks.js"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
// ets_tracing: off
class DrainLeft {
constructor() {
this._tag = "DrainLeft";
}
}
class DrainRight {
constructor() {
this._tag = "DrainRight";
}
}
class PullBoth {
constructor() {
this._tag = "PullBoth";
}
}
class PullLeft {
constructor(rightChunk) {
this.rightChunk = rightChunk;
this._tag = "PullLeft";
}
}
class PullRight {
constructor(leftChunk) {
this.leftChunk = leftChunk;
this._tag = "PullRight";
}
}
/**
* Zips this stream that is sorted by distinct keys and the specified
* stream that is sorted by distinct keys to produce a new stream that is
* sorted by distinct keys. Uses the functions `left`, `right`, and `both`
* to handle the cases where a key and value exist in this stream, that
* stream, or both streams.
*
* This allows zipping potentially unbounded streams of data by key in
* constant space but the caller is responsible for ensuring that the
* streams are sorted by distinct keys.
*
* The execution strategy `exec` will be used to determine whether to pull
* from the streams sequentially or in parallel.
*/
function zipAllSortedByKeyWithExec_(self, that, left, right, both, ord, exec) {
const pull = (state, pullLeft, pullRight) => {
switch (state._tag) {
case "DrainLeft":
return T.fold_(pullLeft, e => Ex.fail(e), leftChunk => Ex.succeed(Tp.tuple(A.map_(leftChunk, ({
tuple: [k, a]
}) => Tp.tuple(k, left(a))), new DrainLeft())));
case "DrainRight":
return T.fold_(pullRight, e => Ex.fail(e), rightChunk => Ex.succeed(Tp.tuple(A.map_(rightChunk, ({
tuple: [k, b]
}) => Tp.tuple(k, right(b))), new DrainRight())));
case "PullBoth":
{
switch (exec._tag) {
case "Sequential":
return T.foldM_(pullLeft, O.fold(() => pull(new DrainRight(), pullLeft, pullRight), e => T.succeed(Ex.fail(O.some(e)))), leftChunk => A.isEmpty(leftChunk) ? pull(new PullBoth(), pullLeft, pullRight) : pull(new PullRight(leftChunk), pullLeft, pullRight));
default:
return T.foldM_(T.zipPar_(T.unsome(pullLeft), T.unsome(pullRight)), e => T.succeed(Ex.fail(O.some(e))), ({
tuple: [a, b]
}) => {
if (O.isSome(a) && O.isSome(b)) {
const leftChunk = a.value;
const rightChunk = b.value;
if (A.isEmpty(leftChunk) && A.isEmpty(rightChunk)) {
return pull(new PullBoth(), pullLeft, pullRight);
} else if (A.isEmpty(leftChunk)) {
return pull(new PullLeft(rightChunk), pullLeft, pullRight);
} else if (A.isEmpty(rightChunk)) {
return pull(new PullRight(leftChunk), pullLeft, pullRight);
} else {
return T.succeed(Ex.succeed(mergeSortedByKeyChunk(leftChunk, rightChunk)));
}
} else if (O.isSome(a)) {
const leftChunk = a.value;
return A.isEmpty(leftChunk) ? pull(new DrainLeft(), pullLeft, pullRight) : T.succeed(Ex.succeed(Tp.tuple(A.map_(leftChunk, ({
tuple: [k, a]
}) => Tp.tuple(k, left(a))), new DrainLeft())));
} else if (O.isSome(b)) {
const rightChunk = b.value;
return A.isEmpty(rightChunk) ? pull(new DrainLeft(), pullLeft, pullRight) : T.succeed(Ex.succeed(Tp.tuple(A.map_(rightChunk, ({
tuple: [k, b]
}) => Tp.tuple(k, right(b))), new DrainRight())));
} else {
return T.succeed(Ex.fail(O.none));
}
});
}
}
case "PullLeft":
{
const rightChunk = state.rightChunk;
return T.foldM_(pullLeft, O.fold(() => T.succeed(Ex.succeed(Tp.tuple(A.map_(rightChunk, ({
tuple: [k, b]
}) => Tp.tuple(k, right(b))), new DrainRight()))), e => T.succeed(Ex.fail(O.some(e)))), leftChunk => A.isEmpty(leftChunk) ? pull(new PullLeft(rightChunk), pullLeft, pullRight) : T.succeed(Ex.succeed(mergeSortedByKeyChunk(leftChunk, rightChunk))));
}
case "PullRight":
{
const leftChunk = state.leftChunk;
return T.foldM_(pullRight, O.fold(() => T.succeed(Ex.succeed(Tp.tuple(A.map_(leftChunk, ({
tuple: [k, a]
}) => Tp.tuple(k, left(a))), new DrainLeft()))), e => T.succeed(Ex.fail(O.some(e)))), rightChunk => A.isEmpty(rightChunk) ? pull(new PullRight(leftChunk), pullLeft, pullRight) : T.succeed(Ex.succeed(mergeSortedByKeyChunk(leftChunk, rightChunk))));
}
}
};
const mergeSortedByKeyChunk = (leftChunk, rightChunk) => {
const builder = A.builder();
let state;
let leftIndex = 0;
let rightIndex = 0;
let leftTuple = A.unsafeGet_(leftChunk, leftIndex);
let rightTuple = A.unsafeGet_(rightChunk, rightIndex);
let k1 = leftTuple.get(0);
let a = leftTuple.get(1);
let k2 = rightTuple.get(0);
let b = rightTuple.get(1);
let loop = true;
const hasNext = (c, index) => index < A.size(c) - 1;
while (loop) {
const compare = ord.compare(k1, k2);
if (compare === 0) {
builder.append(Tp.tuple(k1, both(a, b)));
if (hasNext(leftChunk, leftIndex) && hasNext(rightChunk, rightIndex)) {
leftIndex += 1;
rightIndex += 1;
leftTuple = A.unsafeGet_(leftChunk, leftIndex);
rightTuple = A.unsafeGet_(rightChunk, rightIndex);
k1 = leftTuple.get(0);
a = leftTuple.get(1);
k2 = rightTuple.get(0);
b = rightTuple.get(1);
} else if (hasNext(leftChunk, leftIndex)) {
state = new PullRight(A.drop_(leftChunk, leftIndex + 1));
loop = false;
} else if (hasNext(rightChunk, rightIndex)) {
state = new PullLeft(A.drop_(rightChunk, rightIndex + 1));
loop = false;
} else {
state = new PullBoth();
loop = false;
}
} else if (compare < 0) {
builder.append(Tp.tuple(k1, left(a)));
if (hasNext(leftChunk, leftIndex)) {
leftIndex += 1;
leftTuple = A.unsafeGet_(leftChunk, leftIndex);
k1 = leftTuple.get(0);
a = leftTuple.get(1);
} else {
const rightBuilder = A.builder();
rightBuilder.append(rightTuple);
while (hasNext(rightChunk, rightIndex)) {
rightIndex += 1;
rightTuple = A.unsafeGet_(rightChunk, rightIndex);
rightBuilder.append(rightTuple);
state = new PullLeft(rightBuilder.build());
loop = false;
}
}
} else {
builder.append(Tp.tuple(k2, right(b)));
if (hasNext(rightChunk, rightIndex)) {
rightIndex += 1;
rightTuple = A.unsafeGet_(rightChunk, rightIndex);
k2 = rightTuple.get(0);
b = rightTuple.get(1);
} else {
const leftBuilder = A.builder();
leftBuilder.append(leftTuple);
while (hasNext(leftChunk, leftIndex)) {
leftIndex += 1;
leftTuple = A.unsafeGet_(leftChunk, leftIndex);
leftBuilder.append(leftTuple);
state = new PullRight(leftBuilder.build());
loop = false;
}
}
}
}
return Tp.tuple(builder.build(), state);
};
return CombineChunks.combineChunks_(self, that, new PullBoth(), pull);
}
/**
* Zips this stream that is sorted by distinct keys and the specified
* stream that is sorted by distinct keys to produce a new stream that is
* sorted by distinct keys. Uses the functions `left`, `right`, and `both`
* to handle the cases where a key and value exist in this stream, that
* stream, or both streams.
*
* This allows zipping potentially unbounded streams of data by key in
* constant space but the caller is responsible for ensuring that the
* streams are sorted by distinct keys.
*
* The execution strategy `exec` will be used to determine whether to pull
* from the streams sequentially or in parallel.
*
* @ets_data_first zipAllSortedByKeyWithExec_
*/
function zipAllSortedByKeyWithExec(that, left, right, both, ord, exec) {
return self => zipAllSortedByKeyWithExec_(self, that, left, right, both, ord, exec);
}
//# sourceMappingURL=zipAllSortedByKeyWithExec.js.map