UNPKG

@rimbu/sorted

Version:

Immutable SortedMap and SortedSet implementations for TypeScript

626 lines 26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SortedSetInner = exports.SortedSetLeaf = exports.SortedSetNode = exports.SortedSetEmpty = void 0; var tslib_1 = require("tslib"); var base_1 = require("@rimbu/base"); var common_1 = require("@rimbu/common"); var stream_1 = require("@rimbu/stream"); var custom_1 = require("@rimbu/stream/custom"); var common_2 = require("@rimbu/sorted/common"); var SortedSetEmpty = /** @class */ (function (_super) { tslib_1.__extends(SortedSetEmpty, _super); function SortedSetEmpty(context) { var _this = _super.call(this) || this; _this.context = context; return _this; } SortedSetEmpty.prototype.streamRange = function () { return stream_1.Stream.empty(); }; SortedSetEmpty.prototype.streamSliceIndex = function () { return stream_1.Stream.empty(); }; SortedSetEmpty.prototype.has = function () { return false; }; SortedSetEmpty.prototype.findIndex = function () { return -1; }; SortedSetEmpty.prototype.add = function (value) { return this.context.leaf([value]); }; SortedSetEmpty.prototype.addAll = function (values) { return this.context.from(values); }; SortedSetEmpty.prototype.remove = function () { return this; }; SortedSetEmpty.prototype.removeAll = function () { return this; }; SortedSetEmpty.prototype.slice = function () { return this; }; SortedSetEmpty.prototype.union = function (other) { if (this.context.isSortedSetLeaf(other) || this.context.isSortedSetNode(other)) { if (other.context === this.context) return other; } return this.context.from(other); }; SortedSetEmpty.prototype.difference = function () { return this.context.empty(); }; SortedSetEmpty.prototype.intersect = function () { return this.context.empty(); }; SortedSetEmpty.prototype.symDifference = function (other) { return this.union(other); }; SortedSetEmpty.prototype.toBuilder = function () { return this.context.builder(); }; SortedSetEmpty.prototype.toString = function () { return "SortedSet()"; }; SortedSetEmpty.prototype.toJSON = function () { return { dataType: this.context.typeTag, value: [], }; }; return SortedSetEmpty; }(common_2.SortedEmpty)); exports.SortedSetEmpty = SortedSetEmpty; var SortedSetNode = /** @class */ (function (_super) { tslib_1.__extends(SortedSetNode, _super); function SortedSetNode() { return _super !== null && _super.apply(this, arguments) || this; } SortedSetNode.prototype.asNormal = function () { return this; }; SortedSetNode.prototype.getSliceRange = function (range) { var _a = common_1.Range.getNormalizedRange(range), start = _a.start, end = _a.end; var startIndex = 0; var endIndex = this.size - 1; if (undefined !== start) { var _b = tslib_1.__read(start, 2), startValue = _b[0], startInclude = _b[1]; startIndex = this.getInsertIndexOf(startValue); if (startIndex < 0) startIndex = common_2.SortedIndex.next(startIndex); else if (!startInclude) startIndex++; } if (undefined !== end) { var _c = tslib_1.__read(end, 2), endValue = _c[0], endInclude = _c[1]; endIndex = this.getInsertIndexOf(endValue); if (endIndex < 0) endIndex = common_2.SortedIndex.prev(endIndex); else if (!endInclude) endIndex--; } return { startIndex: startIndex, endIndex: endIndex }; }; SortedSetNode.prototype.streamRange = function (range, options) { var _a = this.getSliceRange(range), startIndex = _a.startIndex, endIndex = _a.endIndex; return this.streamSliceIndex({ start: [startIndex, true], end: [endIndex, true], }, options); }; SortedSetNode.prototype.add = function (value) { return this.addInternal(value).normalize().assumeNonEmpty(); }; SortedSetNode.prototype.addAll = function (values) { if ((0, custom_1.isEmptyStreamSourceInstance)(values)) return this; var builder = this.toBuilder(); builder.addAll(values); return builder.build().assumeNonEmpty(); }; SortedSetNode.prototype.remove = function (value) { if (!this.context.comp.isComparable(value)) return this; return this.removeInternal(value).normalize(); }; SortedSetNode.prototype.removeAll = function (values) { if ((0, custom_1.isEmptyStreamSourceInstance)(values)) return this; var builder = this.toBuilder(); builder.removeAll(values); return builder.build(); }; SortedSetNode.prototype.filter = function (pred, options) { if (options === void 0) { options = {}; } var builder = this.context.builder(); builder.addAll(this.stream().filter(pred, options)); if (builder.size === this.size) return this; return builder.build(); }; SortedSetNode.prototype.take = function (amount) { if (amount === 0) return this.context.empty(); if (amount >= this.size || -amount > this.size) return this; if (amount < 0) return this.drop(this.size + amount); return this.takeInternal(amount).normalize(); }; SortedSetNode.prototype.drop = function (amount) { if (amount === 0) return this; if (amount >= this.size || -amount > this.size) return this.context.empty(); if (amount < 0) return this.take(this.size + amount); return this.dropInternal(amount).normalize(); }; SortedSetNode.prototype.sliceIndex = function (range) { var indexRange = common_1.IndexRange.getIndicesFor(range, this.size); if (indexRange === 'empty') return this.context.empty(); if (indexRange === 'all') return this; var _a = tslib_1.__read(indexRange, 2), start = _a[0], end = _a[1]; return this.drop(start).take(end - start + 1); }; SortedSetNode.prototype.slice = function (range) { var _a = this.getSliceRange(range), startIndex = _a.startIndex, endIndex = _a.endIndex; return this.sliceIndex({ start: [startIndex, true], end: [endIndex, true], }); }; SortedSetNode.prototype.union = function (other) { if (other === this) return this; if ((0, custom_1.isEmptyStreamSourceInstance)(other)) return this; var builder = this.toBuilder(); builder.addAll(other); return builder.build(); }; SortedSetNode.prototype.difference = function (other) { if (other === this) return this.context.empty(); if ((0, custom_1.isEmptyStreamSourceInstance)(other)) return this; var builder = this.toBuilder(); builder.removeAll(other); return builder.build(); }; SortedSetNode.prototype.intersect = function (other) { if (other === this) return this; if ((0, custom_1.isEmptyStreamSourceInstance)(other)) return this.context.empty(); var builder = this.context.builder(); var otherIter = stream_1.Stream.from(other)[Symbol.iterator](); var done = Symbol('Done'); if (this.context.isSortedSetNode(other)) { var thisIt = this[Symbol.iterator](); var thisValue = thisIt.fastNext(done); var otherValue = otherIter.fastNext(done); var comp = this.context.comp; while (true) { if (done === thisValue || done === otherValue) { break; } var result = comp.compare(thisValue, otherValue); if (result === 0) builder.add(thisValue); if (result <= 0) thisValue = thisIt.fastNext(done); if (result >= 0) otherValue = otherIter.fastNext(done); } } else { var value = void 0; while (done !== (value = otherIter.fastNext(done))) { if (this.has(value)) builder.add(value); } } if (builder.size === this.size) return this; return builder.build(); }; SortedSetNode.prototype.symDifference = function (other) { if (other === this) return this.context.empty(); if ((0, custom_1.isEmptyStreamSourceInstance)(other)) return this; var builder = this.toBuilder(); stream_1.Stream.from(other) .filterPure({ pred: builder.remove, negate: true }) .forEach(builder.add); return builder.build(); }; SortedSetNode.prototype.toBuilder = function () { return this.context.createBuilder(this); }; SortedSetNode.prototype.toString = function () { return this.stream().join({ start: 'SortedSet(', sep: ', ', end: ')' }); }; SortedSetNode.prototype.toJSON = function () { return { dataType: this.context.typeTag, value: this.toArray(), }; }; return SortedSetNode; }(common_2.SortedNonEmptyBase)); exports.SortedSetNode = SortedSetNode; var SortedSetLeaf = /** @class */ (function (_super) { tslib_1.__extends(SortedSetLeaf, _super); function SortedSetLeaf(context, entries) { var _this = _super.call(this) || this; _this.context = context; _this.entries = entries; return _this; } SortedSetLeaf.prototype.copy = function (entries) { if (entries === this.entries) return this; return this.context.leaf(entries); }; Object.defineProperty(SortedSetLeaf.prototype, "size", { get: function () { return this.entries.length; }, enumerable: false, configurable: true }); SortedSetLeaf.prototype.stream = function (options) { if (options === void 0) { options = {}; } return stream_1.Stream.fromArray(this.entries, options); }; SortedSetLeaf.prototype.streamSliceIndex = function (range, options) { if (options === void 0) { options = {}; } var _a = options.reversed, reversed = _a === void 0 ? false : _a; return stream_1.Stream.fromArray(this.entries, { range: range, reversed: reversed }); }; SortedSetLeaf.prototype.min = function () { return this.entries[0]; }; SortedSetLeaf.prototype.max = function () { return base_1.Arr.last(this.entries); }; SortedSetLeaf.prototype.has = function (value) { if (!this.context.comp.isComparable(value)) return false; return this.context.findIndex(value, this.entries) >= 0; }; SortedSetLeaf.prototype.findIndex = function (value) { if (!this.context.comp.isComparable(value)) return -1; var index = this.context.findIndex(value, this.entries); return index < 0 ? -1 : index; }; SortedSetLeaf.prototype.getAtIndex = function (index, otherwise) { if (index >= this.size || -index > this.size) { return (0, common_1.OptLazy)(otherwise); } if (index < 0) { return this.getAtIndex(this.size + index, otherwise); } return this.entries[index]; }; SortedSetLeaf.prototype.forEach = function (f, options) { if (options === void 0) { options = {}; } var _a = options.state, state = _a === void 0 ? (0, common_1.TraverseState)() : _a; if (state.halted) return; base_1.Arr.forEach(this.entries, f, state); }; SortedSetLeaf.prototype.toArray = function () { return this.entries.slice(); }; // internal methods SortedSetLeaf.prototype.getInsertIndexOf = function (value) { return this.context.findIndex(value, this.entries); }; SortedSetLeaf.prototype.addInternal = function (value) { var index = this.context.findIndex(value, this.entries); if (index >= 0) { var newEntries_1 = base_1.Arr.update(this.entries, index, value); return this.copy(newEntries_1); } var insertIndex = common_2.SortedIndex.next(index); var newEntries = base_1.Arr.insert(this.entries, insertIndex, value); return this.copy(newEntries); }; SortedSetLeaf.prototype.removeInternal = function (value) { var entryIndex = this.context.findIndex(value, this.entries); if (entryIndex < 0) return this; var currentValue = this.entries[entryIndex]; if (this.context.comp.compare(currentValue, value) !== 0) return this; var newEntries = base_1.Arr.splice(this.mutateEntries, entryIndex, 1); return this.copy(newEntries); }; SortedSetLeaf.prototype.takeInternal = function (amount) { return this.context.leaf(this.entries.slice(0, amount)); }; SortedSetLeaf.prototype.dropInternal = function (amount) { return this.context.leaf(this.entries.slice(amount)); }; SortedSetLeaf.prototype.deleteMin = function () { return (0, common_2.leafDeleteMin)(this); }; SortedSetLeaf.prototype.deleteMax = function () { return (0, common_2.leafDeleteMax)(this); }; SortedSetLeaf.prototype.mutateSplitRight = function (index) { return (0, common_2.leafMutateSplitRight)(this, index); }; SortedSetLeaf.prototype.mutateGiveToLeft = function (left, toLeft) { return (0, common_2.leafMutateGiveToLeft)(this, left, toLeft); }; SortedSetLeaf.prototype.mutateGiveToRight = function (right, toRight) { return (0, common_2.leafMutateGiveToRight)(this, right, toRight); }; SortedSetLeaf.prototype.mutateGetFromLeft = function (left, toMe) { return (0, common_2.leafMutateGetFromLeft)(this, left, toMe); }; SortedSetLeaf.prototype.mutateGetFromRight = function (right, toMe) { return (0, common_2.leafMutateGetFromRight)(this, right, toMe); }; SortedSetLeaf.prototype.mutateJoinLeft = function (left, entry) { return (0, common_2.leafMutateJoinLeft)(this, left, entry); }; SortedSetLeaf.prototype.mutateJoinRight = function (right, entry) { return (0, common_2.leafMutateJoinRight)(this, right, entry); }; SortedSetLeaf.prototype.normalize = function () { if (this.entries.length === 0) return this.context.empty(); if (this.entries.length <= this.context.maxEntries) return this; var size = this.size; var _a = tslib_1.__read(this.mutateSplitRight(), 2), upEntry = _a[0], rightNode = _a[1]; return this.context.inner([upEntry], [this, rightNode], size); }; return SortedSetLeaf; }(SortedSetNode)); exports.SortedSetLeaf = SortedSetLeaf; var SortedSetInner = /** @class */ (function (_super) { tslib_1.__extends(SortedSetInner, _super); function SortedSetInner(context, entries, children, size) { var _this = _super.call(this) || this; _this.context = context; _this.entries = entries; _this.children = children; _this.size = size; return _this; } Object.defineProperty(SortedSetInner.prototype, "mutateChildren", { get: function () { return this.children; }, enumerable: false, configurable: true }); SortedSetInner.prototype.copy = function (entries, children, size) { if (entries === void 0) { entries = this.entries; } if (children === void 0) { children = this.children; } if (size === void 0) { size = this.size; } if (entries === this.entries && children === this.children && size === this.size) return this; return this.context.inner(entries, children, size); }; SortedSetInner.prototype.stream = function (options) { if (options === void 0) { options = {}; } var token = Symbol(); return stream_1.Stream.zipAll(token, stream_1.Stream.fromArray(this.children, options), stream_1.Stream.fromArray(this.entries, options)).flatMap(function (_a) { var _b = tslib_1.__read(_a, 2), child = _b[0], e = _b[1]; if (token === child) base_1.RimbuError.throwInvalidStateError(); if (token === e) return child.stream(options); return child.stream(options).append(e); }); }; SortedSetInner.prototype.streamSliceIndex = function (range, options) { if (options === void 0) { options = {}; } var _a = options.reversed, reversed = _a === void 0 ? false : _a; return (0, common_2.innerStreamSliceIndex)(this, range, reversed); }; SortedSetInner.prototype.min = function () { return this.children[0].min(); }; SortedSetInner.prototype.max = function () { return base_1.Arr.last(this.children).max(); }; SortedSetInner.prototype.has = function (value) { if (!this.context.comp.isComparable(value)) return false; var index = this.context.findIndex(value, this.entries); if (index >= 0) return true; var childIndex = common_2.SortedIndex.next(index); var child = this.children[childIndex]; return child.has(value); }; SortedSetInner.prototype.findIndex = function (value) { if (!this.context.comp.isComparable(value)) return -1; var index = this.context.findIndex(value, this.entries); if (index >= 0) return (this.children.slice(0, index + 1).reduce(function (x, y) { return x + y.size; }, 0) + index); var childIndex = common_2.SortedIndex.next(index); var child = this.children[childIndex]; var index$ = child.findIndex(value); if (index$ >= 0) { return (index$ + (this.children.slice(0, childIndex).reduce(function (x, y) { return x + y.size; }, 0) - index - 1)); } return -1; }; SortedSetInner.prototype.getAtIndex = function (index, otherwise) { return (0, common_2.innerGetAtIndex)(this, index, otherwise); }; SortedSetInner.prototype.forEach = function (f, options) { if (options === void 0) { options = {}; } var _a = options.state, state = _a === void 0 ? (0, common_1.TraverseState)() : _a; var i = -1; var halt = state.halt; while (!state.halted && i < this.entries.length) { if (i >= 0) f(this.entries[i], state.nextIndex(), halt); else { var childIndex = common_2.SortedIndex.next(i); this.children[childIndex].forEach(f, { state: state }); } i = common_2.SortedIndex.next(i); } }; SortedSetInner.prototype.toArray = function () { var i = -1; var result = []; while (i < this.entries.length) { if (i >= 0) result.push(this.entries[i]); else { var childIndex = common_2.SortedIndex.next(i); result = result.concat(this.children[childIndex].toArray()); } i = common_2.SortedIndex.next(i); } return result; }; // internal methods SortedSetInner.prototype.getInsertIndexOf = function (value) { var index = 0; for (var i = 0; i < this.entries.length; i++) { var comp = this.context.comp.compare(value, this.entries[i]); var child = this.children[i]; if (comp < 0) { var insertIndex_1 = child.getInsertIndexOf(value); if (insertIndex_1 < 0) return -index + insertIndex_1; return index + insertIndex_1; } index += child.size + 1; if (comp === 0) return index - 1; } var insertIndex = base_1.Arr.last(this.children).getInsertIndexOf(value); if (insertIndex < 0) return -index + insertIndex; return index + insertIndex; }; SortedSetInner.prototype.deleteMin = function () { return (0, common_2.innerDeleteMin)(this); }; SortedSetInner.prototype.deleteMax = function () { return (0, common_2.innerDeleteMax)(this); }; SortedSetInner.prototype.mutateSplitRight = function (index) { return (0, common_2.innerMutateSplitRight)(this, index); }; SortedSetInner.prototype.mutateGiveToLeft = function (left, toLeft) { return (0, common_2.innerMutateGiveToLeft)(this, left, toLeft); }; SortedSetInner.prototype.mutateGiveToRight = function (right, toRight) { return (0, common_2.innerMutateGiveToRight)(this, right, toRight); }; SortedSetInner.prototype.mutateGetFromLeft = function (left, toMe) { return (0, common_2.innerMutateGetFromLeft)(this, left, toMe); }; SortedSetInner.prototype.mutateGetFromRight = function (right, toMe) { return (0, common_2.innerMutateGetFromRight)(this, right, toMe); }; SortedSetInner.prototype.mutateJoinLeft = function (left, entry) { return (0, common_2.innerMutateJoinLeft)(this, left, entry); }; SortedSetInner.prototype.mutateJoinRight = function (right, entry) { return (0, common_2.innerMutateJoinRight)(this, right, entry); }; SortedSetInner.prototype.normalizeDownsizeChild = function (childIndex, newChild, newSize) { return (0, common_2.innerNormalizeDownsizeChild)(this, childIndex, newChild, newSize); }; SortedSetInner.prototype.normalizeIncreaseChild = function (childIndex, newChild, newSize) { return (0, common_2.innerNormalizeIncreaseChild)(this, childIndex, newChild, newSize); }; SortedSetInner.prototype.addInternal = function (value) { var entryIndex = this.context.findIndex(value, this.entries); if (entryIndex >= 0) { var newEntries = base_1.Arr.update(this.entries, entryIndex, value); return this.copy(newEntries); } var childIndex = common_2.SortedIndex.next(entryIndex); var child = this.children[childIndex]; var newChild = child.addInternal(value); if (newChild === child) return this; var newSize = this.size + newChild.size - child.size; if (newChild.entries.length <= this.context.maxEntries) { // no need to shift var newChildren = base_1.Arr.update(this.children, childIndex, newChild); return this.copy(undefined, newChildren, newSize); } return this.normalizeDownsizeChild(childIndex, newChild, newSize); }; SortedSetInner.prototype.removeInternal = function (value) { var entryIndex = this.context.findIndex(value, this.entries); if (entryIndex >= 0) { var currentValue = this.entries[entryIndex]; if (!Object.is(currentValue, value)) return this; // remove inner entry var leftChild = this.children[entryIndex]; var rightChild = this.children[entryIndex + 1]; if (leftChild.entries.length >= rightChild.entries.length) { var _a = tslib_1.__read(leftChild.deleteMax(), 2), max = _a[0], newLeft = _a[1]; var newEntries_2 = base_1.Arr.update(this.entries, entryIndex, max); var newSelf_1 = this.copy(newEntries_2); return newSelf_1.normalizeIncreaseChild(entryIndex, newLeft, this.size - 1); } var _b = tslib_1.__read(rightChild.deleteMin(), 2), min = _b[0], newRight = _b[1]; var newEntries = base_1.Arr.update(this.entries, entryIndex, min); var newSelf = this.copy(newEntries); return newSelf.normalizeIncreaseChild(entryIndex + 1, newRight, this.size - 1); } var childIndex = common_2.SortedIndex.next(entryIndex); var child = this.children[childIndex]; var newChild = child.removeInternal(value); var newSize = this.size + newChild.size - child.size; if (newChild.entries.length < this.context.minEntries) { return this.normalizeIncreaseChild(childIndex, newChild, newSize); } if (newChild.entries.length > this.context.maxEntries) { return this.normalizeDownsizeChild(childIndex, newChild, newSize); } var newChildren = base_1.Arr.update(this.children, childIndex, newChild); return this.copy(undefined, newChildren, this.size + newChild.size - child.size); }; SortedSetInner.prototype.takeInternal = function (amount) { return (0, common_2.innerTakeInternal)(this, amount); }; SortedSetInner.prototype.dropInternal = function (amount) { return (0, common_2.innerDropInternal)(this, amount); }; SortedSetInner.prototype.normalize = function () { if (this.entries.length === 0) return this.children[0].normalize(); if (this.entries.length <= this.context.maxEntries) return this; var size = this.size; var _a = tslib_1.__read(this.mutateSplitRight(), 2), upEntry = _a[0], rightNode = _a[1]; return this.copy([upEntry], [this, rightNode], size); }; return SortedSetInner; }(SortedSetNode)); exports.SortedSetInner = SortedSetInner; //# sourceMappingURL=immutable.cjs.map