Skip to content

Commit e1d50b0

Browse files
author
Aiday Marlen Kyzy
authored
Merge pull request microsoft#159031 from microsoft/aiday/issue156874
Using binary search in getCandidateStickyLinesIntersectingFromOutline in order to improve performance
2 parents 1bdec7a + 479d1ce commit e1d50b0

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions';
1212
import { RunOnceScheduler } from 'vs/base/common/async';
1313
import { Range } from 'vs/editor/common/core/range';
1414
import { Emitter } from 'vs/base/common/event';
15+
import { binarySearch } from 'vs/base/common/arrays';
1516

1617
export class StickyRange {
1718
constructor(
@@ -96,9 +97,34 @@ export class StickyLineCandidateProvider extends Disposable {
9697
}
9798
}
9899

100+
private updateIndex(index: number) {
101+
if (index === -1) {
102+
index = 0;
103+
} else if (index < 0) {
104+
index = -index - 2;
105+
}
106+
return index;
107+
}
108+
99109
public getCandidateStickyLinesIntersectingFromOutline(range: StickyRange, outlineModel: StickyOutlineElement, result: StickyLineCandidate[], depth: number, lastStartLineNumber: number): void {
110+
if (outlineModel.children.length === 0) {
111+
return;
112+
}
100113
let lastLine = lastStartLineNumber;
101-
for (const child of outlineModel.children) {
114+
const childrenStartLines: number[] = [];
115+
for (let i = 0; i < outlineModel.children.length; i++) {
116+
const child = outlineModel.children[i];
117+
if (child.range) {
118+
childrenStartLines.push(child.range.startLineNumber);
119+
}
120+
}
121+
const lowerBound = this.updateIndex(binarySearch(childrenStartLines, range.startLineNumber, (a: number, b: number) => { return a - b; }));
122+
const upperBound = this.updateIndex(binarySearch(childrenStartLines, range.startLineNumber + depth, (a: number, b: number) => { return a - b; }));
123+
for (let i = lowerBound; i <= upperBound; i++) {
124+
const child = outlineModel.children[i];
125+
if (!child) {
126+
return;
127+
}
102128
if (child.range) {
103129
const childStartLine = child.range.startLineNumber;
104130
const childEndLine = child.range.endLineNumber;
@@ -133,9 +159,13 @@ export class StickyLineCandidateProvider extends Disposable {
133159

134160
class StickyOutlineElement {
135161
public static fromOutlineModel(outlineModel: OutlineModel | OutlineElement | OutlineGroup): StickyOutlineElement {
136-
const children = [...outlineModel.children.values()].map(child =>
137-
StickyOutlineElement.fromOutlineModel(child)
138-
);
162+
163+
const children: StickyOutlineElement[] = [];
164+
for (const child of outlineModel.children.values()) {
165+
if (child instanceof OutlineElement && child.symbol.selectionRange.startLineNumber !== child.symbol.range.endLineNumber || child instanceof OutlineGroup || child instanceof OutlineModel) {
166+
children.push(StickyOutlineElement.fromOutlineModel(child));
167+
}
168+
}
139169
children.sort((child1, child2) => {
140170
if (!child1.range || !child2.range) {
141171
return 1;

src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
160160
return linkGestureStore;
161161
}
162162

163-
164163
public get lineNumbers(): number[] {
165164
return this._lineNumbers;
166165
}

src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,10 @@ suite('Sticky Scroll Tests', () => {
105105
const languageService = instantiationService.get(ILanguageFeaturesService);
106106
languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel());
107107
const provider: StickyLineCandidateProvider = new StickyLineCandidateProvider(editor, languageService);
108-
109108
await provider.update();
110-
111109
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 1, endLineNumber: 4 }), [new StickyLineCandidate(1, 2, 1)]);
112-
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 1, endLineNumber: 10 }), [new StickyLineCandidate(1, 2, 1), new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]);
113-
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 1, endLineNumber: 13 }), [new StickyLineCandidate(1, 2, 1), new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3), new StickyLineCandidate(13, 13, 1)]);
110+
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 8, endLineNumber: 10 }), [new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]);
111+
assert.deepStrictEqual(provider.getCandidateStickyLinesIntersecting({ startLineNumber: 10, endLineNumber: 13 }), [new StickyLineCandidate(7, 11, 1), new StickyLineCandidate(9, 11, 2), new StickyLineCandidate(10, 10, 3)]);
114112

115113
provider.dispose();
116114
model.dispose();

0 commit comments

Comments
 (0)