Skip to content
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

Deduplicate disk abstraction infrastructure #1060

Merged
merged 4 commits into from Feb 3, 2016

Conversation

bradking
Copy link
Contributor

@bradking bradking commented Dec 1, 2015

Currently we have two disk abstractions: DiskInterface and ManifestParser::FileReader.

Revise DiskInterface to support both use cases and then drop FileReader. This also simplifies test infrastructure by avoiding custom FileReader implementations.

@tfarina
Copy link
Contributor

tfarina commented Dec 1, 2015

Nice! Thanks for doing this! I always felt there was something that could be done, since the two were very similar!

@jcfr
Copy link

jcfr commented Dec 11, 2015

👍

Fix some ManifestParser constructor calls missed by commit 56bab44
(dupe_edge_should_err from bool to enum, 2016-01-27).
@bradking
Copy link
Contributor Author

bradking commented Feb 2, 2016

Rebased on master to resolve conflicts.

@nico
Copy link
Collaborator

nico commented Feb 2, 2016

Thank you for the patch. All that deleted code is nice to see, and the bonus build fix is much appreciated too :-) I think this makes the codebase better than it was before. I'll explain briefly why I didn't just hit "merge" long ago (sorry for the delay). If after reading this you think this patch as-is is the way to go, then I'll merge it as-is (as I do think it's better than what's there today).

  • This allows ManifestParser to allow all of DiskInterface, even though ManifestParser doesn't have to stat files, write files, remove files, or make directories. In larger projects, having more, smaller interfaces tends to reduce unnecessary dependencies between targets in my experience. (But ninja is small enough that this doesn't matter, and e.g. introducing a FileReader interface and making DiskInterface a subclass of that seems like overkill, so this is fine as-is I think.)
  • It adds errno to the interface of DiskInterface, while this was abstracted out previously. Almost nothing uses this errno return. (And it's not really errno on Windows, except for "file not found".) True, ::ReadFile() also exposes this, but I understood the functions in util.cc to be thin convenience wrappers around OS-specific functions while DiskInterface tries to be a real abstraction. Maybe ReadFile() could return an enum FileStatus { Ok, FileNotFound, OtherError }?
  • It gives DiskInterface two ReadFile() methods, one of them more or less named DoAAndB(). At my current employer, we have this story about a File class that grew larger and larger over the decades due to people adding "XOrDie()", "XOrDieExceptIfFoo()" variants for several of its methods. The lesson from that was that it's preferable for clients of a class to have some control flow -- if a client wants "XOrDie()" they can write "if (!foo->X()) Die()" themselves. Since ReadFileIfExistsElseEmpty() (empty what?) only has two callers, maybe the two callers could check for "file not found" and clear out err themselves explicitly? (it is currently not obvious that the callers are fine with "file not found", so that might be a good change anyhow)

I hope that makes sense :-) As I said, if you prefer to not make any changes, that's fine too.

Some clients will need only the ability to read files, so provide this
as a more narrow interface than the full disk interface.
Return a status so callers can distinguish a missing file from an empty
file.  This allows our VirtualFileSystem test infrastructure to report
as missing any file for which it has no entry.
Avoid having two separate filesystem interfaces.  Simplify test
infrastructure by avoiding custom `ManifestParser::FileReader`
implementations.
@bradking
Copy link
Contributor Author

bradking commented Feb 3, 2016

@nico, all good comments, thanks. I've rewritten the topic to address them.

This allows ManifestParser to allow all of DiskInterface

I split out a FileReader base class interface from DiskInterface to give to ManifestParser instead. This will restrict what it can use from a DiskInterface implementation.

It adds errno to the interface of DiskInterface

I changed the interface to return an enumeration as suggested.

It gives DiskInterface two ReadFile() methods, one of them...ReadFileIfExistsElseEmpty

I removed the latter in favor of updating the call sites. I had intended it to avoid duplication but there are only two places and a switch on the enumeration value makes the logic more transparent than trying to encode it in a long method name.

nico added a commit that referenced this pull request Feb 3, 2016
Deduplicate disk abstraction infrastructure
@nico nico merged commit 27c87c5 into ninja-build:master Feb 3, 2016
@nico
Copy link
Collaborator

nico commented Feb 3, 2016

Thanks!

@bradking bradking deleted the deduplicate-disk-interface branch February 3, 2016 21:19
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.

None yet

4 participants