UNPKG

@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
"use strict"; 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