monaco-editor
Version:
A browser based code editor
201 lines (200 loc) • 8.23 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { toUint32 } from '../core/uint.js';
var PrefixSumIndexOfResult = /** @class */ (function () {
function PrefixSumIndexOfResult(index, remainder) {
this.index = index;
this.remainder = remainder;
}
return PrefixSumIndexOfResult;
}());
export { PrefixSumIndexOfResult };
var PrefixSumComputer = /** @class */ (function () {
function PrefixSumComputer(values) {
this.values = values;
this.prefixSum = new Uint32Array(values.length);
this.prefixSumValidIndex = new Int32Array(1);
this.prefixSumValidIndex[0] = -1;
}
PrefixSumComputer.prototype.getCount = function () {
return this.values.length;
};
PrefixSumComputer.prototype.insertValues = function (insertIndex, insertValues) {
insertIndex = toUint32(insertIndex);
var oldValues = this.values;
var oldPrefixSum = this.prefixSum;
var insertValuesLen = insertValues.length;
if (insertValuesLen === 0) {
return false;
}
this.values = new Uint32Array(oldValues.length + insertValuesLen);
this.values.set(oldValues.subarray(0, insertIndex), 0);
this.values.set(oldValues.subarray(insertIndex), insertIndex + insertValuesLen);
this.values.set(insertValues, insertIndex);
if (insertIndex - 1 < this.prefixSumValidIndex[0]) {
this.prefixSumValidIndex[0] = insertIndex - 1;
}
this.prefixSum = new Uint32Array(this.values.length);
if (this.prefixSumValidIndex[0] >= 0) {
this.prefixSum.set(oldPrefixSum.subarray(0, this.prefixSumValidIndex[0] + 1));
}
return true;
};
PrefixSumComputer.prototype.changeValue = function (index, value) {
index = toUint32(index);
value = toUint32(value);
if (this.values[index] === value) {
return false;
}
this.values[index] = value;
if (index - 1 < this.prefixSumValidIndex[0]) {
this.prefixSumValidIndex[0] = index - 1;
}
return true;
};
PrefixSumComputer.prototype.removeValues = function (startIndex, cnt) {
startIndex = toUint32(startIndex);
cnt = toUint32(cnt);
var oldValues = this.values;
var oldPrefixSum = this.prefixSum;
if (startIndex >= oldValues.length) {
return false;
}
var maxCnt = oldValues.length - startIndex;
if (cnt >= maxCnt) {
cnt = maxCnt;
}
if (cnt === 0) {
return false;
}
this.values = new Uint32Array(oldValues.length - cnt);
this.values.set(oldValues.subarray(0, startIndex), 0);
this.values.set(oldValues.subarray(startIndex + cnt), startIndex);
this.prefixSum = new Uint32Array(this.values.length);
if (startIndex - 1 < this.prefixSumValidIndex[0]) {
this.prefixSumValidIndex[0] = startIndex - 1;
}
if (this.prefixSumValidIndex[0] >= 0) {
this.prefixSum.set(oldPrefixSum.subarray(0, this.prefixSumValidIndex[0] + 1));
}
return true;
};
PrefixSumComputer.prototype.getTotalValue = function () {
if (this.values.length === 0) {
return 0;
}
return this._getAccumulatedValue(this.values.length - 1);
};
PrefixSumComputer.prototype.getAccumulatedValue = function (index) {
if (index < 0) {
return 0;
}
index = toUint32(index);
return this._getAccumulatedValue(index);
};
PrefixSumComputer.prototype._getAccumulatedValue = function (index) {
if (index <= this.prefixSumValidIndex[0]) {
return this.prefixSum[index];
}
var startIndex = this.prefixSumValidIndex[0] + 1;
if (startIndex === 0) {
this.prefixSum[0] = this.values[0];
startIndex++;
}
if (index >= this.values.length) {
index = this.values.length - 1;
}
for (var i = startIndex; i <= index; i++) {
this.prefixSum[i] = this.prefixSum[i - 1] + this.values[i];
}
this.prefixSumValidIndex[0] = Math.max(this.prefixSumValidIndex[0], index);
return this.prefixSum[index];
};
PrefixSumComputer.prototype.getIndexOf = function (accumulatedValue) {
accumulatedValue = Math.floor(accumulatedValue); //@perf
// Compute all sums (to get a fully valid prefixSum)
this.getTotalValue();
var low = 0;
var high = this.values.length - 1;
var mid = 0;
var midStop = 0;
var midStart = 0;
while (low <= high) {
mid = low + ((high - low) / 2) | 0;
midStop = this.prefixSum[mid];
midStart = midStop - this.values[mid];
if (accumulatedValue < midStart) {
high = mid - 1;
}
else if (accumulatedValue >= midStop) {
low = mid + 1;
}
else {
break;
}
}
return new PrefixSumIndexOfResult(mid, accumulatedValue - midStart);
};
return PrefixSumComputer;
}());
export { PrefixSumComputer };
var PrefixSumComputerWithCache = /** @class */ (function () {
function PrefixSumComputerWithCache(values) {
this._cacheAccumulatedValueStart = 0;
this._cache = null;
this._actual = new PrefixSumComputer(values);
this._bustCache();
}
PrefixSumComputerWithCache.prototype._bustCache = function () {
this._cacheAccumulatedValueStart = 0;
this._cache = null;
};
PrefixSumComputerWithCache.prototype.insertValues = function (insertIndex, insertValues) {
if (this._actual.insertValues(insertIndex, insertValues)) {
this._bustCache();
}
};
PrefixSumComputerWithCache.prototype.changeValue = function (index, value) {
if (this._actual.changeValue(index, value)) {
this._bustCache();
}
};
PrefixSumComputerWithCache.prototype.removeValues = function (startIndex, cnt) {
if (this._actual.removeValues(startIndex, cnt)) {
this._bustCache();
}
};
PrefixSumComputerWithCache.prototype.getTotalValue = function () {
return this._actual.getTotalValue();
};
PrefixSumComputerWithCache.prototype.getAccumulatedValue = function (index) {
return this._actual.getAccumulatedValue(index);
};
PrefixSumComputerWithCache.prototype.getIndexOf = function (accumulatedValue) {
accumulatedValue = Math.floor(accumulatedValue); //@perf
if (this._cache !== null) {
var cacheIndex = accumulatedValue - this._cacheAccumulatedValueStart;
if (cacheIndex >= 0 && cacheIndex < this._cache.length) {
// Cache hit!
return this._cache[cacheIndex];
}
}
// Cache miss!
return this._actual.getIndexOf(accumulatedValue);
};
/**
* Gives a hint that a lot of requests are about to come in for these accumulated values.
*/
PrefixSumComputerWithCache.prototype.warmUpCache = function (accumulatedValueStart, accumulatedValueEnd) {
var newCache = [];
for (var accumulatedValue = accumulatedValueStart; accumulatedValue <= accumulatedValueEnd; accumulatedValue++) {
newCache[accumulatedValue - accumulatedValueStart] = this.getIndexOf(accumulatedValue);
}
this._cache = newCache;
this._cacheAccumulatedValueStart = accumulatedValueStart;
};
return PrefixSumComputerWithCache;
}());
export { PrefixSumComputerWithCache };