Skip to content

Commit 8d63804

Browse files
authored
get long collections in chunks (microsoft#202758)
* stateless Datasource, improve initialization * retreive long collections in chunks
1 parent 9ed02ce commit 8d63804

File tree

3 files changed

+80
-39
lines changed

3 files changed

+80
-39
lines changed

src/vs/workbench/contrib/notebook/browser/contrib/notebookVariables/notebookVariables.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,30 @@ import { NOTEBOOK_KERNEL } from 'vs/workbench/contrib/notebook/common/notebookCo
1616
import { variablesViewIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons';
1717
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
1818
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
19+
import { INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
1920

2021

2122
export class NotebookVariables extends Disposable implements IWorkbenchContribution {
22-
private listener: IDisposable | undefined;
23+
private listeners: IDisposable[] = [];
2324

2425
constructor(
2526
@IEditorService private readonly editorService: IEditorService,
2627
@IConfigurationService configurationService: IConfigurationService,
28+
@INotebookExecutionStateService private readonly notebookExecutionStateService: INotebookExecutionStateService
2729
) {
2830
super();
2931

30-
this.listener = this.editorService.onDidEditorsChange(() => {
31-
if (configurationService.getValue('notebook.experimental.notebookVariablesView')
32-
&& this.editorService.activeEditorPane?.getId() === 'workbench.editor.notebook') {
33-
if (this.initializeView()) {
34-
this.listener?.dispose();
35-
}
32+
this.listeners.push(this.editorService.onDidEditorsChange(() => this.handleInitEvent(configurationService)));
33+
this.listeners.push(this.notebookExecutionStateService.onDidChangeExecution(() => this.handleInitEvent(configurationService)));
34+
}
35+
36+
private handleInitEvent(configurationService: IConfigurationService) {
37+
if (configurationService.getValue('notebook.experimental.notebookVariablesView')
38+
&& this.editorService.activeEditorPane?.getId() === 'workbench.editor.notebook') {
39+
if (this.initializeView()) {
40+
this.listeners.forEach(listener => listener.dispose());
3641
}
37-
});
42+
}
3843
}
3944

4045
private initializeView() {

src/vs/workbench/contrib/notebook/browser/contrib/notebookVariables/notebookVariablesDataSource.ts

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
import { IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
77
import { CancellationToken } from 'vs/base/common/cancellation';
88
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
9-
import { INotebookKernelService, VariablesResult } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
9+
import { INotebookKernel, INotebookKernelService, VariablesResult } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
1010

1111
export interface INotebookScope {
1212
type: 'root';
13-
readonly notebook: NotebookTextModel | undefined;
13+
readonly notebook: NotebookTextModel;
1414
}
1515

1616
export interface INotebookVariableElement {
@@ -19,13 +19,13 @@ export interface INotebookVariableElement {
1919
readonly name: string;
2020
readonly value: string;
2121
readonly indexedChildrenCount: number;
22+
readonly indexStart?: number;
2223
readonly hasNamedChildren: boolean;
24+
readonly notebook: NotebookTextModel;
2325
}
2426

2527
export class NotebookVariableDataSource implements IAsyncDataSource<INotebookScope, INotebookVariableElement> {
2628

27-
private notebook: NotebookTextModel | undefined = undefined;
28-
2929
constructor(private readonly notebookKernelService: INotebookKernelService) { }
3030

3131
hasChildren(element: INotebookScope | INotebookVariableElement): boolean {
@@ -34,33 +34,26 @@ export class NotebookVariableDataSource implements IAsyncDataSource<INotebookSco
3434

3535
async getChildren(element: INotebookScope | INotebookVariableElement): Promise<Array<INotebookVariableElement>> {
3636
if (element.type === 'root') {
37-
this.notebook = element.notebook;
38-
return this.getRootVariables();
37+
return this.getRootVariables(element.notebook);
3938
} else {
4039
return this.getVariables(element);
4140
}
4241
}
4342

4443
async getVariables(parent: INotebookVariableElement): Promise<INotebookVariableElement[]> {
45-
if (!this.notebook) {
46-
return [];
47-
}
48-
const selectedKernel = this.notebookKernelService.getMatchingKernel(this.notebook).selected;
44+
const selectedKernel = this.notebookKernelService.getMatchingKernel(parent.notebook).selected;
4945
if (selectedKernel && selectedKernel.hasVariableProvider) {
5046

5147
let children: INotebookVariableElement[] = [];
5248
if (parent.hasNamedChildren) {
53-
const variables = selectedKernel.provideVariables(this.notebook.uri, parent.id, 'named', 0, CancellationToken.None);
49+
const variables = selectedKernel.provideVariables(parent.notebook.uri, parent.id, 'named', 0, CancellationToken.None);
5450
const childNodes = await variables
55-
.map(variable => { return this.createVariableElement(variable); })
51+
.map(variable => { return this.createVariableElement(variable, parent.notebook); })
5652
.toPromise();
5753
children = children.concat(childNodes);
5854
}
5955
if (parent.indexedChildrenCount > 0) {
60-
const variables = selectedKernel.provideVariables(this.notebook.uri, parent.id, 'indexed', 0, CancellationToken.None);
61-
const childNodes = await variables
62-
.map(variable => { return this.createVariableElement(variable); })
63-
.toPromise();
56+
const childNodes = await this.getIndexedChildren(parent, selectedKernel);
6457
children = children.concat(childNodes);
6558
}
6659

@@ -69,25 +62,58 @@ export class NotebookVariableDataSource implements IAsyncDataSource<INotebookSco
6962
return [];
7063
}
7164

72-
async getRootVariables(): Promise<INotebookVariableElement[]> {
73-
if (!this.notebook) {
74-
return [];
65+
async getIndexedChildren(parent: INotebookVariableElement, kernel: INotebookKernel) {
66+
const childNodes: INotebookVariableElement[] = [];
67+
68+
if (parent.indexedChildrenCount > 100) {
69+
for (let start = 0; start < parent.indexedChildrenCount; start += 100) {
70+
let end = start + 100;
71+
if (end > parent.indexedChildrenCount) {
72+
end = parent.indexedChildrenCount;
73+
}
74+
75+
childNodes.push({
76+
type: 'variable',
77+
notebook: parent.notebook,
78+
id: parent.id,
79+
name: `[${start}..${end - 1}]`,
80+
value: '',
81+
indexedChildrenCount: end - start,
82+
indexStart: start,
83+
hasNamedChildren: false
84+
});
85+
}
86+
}
87+
else if (parent.indexedChildrenCount > 0) {
88+
const variables = kernel.provideVariables(parent.notebook.uri, parent.id, 'indexed', parent.indexStart ?? 0, CancellationToken.None);
89+
90+
for await (const variable of variables) {
91+
childNodes.push(this.createVariableElement(variable, parent.notebook));
92+
if (childNodes.length >= 100) {
93+
break;
94+
}
95+
}
96+
7597
}
98+
return childNodes;
99+
}
76100

77-
const selectedKernel = this.notebookKernelService.getMatchingKernel(this.notebook).selected;
101+
async getRootVariables(notebook: NotebookTextModel): Promise<INotebookVariableElement[]> {
102+
const selectedKernel = this.notebookKernelService.getMatchingKernel(notebook).selected;
78103
if (selectedKernel && selectedKernel.hasVariableProvider) {
79-
const variables = selectedKernel.provideVariables(this.notebook.uri, undefined, 'named', 0, CancellationToken.None);
104+
const variables = selectedKernel.provideVariables(notebook.uri, undefined, 'named', 0, CancellationToken.None);
80105
return await variables
81-
.map(variable => { return this.createVariableElement(variable); })
106+
.map(variable => { return this.createVariableElement(variable, notebook); })
82107
.toPromise();
83108
}
84109

85110
return [];
86111
}
87112

88-
private createVariableElement(variable: VariablesResult): INotebookVariableElement {
113+
private createVariableElement(variable: VariablesResult, notebook: NotebookTextModel): INotebookVariableElement {
89114
return {
90115
type: 'variable',
116+
notebook,
91117
...variable
92118
};
93119
}

src/vs/workbench/contrib/notebook/browser/contrib/notebookVariables/notebookVariablesView.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ export class NotebookVariablesView extends ViewPane {
5555
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService);
5656

5757
this._register(this.editorService.onDidActiveEditorChange(this.handleActiveEditorChange.bind(this)));
58-
this._register(this.notebookExecutionStateService.onDidChangeExecution(this.handleExecutionStateChange.bind(this)));
5958
this._register(this.notebookKernelService.onDidNotebookVariablesUpdate(this.handleVariablesChanged.bind(this)));
59+
this._register(this.notebookExecutionStateService.onDidChangeExecution(this.handleExecutionStateChange.bind(this)));
60+
61+
this.setActiveNotebook();
6062
}
6163

6264
protected override renderBody(container: HTMLElement): void {
@@ -75,23 +77,31 @@ export class NotebookVariablesView extends ViewPane {
7577
});
7678

7779
this.tree.layout();
78-
this.tree.setInput({ type: 'root', notebook: this.activeNotebook });
80+
if (this.activeNotebook) {
81+
this.tree.setInput({ type: 'root', notebook: this.activeNotebook });
82+
}
7983
}
8084

8185
protected override layoutBody(height: number, width: number): void {
8286
super.layoutBody(height, width);
8387
this.tree?.layout(height, width);
8488
}
8589

86-
private handleActiveEditorChange() {
90+
setActiveNotebook() {
91+
const current = this.activeNotebook;
8792
const activeEditorPane = this.editorService.activeEditorPane;
8893
if (activeEditorPane && activeEditorPane.getId() === 'workbench.editor.notebook') {
8994
const notebookDocument = getNotebookEditorFromEditorPane(activeEditorPane)?.getViewModel()?.notebookDocument;
90-
if (notebookDocument && notebookDocument !== this.activeNotebook) {
91-
this.activeNotebook = notebookDocument;
92-
this.tree?.setInput({ type: 'root', notebook: this.activeNotebook });
93-
this.tree?.updateChildren();
94-
}
95+
this.activeNotebook = notebookDocument;
96+
}
97+
98+
return current !== this.activeNotebook;
99+
}
100+
101+
private handleActiveEditorChange() {
102+
if (this.setActiveNotebook() && this.activeNotebook) {
103+
this.tree?.setInput({ type: 'root', notebook: this.activeNotebook });
104+
this.tree?.updateChildren();
95105
}
96106
}
97107

0 commit comments

Comments
 (0)