Skip to content

Implement _removeItem in terms of DirectoryEnumerator #2002

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

gmittert
Copy link
Contributor

Alternate implementation to #1976 that uses DirectoryEnumerator

@millenomi
Copy link
Contributor

@swift-ci please test

fts_close(stream)
if (URL(fileURLWithPath: itemPath).hasDirectoryPath) {
#if os(Windows)
let result = _NS_rmdir(itemPath)
Copy link
Contributor

@millenomi millenomi Mar 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to just fileprivate let _NS_rmdir = rmdir on non-Windows?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And similarly for _NS_unlink.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or fileprivate let rmdir = _NS_rundir on Windows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure!

@gmittert gmittert force-pushed the TreeRemovalByIterator branch from 9c8bfdc to 99ec935 Compare March 14, 2019 19:44
return _NS_unlink(path) != 0
#else
return unlink(path) != 0
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can also be unlink(path) now right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eeeyup

@gmittert gmittert force-pushed the TreeRemovalByIterator branch from 99ec935 to 591661f Compare March 14, 2019 19:55
@spevans
Copy link
Contributor

spevans commented Mar 14, 2019

Wont this spend a lot of effort to convert every file entry from file system representation into a URL then convert it back again to remove it? Im not sure of the benefit of this change.

@gmittert
Copy link
Contributor Author

Wont this spend a lot of effort to convert every file entry from file system representation into a URL then convert it back again to remove it? Im not sure of the benefit of this change.

It does add extra URL calls, however, it's one less use of fts and means the same codepath works across Windows/Darwin/Linux. How expensive is converting to a URL? I'm still okay with #1976 if adding an extra conversion is too expensive to be worth it.

@compnerd
Copy link
Member

Could also do the .standardizingPath to avoid the URL conversions.

@millenomi
Copy link
Contributor

@swift-ci please test

@gmittert
Copy link
Contributor Author

Could also do the .standardizingPath to avoid the URL conversions.

I can remove all the URL conversions in _removeItem, but the issue is still that NSURLDirectoryEnumerator gives back URLs rather than Strings so it will still be doing the conversion there and back.

@compnerd
Copy link
Member

Yes, but that is a feature since the paths need to be converted to FSRs prior to the unlink.

@millenomi
Copy link
Contributor

@swift-ci please test

@gmittert gmittert force-pushed the TreeRemovalByIterator branch from 591661f to 5114418 Compare March 15, 2019 21:31
@gmittert
Copy link
Contributor Author

Okay, I've removed the unneeded URL conversions in _removeItem, the only one remaining is the needed one to create the Enumerator.

@compnerd
Copy link
Member

@swift-ci please test

1 similar comment
@compnerd
Copy link
Member

@swift-ci please test

@gmittert
Copy link
Contributor Author

It fails when creating a symlink for swiftpm... I don't think it's related?

12:45:08 [37/38] Compiling Swift Module 'SwiftPMPackageTests' (1 sources)
12:45:08 error: symlink error: File exists (17): /home/buildnode/jenkins/workspace/swift-corelibs-foundation-PR-Linux/buildbot_linux/swiftpm-linux-x86_64/release -> x86_64-unknown-linux/release
12:45:08 --- bootstrap: error: build failed with exit status 1
12:45:08 Building the standard library for: swift-stdlib-linux-x86_64
12:45:08 Running Swift tests for: check-swift-all-linux-x86_64 check-swift-all-optimize-linux-x86_64
12:45:08 /home/buildnode/jenkins/workspace/swift-corelibs-foundation-PR-Linux/swift/utils/build-script: fatal error: command terminated with a non-zero exit status 1, aborting

@compnerd
Copy link
Member

@swift-ci please test

1 similar comment
@compnerd
Copy link
Member

@swift-ci please test

@gmittert
Copy link
Contributor Author

gmittert commented Mar 27, 2019

@swift-ci please test

Ah hold up a bit, this is actually broken on Linux, I've repro'd it locally. Just having issues setting up a Linux environment where I can test it properly.

@spevans
Copy link
Contributor

spevans commented Mar 27, 2019

You are calling the unlink and rmdir without using the FSR of the file name.
Also every _fileExists call does at least one lstat call and possibly a second stat call making this quite system call heavy.

Another point regarding the FSR, is that the fts_read already returns the filename in FSR which can be passed straight to unlink and rmdir instead of converting the name to a String and then back again.

I think this approach in general is wrong, for an internal helper like this it should just use the best per-OS solution to delete a file or directory structure.

@gmittert
Copy link
Contributor Author

gmittert commented Mar 27, 2019

I think this approach in general is wrong, for an internal helper like this it should just use the best per-OS solution to delete a file or directory structure.

I actually agree, and I think I'd rather do #1976 instead. @compnerd if we really care about a single codepath, one other alternative would be to have an fts shim and implement that on Windows and call through to the real thing on everything else, but that might be more effort than it's worth.

@compnerd
Copy link
Member

I don't think that we want to re-implement FTS on top of the Windows APIs. Would it not be possible to actually have an internal method to avoid the overheads of the FTS translation and the stating? If not, then I suppose that we can split the file into two and have a FileManager+POSIX.swift and FileManager+Win32.swift and start duplicating the interfaces.

@gmittert
Copy link
Contributor Author

Closing in favour of #2117

@gmittert gmittert closed this Apr 15, 2019
@gmittert gmittert deleted the TreeRemovalByIterator branch April 15, 2019 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants