@rimbu/sorted
Version:
Immutable SortedMap and SortedSet implementations for TypeScript
268 lines • 10.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SortedMapBuilder = 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 SortedMapBuilder = /** @class */ (function (_super) {
tslib_1.__extends(SortedMapBuilder, _super);
function SortedMapBuilder(context, source, _entries, _children, size) {
if (size === void 0) { size = (_a = source === null || source === void 0 ? void 0 : source.size) !== null && _a !== void 0 ? _a : 0; }
var _a;
var _this = _super.call(this) || this;
_this.context = context;
_this.source = source;
_this._entries = _entries;
_this._children = _children;
_this.size = size;
_this.get = function (key, otherwise) {
if (!_this.context.comp.isComparable(key))
return (0, common_1.OptLazy)(otherwise);
if (undefined !== _this.source)
return _this.source.get(key, otherwise);
var entryIndex = _this.context.findIndex(key, _this.entries);
if (entryIndex >= 0) {
return _this.entries[entryIndex][1];
}
if (_this.hasChildren) {
var childIndex = common_2.SortedIndex.next(entryIndex);
var child = _this.children[childIndex];
return child.get(key, otherwise);
}
return (0, common_1.OptLazy)(otherwise);
};
// prettier-ignore
_this.hasKey = function (key) {
return base_1.Token !== _this.get(key, base_1.Token);
};
_this.addEntry = function (entry) {
_this.checkLock();
var result = _this.addEntryInternal(entry);
_this.normalize();
return result;
};
_this.addEntries = function (source) {
_this.checkLock();
return stream_1.Stream.from(source).filterPure({ pred: _this.addEntry }).count() > 0;
};
_this.set = function (key, value) {
return _this.addEntry([key, value]);
};
_this.removeKey = function (key, otherwise) {
_this.checkLock();
if (!_this.context.comp.isComparable(key))
return (0, common_1.OptLazy)(otherwise);
var result = _this.removeInternal(key, otherwise);
_this.normalize();
return result;
};
// prettier-ignore
_this.removeKeys = function (keys) {
_this.checkLock();
if ((0, custom_1.isEmptyStreamSourceInstance)(keys))
return false;
var notFound = Symbol();
return (stream_1.Stream.from(keys)
.mapPure(_this.removeKey, notFound)
.countElement(notFound, { negate: true }) > 0);
};
_this.modifyAt = function (key, options) {
_this.checkLock();
var result = _this.modifyAtInternal(key, options);
_this.normalize();
return result;
};
// prettier-ignore
_this.updateAt = function (key, update, otherwise) {
var result;
var found = false;
_this.modifyAt(key, {
ifExists: function (value) {
result = value;
found = true;
return (0, common_1.Update)(value, update);
},
});
if (!found)
return (0, common_1.OptLazy)(otherwise);
return result;
};
_this.build = function () {
if (undefined !== _this.source)
return _this.source;
if (_this.size === 0)
return _this.context.empty();
if (!_this.hasChildren) {
return _this.context.leaf(_this.entries.slice());
}
return _this.context.inner(_this.entries.slice(), _this.children.map(function (child) { return child.build(); }), _this.size);
};
// prettier-ignore
_this.buildMapValues = function (f) {
if (undefined !== _this.source)
return _this.source.mapValues(f);
if (_this.size === 0)
return _this.context.empty();
var newEntries = _this.entries.map(function (entry) { return [
entry[0],
f(entry[1], entry[0]),
]; });
if (!_this.hasChildren) {
return _this.context.leaf(newEntries);
}
return _this.context.inner(newEntries, _this.children.map(function (c) { return c.buildMapValues(f); }), _this.size);
};
return _this;
}
SortedMapBuilder.prototype.createNew = function (source, _entries, _children, size) {
return new SortedMapBuilder(this.context, source, _entries, _children, size);
};
SortedMapBuilder.prototype.prepareMutate = function () {
var _this = this;
if (undefined === this._entries) {
if (undefined !== this.source) {
if (this.context.isSortedMapEmpty(this.source)) {
this._entries = [];
this._children = [];
}
else if (this.context.isSortedMapLeaf(this.source)) {
this._entries = this.source.entries.slice();
}
else if (this.context.isSortedMapInner(this.source)) {
this._entries = this.source.entries.slice();
this._children = this.source.children.map(function (child) { return _this.createNew(child); });
}
}
if (undefined === this._entries) {
this._entries = [];
}
}
};
Object.defineProperty(SortedMapBuilder.prototype, "children", {
get: function () {
this.prepareMutate();
return this._children;
},
set: function (value) {
this.prepareMutate();
this.source = undefined;
this._children = value;
},
enumerable: false,
configurable: true
});
SortedMapBuilder.prototype.addEntryInternal = function (entry) {
var entryIndex = this.context.findIndex(entry[0], this.entries);
if (entryIndex >= 0) {
var currentEntry = this.entries[entryIndex];
if (Object.is(currentEntry[1], entry[1]))
return false;
this.source = undefined;
this.entries[entryIndex] = entry;
return true;
}
var childIndex = common_2.SortedIndex.next(entryIndex);
if (!this.hasChildren) {
this.source = undefined;
this.size++;
this.entries.splice(childIndex, 0, entry);
return true;
}
var child = this.children[childIndex];
var preSize = child.size;
var changed = child.addEntryInternal(entry);
if (!changed)
return false;
this.source = undefined;
this.size += child.size - preSize;
this.normalizeChildDecrease(childIndex);
return true;
};
SortedMapBuilder.prototype.removeInternal = function (key, otherwise) {
if (this.size === 0)
return (0, common_1.OptLazy)(otherwise);
var entryIndex = this.context.findIndex(key, this.entries);
if (entryIndex >= 0) {
this.source = undefined;
this.size--;
if (!this.hasChildren) {
var removed_1 = this.entries.splice(entryIndex, 1);
return removed_1[0][1];
}
var leftChild = this.children[entryIndex];
var rightChild = this.children[entryIndex + 1];
var removed = this.entries[entryIndex];
if (leftChild.size >= rightChild.size) {
this.entries[entryIndex] = leftChild.deleteMax();
this.normalizeChildIncrease(entryIndex);
}
else {
this.entries[entryIndex] = rightChild.deleteMin();
this.normalizeChildIncrease(entryIndex + 1);
}
return removed[1];
}
if (!this.hasChildren)
return (0, common_1.OptLazy)(otherwise);
var childIndex = common_2.SortedIndex.next(entryIndex);
var child = this.children[childIndex];
var preSize = child.size;
var token = Symbol();
var oldValue = child.removeInternal(key, token);
if (token === oldValue)
return (0, common_1.OptLazy)(otherwise);
this.source = undefined;
this.size += child.size - preSize;
this.normalizeChildIncrease(childIndex);
return oldValue;
};
SortedMapBuilder.prototype.modifyAtInternal = function (key, options) {
var entryIndex = this.context.findIndex(key, this.entries);
if (entryIndex >= 0) {
if (undefined === options.ifExists)
return false;
var currentEntry = this.entries[entryIndex];
var currentValue = currentEntry[1];
var newValue = options.ifExists instanceof Function
? options.ifExists(currentValue, base_1.Token)
: options.ifExists;
if (newValue === currentValue)
return false;
if (base_1.Token === newValue) {
return base_1.Token !== this.removeInternal(key, base_1.Token);
}
this.source = undefined;
var newEntry = [key, newValue];
this.entries[entryIndex] = newEntry;
return true;
}
var childIndex = common_2.SortedIndex.next(entryIndex);
if (!this.hasChildren) {
if (undefined === options.ifNew)
return false;
var newValue = (0, common_1.OptLazyOr)(options.ifNew, base_1.Token);
if (base_1.Token === newValue)
return false;
this.source = undefined;
this.size++;
this.entries.splice(childIndex, 0, [key, newValue]);
return true;
}
var child = this.children[childIndex];
var preSize = child.size;
var changed = child.modifyAtInternal(key, options);
if (!changed)
return false;
this.source = undefined;
this.size += child.size - preSize;
this.normalizeChildDecrease(childIndex);
this.normalizeChildIncrease(childIndex);
return changed;
};
return SortedMapBuilder;
}(common_2.SortedBuilder));
exports.SortedMapBuilder = SortedMapBuilder;
//# sourceMappingURL=builder.cjs.map