mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
fix maximum call stack size reached issue (#14878)
* fix maximum call stack size reached issue * Revert "fix maximum call stack size reached issue" This reverts commit 178675633032a508ddb5585d1adc4f83bb243f55. * add a few array operations * use new push
This commit is contained in:
@@ -34,6 +34,7 @@ import { IDataTreeViewState } from 'vs/base/browser/ui/tree/dataTree';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IQueryEditorConfiguration } from 'sql/platform/query/common/query';
|
||||
import { push } from 'vs/base/common/arrays';
|
||||
|
||||
export interface IResultMessageIntern {
|
||||
id?: string;
|
||||
@@ -201,7 +202,7 @@ export class MessagePanel extends Disposable {
|
||||
|
||||
private onMessage(message: IQueryMessage | IQueryMessage[], setInput: boolean = false) {
|
||||
if (isArray(message)) {
|
||||
this.model.messages.push(...message);
|
||||
push(this.model.messages, message);
|
||||
} else {
|
||||
this.model.messages.push(message);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ICollapseStateChangeEvent, ITreeElement, ITreeFilter, ITreeFilterDataResult, ITreeModel, ITreeNode, TreeVisibility, ITreeModelSpliceEvent, TreeError } from 'vs/base/browser/ui/tree/tree';
|
||||
import { tail2 } from 'vs/base/common/arrays';
|
||||
import { splice, tail2 } from 'vs/base/common/arrays';
|
||||
import { Emitter, Event, EventBufferer } from 'vs/base/common/event';
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { ISpliceable } from 'vs/base/common/sequence';
|
||||
@@ -149,7 +149,7 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
|
||||
}
|
||||
}
|
||||
|
||||
const deletedNodes = parentNode.children.splice(lastIndex, deleteCount, ...nodesToInsert);
|
||||
const deletedNodes = splice(parentNode.children, lastIndex, deleteCount, nodesToInsert);
|
||||
|
||||
// figure out what is the count of deleted visible children
|
||||
let deletedVisibleChildrenCount = 0;
|
||||
|
||||
@@ -612,3 +612,78 @@ export function mapFind<T, R>(array: Iterable<T>, mapFn: (value: T) => R | undef
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* An alternative for Array.push(...items) method, Use this if you need to push large number of items to the array.
|
||||
* Array.push(...item) can only support limited number of items due to the maximum call stack size limit.
|
||||
* @param array The array to add items to.
|
||||
* @param items The new items to be added.
|
||||
*/
|
||||
export function push<T>(array: T[], items: T[]): void {
|
||||
// set array length and then assign value at index is faster than doing array.push(item) individually
|
||||
const newLength = array.length + items.length;
|
||||
const startIdx = array.length;
|
||||
array.length = newLength;
|
||||
items.forEach((item, index) => {
|
||||
array[startIdx + index] = item;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the new items to array, the insertion be performed on the original array directly, the alternative insertArray() method will return a new array.
|
||||
* @param array The original array.
|
||||
* @param start The zero-based location in the array from which to start inserting elements.
|
||||
* @param newItems The items to be inserted
|
||||
*/
|
||||
export function insertArray2<T>(array: T[], start: number, newItems: T[]): void {
|
||||
const startIdx = getActualStartIndex(array, start);
|
||||
const originalLength = array.length;
|
||||
const newItemsLength = newItems.length;
|
||||
array.length = originalLength + newItemsLength;
|
||||
// Move the items after the start index, start from the end so that we don't overwrite any value.
|
||||
for (let i = originalLength - 1; i >= startIdx; i--) {
|
||||
array[i + newItemsLength] = array[i];
|
||||
}
|
||||
|
||||
for (let i = 0; i < newItemsLength; i++) {
|
||||
array[i + startIdx] = newItems[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes elements from an array and inserts new elements in their place, returning the deleted elements. Alternative to the native Array.splice method, it
|
||||
* can only support limited number of items due to the maximum call stack size limit.
|
||||
* @param array The original array.
|
||||
* @param start The zero-based location in the array from which to start removing elements.
|
||||
* @param deleteCount The number of elements to remove.
|
||||
* @returns An array containing the elements that were deleted.
|
||||
*/
|
||||
export function splice<T>(array: T[], start: number, deleteCount: number, newItems: T[]): T[] {
|
||||
const startIdx = getActualStartIndex(array, start);
|
||||
const deletedItems = array.splice(startIdx, deleteCount);
|
||||
insertArray2(array, startIdx, newItems);
|
||||
return deletedItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the actual start index (same logic as the native splice() or slice())
|
||||
* If greater than the length of the array, start will be set to the length of the array. In this case, no element will be deleted but the method will behave as an adding function, adding as many element as item[n*] provided.
|
||||
* If negative, it will begin that many elements from the end of the array. (In this case, the origin -1, meaning -n is the index of the nth last element, and is therefore equivalent to the index of array.length - n.) If array.length + start is less than 0, it will begin from index 0.
|
||||
* @param array The target array.
|
||||
* @param start The operation index.
|
||||
*/
|
||||
function getActualStartIndex<T>(array: T[], start: number): number {
|
||||
let startIndex: number;
|
||||
if (start > array.length) {
|
||||
startIndex = array.length;
|
||||
} else if (start < 0) {
|
||||
if ((start + array.length) < 0) {
|
||||
startIndex = 0;
|
||||
} else {
|
||||
startIndex = start + array.length;
|
||||
}
|
||||
} else {
|
||||
startIndex = start;
|
||||
}
|
||||
return startIndex;
|
||||
}
|
||||
|
||||
@@ -369,4 +369,46 @@ suite('Arrays', () => {
|
||||
remove();
|
||||
assert.equal(array.length, 0);
|
||||
});
|
||||
|
||||
test('splice', function () {
|
||||
// negative start index, absolute value greater than the length
|
||||
let array = [1, 2, 3, 4, 5];
|
||||
arrays.splice(array, -6, 3, [6, 7]);
|
||||
assert.strictEqual(array.length, 4);
|
||||
assert.strictEqual(array[0], 6);
|
||||
assert.strictEqual(array[1], 7);
|
||||
assert.strictEqual(array[2], 4);
|
||||
assert.strictEqual(array[3], 5);
|
||||
|
||||
// negative start index, absolute value less than the length
|
||||
array = [1, 2, 3, 4, 5];
|
||||
arrays.splice(array, -3, 3, [6, 7]);
|
||||
assert.strictEqual(array.length, 4);
|
||||
assert.strictEqual(array[0], 1);
|
||||
assert.strictEqual(array[1], 2);
|
||||
assert.strictEqual(array[2], 6);
|
||||
assert.strictEqual(array[3], 7);
|
||||
|
||||
// Start index less than the length
|
||||
array = [1, 2, 3, 4, 5];
|
||||
arrays.splice(array, 3, 3, [6, 7]);
|
||||
assert.strictEqual(array.length, 5);
|
||||
assert.strictEqual(array[0], 1);
|
||||
assert.strictEqual(array[1], 2);
|
||||
assert.strictEqual(array[2], 3);
|
||||
assert.strictEqual(array[3], 6);
|
||||
assert.strictEqual(array[4], 7);
|
||||
|
||||
// Start index greater than the length
|
||||
array = [1, 2, 3, 4, 5];
|
||||
arrays.splice(array, 6, 3, [6, 7]);
|
||||
assert.strictEqual(array.length, 7);
|
||||
assert.strictEqual(array[0], 1);
|
||||
assert.strictEqual(array[1], 2);
|
||||
assert.strictEqual(array[2], 3);
|
||||
assert.strictEqual(array[3], 4);
|
||||
assert.strictEqual(array[4], 5);
|
||||
assert.strictEqual(array[5], 6);
|
||||
assert.strictEqual(array[6], 7);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user