diskFileSystemProvider.ts ×15

Frontier kind: Code frontier

unlabeled · c_bfb413e344f6

29 tests · 13530 LOC · 64 files · introduces 0 tests · 104 LOC · 3 files

Introduces — evidence that enters the hierarchy at this concept

Code
23 ranges104 lines · 3 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
2029 ranges13530 lines · 64 files · Browse complete extent
All tests (intent)
29 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

3 files ranked by introduced lines: 104 introduced LOC across 23 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/files/common/diskFileSystemProvider.ts 52 introduced LOC · 7 ranges

Open complete file

44
45 constructor(
46 > protected readonly logService: ILogService, diskFileSystemProvider.ts
47 > private readonly options?: IDiskFileSystemProviderOptions
48 > ) {
49 > super();
50 > }
51 >
52 > protected readonly _onDidChangeFile = this._register(new Emitter<readonly IFileChange[]>());
53 > readonly onDidChangeFile = this._onDidChangeFile.event;
54 >
55 > protected readonly _onDidWatchError = this._register(new Emitter<string>());
56 > readonly onDidWatchError = this._onDidWatchError.event;
57 >
58 > watch(resource: URI, opts: IWatchOptions): IDisposable {
59 if (opts.recursive || this.options?.watcher?.forceUniversal) {
60 return this.watchUniversal(resource, opts);
63 return this.watchNonRecursive(resource, opts);
64 }
66 > private getRefreshWatchersDelay(count: number): number {
67 > if (count > 200) {
68 // If there are many requests to refresh, start to throttle
69 // the refresh to reduce pressure. We see potentially thousands
71 return 500;
72 }
74 > // By default, use a short delay to keep watchers updating fast but still
75 > // with a delay so that we can efficiently deduplicate requests or reuse
76 > // existing watchers.
77 > return 0;
78 > }
79 >
80 > //#region File Watching (universal)
81 >
82 > private universalWatcher: AbstractUniversalWatcherClient | undefined;
83 >
84 > private readonly universalWatchRequests: IUniversalWatchRequest[] = [];
85 > private readonly universalWatchRequestDelayer = this._register(new ThrottledDelayer<void>(this.getRefreshWatchersDelay(this.universalWatchRequests.length)));
86 >
87 > private watchUniversal(resource: URI, opts: IWatchOptions): IDisposable {
88 const request = this.toWatchRequest(resource, opts);
89 const remove = insert(this.universalWatchRequests, request);
101 });
102 }
104 > private toWatchRequest(resource: URI, opts: IWatchOptions): IUniversalWatchRequest {
105 const request: IUniversalWatchRequest = {
106 path: this.toWatchPath(resource),
127 return request;
128 }
130 > private refreshUniversalWatchers(): void {
131 this.universalWatchRequestDelayer.trigger(() => {
132 return this.doRefreshUniversalWatchers();
133 }, this.getRefreshWatchersDelay(this.universalWatchRequests.length)).catch(error => onUnexpectedError(error));
134 }
136 > private doRefreshUniversalWatchers(): Promise<void> {
137
138 // Create watcher if this is the first time
153 return this.universalWatcher.watch(this.universalWatchRequests);
154 }
156 > protected abstract createUniversalWatcher(
157 > onChange: (changes: IFileChange[]) => void,
158 > onLogMessage: (msg: ILogMessage) => void,
159 > verboseLogging: boolean
160 > ): AbstractUniversalWatcherClient;
161 >
162 > //#endregion
163 >
164 > //#region File Watching (non-recursive)
165 >
166 > private nonRecursiveWatcher: AbstractNonRecursiveWatcherClient | undefined;
167 >
168 > private readonly nonRecursiveWatchRequests: INonRecursiveWatchRequest[] = [];
169 > private readonly nonRecursiveWatchRequestDelayer = this._register(new ThrottledDelayer<void>(this.getRefreshWatchersDelay(this.nonRecursiveWatchRequests.length)));
170
171 private watchNonRecursive(resource: URI, opts: IWatchOptions): IDisposable {
src/vs/platform/files/node/diskFileSystemProvider.ts 50 introduced LOC · 15 ranges

Open complete file

36 IFileSystemProviderWithFileCloneCapability,
37 IFileSystemProviderWithFileRealpathCapability {
39 > private static TRACE_LOG_RESOURCE_LOCKS = false; // not enabled by default because very spammy
40 >
41 > //#region File Capabilities
42 >
43 > readonly onDidChangeCapabilities = Event.None;
44 >
45 > private _capabilities: FileSystemProviderCapabilities | undefined;
46 > get capabilities(): FileSystemProviderCapabilities {
47 if (!this._capabilities) {
48 this._capabilities =
66 return this._capabilities;
67 }
69 > //#endregion
70 >
71 > //#region File Metadata Resolving
72 >
73 > async stat(resource: URI): Promise<IStat> {
74 try {
75 const { stat, symbolicLink } = await SymlinkSupport.stat(this.toFilePath(resource)); // cannot use fs.stat() here to support links properly
98 }
99 }
101 > private async statIgnoreError(resource: URI): Promise<IStat | undefined> {
102 try {
103 return await this.stat(resource);
106 }
107 }
109 > async realpath(resource: URI): Promise<string> {
110 const filePath = this.toFilePath(resource);
111
112 return Promises.realpath(filePath);
113 }
115 > async readdir(resource: URI): Promise<[string, FileType][]> {
116 try {
117 const children = await Promises.readdir(this.toFilePath(resource), { withFileTypes: true });
138 }
139 }
141 > private toType(entry: Stats | IDirent, symbolicLink?: { dangling: boolean }): FileType {
142
143 // Signal file type by checking for file / directory, except:
162 return type;
163 }
165 > //#endregion
166 >
167 > //#region File Reading/Writing
168 >
169 > private readonly resourceLocks = new ResourceMap<Barrier>(resource => extUriBiasedIgnorePathCase.getComparisonKey(resource));
170 >
171 > private async createResourceLock(resource: URI): Promise<IDisposable> {
172 const filePath = this.toFilePath(resource);
173 this.traceLock(`[Disk FileSystemProvider]: createResourceLock() - request to acquire resource lock (${filePath})`);
202 });
203 }
205 > async readFile(resource: URI, options?: IFileAtomicReadOptions): Promise<Uint8Array> {
206 let lock: IDisposable | undefined = undefined;
207 try {
224 }
225 }
227 > private traceLock(msg: string): void {
228 if (DiskFileSystemProvider.TRACE_LOG_RESOURCE_LOCKS) {
229 this.logService.trace(msg);
230 }
231 }
233 > readFileStream(resource: URI, opts: IFileReadStreamOptions, token: CancellationToken): ReadableStreamEvents<Uint8Array> {
234 const stream = newWriteableStream<Uint8Array>(data => VSBuffer.concat(data.map(data => VSBuffer.wrap(data))).buffer);
235
241 return stream;
242 }
244 > async writeFile(resource: URI, content: Uint8Array, opts: IFileWriteOptions): Promise<void> {
245 if (opts?.atomic !== false && opts?.atomic?.postfix && await this.canWriteFileAtomic(resource)) {
246 return this.doWriteFileAtomic(resource, joinPath(resourcesDirname(resource), `${resourcesBasename(resource)}${opts.atomic.postfix}`), content, opts);
249 }
250 }
252 > private async canWriteFileAtomic(resource: URI): Promise<boolean> {
253 try {
254 const filePath = this.toFilePath(resource);
268 return true; // atomic writing supported
269 }
271 > private async doWriteFileAtomic(resource: URI, tempResource: URI, content: Uint8Array, opts: IFileWriteOptions): Promise<void> {
272
273 // Ensure to create locks for all resources involved
304 }
305 }
307 > private async doWriteFile(resource: URI, content: Uint8Array, opts: IFileWriteOptions, disableWriteLock?: boolean): Promise<void> {
308 let handle: number | undefined = undefined;
309 try {
337 }
338 }
340 > private readonly mapHandleToPos = new Map<number, number>();
341 > private readonly mapHandleToLock = new Map<number, IDisposable>();
342 >
343 > private readonly writeHandles = new Map<number, URI>();
344
345 private static canFlush = true;
src/vs/platform/files/common/fileService.ts 2 introduced LOC · 1 range

Open complete file

76 }));
77 if (typeof provider.onDidWatchError === 'function') {
78 > providerDisposables.add(provider.onDidWatchError(error => this._onDidWatchError.fire(new Error(error)))); fileService.ts
79 > }
80 providerDisposables.add(provider.onDidChangeCapabilities(() => this._onDidChangeFileSystemProviderCapabilities.fire({ provider, scheme })));
81