Skip to content

FileManager: Implement contentsEqual(atPath:andPath:) #1510

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

Merged
merged 4 commits into from
Apr 18, 2018

Conversation

spevans
Copy link
Contributor

@spevans spevans commented Apr 8, 2018

  • Requires some more tests, especially for comparing directories.

@spevans
Copy link
Contributor Author

spevans commented Apr 8, 2018

@swift-ci please test

@parkera parkera requested a review from kperryua April 9, 2018 20:57
Copy link
Contributor

@kperryua kperryua left a comment

Choose a reason for hiding this comment

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

Overall looks reasonable, but a few comments and one necessary correctness change.

return false
}
}
return path1entries.isEmpty
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd expect this to recurse for each item in the two directories. If the contents of 'A/C' doesn't match 'B/C', then this is supposed to fail.

}

private func _compareSymlinks(withFileSystemRepresentation file1Rep: UnsafePointer<Int8>, andFileSystemRepresentation file2Rep: UnsafePointer<Int8>, size: Int64) -> Bool {
let bufSize = Int(size) + 1
Copy link
Contributor

Choose a reason for hiding this comment

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

On Darwin at least, readlink does not append a NUL byte, so the +1 isn't strictly necessary.

return false
}

if file1Type == S_IFCHR {
Copy link
Contributor

Choose a reason for hiding this comment

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

The same could be done here for S_IFBLK, no?

XCTAssertFalse(fm.contentsEqual(atPath: symlink, andPath: testFile1URL.path))
XCTAssertTrue(fm.contentsEqual(atPath: testDir1.path, andPath: testDir1.path))
XCTAssertTrue(fm.contentsEqual(atPath: testDir2.path, andPath: testDir3.path))
XCTAssertFalse(fm.contentsEqual(atPath: testDir1.path, andPath: testDir2.path))
Copy link
Contributor

Choose a reason for hiding this comment

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

A test case that verifies recursive (in)equality is needed.



private func _compareFiles(withFileSystemRepresentation file1Rep: UnsafePointer<Int8>, andFileSystemRepresentation file2Rep: UnsafePointer<Int8>, size: Int64) -> Bool {
let bufSize = min(size, 1024 * 1024)
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be worth using st_blksize to pick an optimal block size. 1 MB (*2) seems like a rather large allocation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Im not sure how to relate it to block size, given there are only a few fixed block sizes. How does Darwin's Foundation decide on the buffer size to use?

Copy link
Contributor

Choose a reason for hiding this comment

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

st_blksize is documented as "The optimal I/O block size for the file". I've taken that to mean that, especially if we're not reading the entire contents of the file into a single buffer (a la NSData), that this value is the system-declared preferred buffer size for I/O operations. I won't link directly to any here, but various implementations of 'cat' agree (including Darwin's).

Darwin's implementation of this method is fairly old and happens not to use this value—opting for a constant 8K size instead—though it should probably should.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah right, I mis-read this as using some multiple of st_blksize rather than the value directly.

- For block devices, compare the major/minor to match character
  devices.

- When comparing directory contents, compare the contents of each
  item in the directories.
@spevans
Copy link
Contributor Author

spevans commented Apr 10, 2018

@swift-ci please test

@spevans
Copy link
Contributor Author

spevans commented Apr 10, 2018

@swift-ci please test

Copy link
Contributor

@kperryua kperryua left a comment

Choose a reason for hiding this comment

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

The tests are still lacking, especially in the area of recursive content (in)equality. The implementation looks fine to me now, but it'd be great to get those tests in before committing.

@alblue
Copy link
Contributor

alblue commented Apr 12, 2018

@swift-ci please test

@spevans
Copy link
Contributor Author

spevans commented Apr 14, 2018

I added some extra tests for deep subdirectories to check the recursion. It exposed a bug in copyItem(atPath:toPath:) (#1515) which will need to be merged before this and also I came across a bug in fileExists(atPath:isDirectory) (#1514) which should also go in .

@parkera
Copy link
Contributor

parkera commented Apr 14, 2018

Great, thanks @spevans!

@spevans
Copy link
Contributor Author

spevans commented Apr 15, 2018

@swift-ci please test

1 similar comment
@millenomi
Copy link
Contributor

@swift-ci please test

@spevans
Copy link
Contributor Author

spevans commented Apr 18, 2018

@swift-ci please test and merge

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.

6 participants