OpenEnroth 4aaa0a0
|
#include <MergingFileSystem.h>
Public Member Functions | |
MergingFileSystem (std::vector< const FileSystem * > bases) | |
virtual | ~MergingFileSystem () |
![]() | |
FileSystem ()=default | |
virtual | ~FileSystem ()=default |
bool | exists (std::string_view path) const |
bool | exists (FileSystemPathView path) const |
FileStat | stat (std::string_view path) const |
FileStat | stat (FileSystemPathView path) const |
std::vector< DirectoryEntry > | ls (std::string_view path) const |
std::vector< DirectoryEntry > | ls (FileSystemPathView path) const |
void | ls (std::string_view path, std::vector< DirectoryEntry > *entries) const |
void | ls (FileSystemPathView path, std::vector< DirectoryEntry > *entries) const |
Blob | read (std::string_view path) const |
Blob | read (FileSystemPathView path) const |
void | write (std::string_view path, const Blob &data) |
void | write (FileSystemPathView path, const Blob &data) |
std::unique_ptr< InputStream > | openForReading (std::string_view path) const |
std::unique_ptr< InputStream > | openForReading (FileSystemPathView path) const |
std::unique_ptr< OutputStream > | openForWriting (std::string_view path) |
std::unique_ptr< OutputStream > | openForWriting (FileSystemPathView path) |
void | rename (std::string_view srcPath, std::string_view dstPath) |
void | rename (FileSystemPathView srcPath, FileSystemPathView dstPath) |
bool | remove (std::string_view path) |
bool | remove (FileSystemPathView path) |
std::string | displayPath (std::string_view path) const |
std::string | displayPath (FileSystemPathView path) const |
Private Member Functions | |
virtual bool | _exists (FileSystemPathView path) const override |
virtual FileStat | _stat (FileSystemPathView path) const override |
virtual void | _ls (FileSystemPathView path, std::vector< DirectoryEntry > *entries) const override |
virtual Blob | _read (FileSystemPathView path) const override |
virtual std::unique_ptr< InputStream > | _openForReading (FileSystemPathView path) const override |
virtual std::string | _displayPath (FileSystemPathView path) const override |
const FileSystem * | locateForReading (FileSystemPathView path) const |
const FileSystem * | locateForReadingOrNull (FileSystemPathView path) const |
Private Attributes | |
std::vector< const FileSystem * > | _bases |
Additional Inherited Members | |
![]() | |
template<class T > | |
using | FileSystemTrieNode = detail::FileSystemTrieNode< T > |
template<class T > | |
using | FileSystemTrie = detail::FileSystemTrie< T > |
virtual bool | _exists (FileSystemPathView path) const =0 |
virtual FileStat | _stat (FileSystemPathView path) const =0 |
virtual void | _ls (FileSystemPathView path, std::vector< DirectoryEntry > *entries) const =0 |
virtual Blob | _read (FileSystemPathView path) const =0 |
virtual void | _write (FileSystemPathView path, const Blob &data)=0 |
virtual std::unique_ptr< InputStream > | _openForReading (FileSystemPathView path) const =0 |
virtual std::unique_ptr< OutputStream > | _openForWriting (FileSystemPathView path)=0 |
virtual void | _rename (FileSystemPathView srcPath, FileSystemPathView dstPath) |
virtual bool | _remove (FileSystemPathView path)=0 |
virtual std::string | _displayPath (FileSystemPathView path) const =0 |
Merges several filesystems into a single read-only view:
stat()
returns information for a file, so that it's possible to know its size. ls()
will return both entries, in unspecified order.Some notes on why go Schrodingermaxxxing. When there is a conflict between underlying filesystems, and we have a file and a folder with the same names, we have several different options:
When picking between the options, we must remember that: a. A tree of MergingFileSystem
s should behave the same way as a single flattened MergingFileSystem
. E.g. if we have a MergingFileSystem
containing another MergingFileSystem
, it should be no different from just having a single MergingFileSystem
with all the leaf filesystems added to it. b. Ideally, each method of the merging filesystem should call into each of the base filesystems at most once. c. The behavior shouldn't be surprising.
Point #1 above fails (b) and (c). We can fix (b) by introducing a walk()
method to FileSystem
that would return the longest existing prefix of a path, but then we're still left with the fact that behaviour is surprising.
Point #2 fails (c).
Point #3 fails (a), (b) and (c). How exactly it does it fail (a)? Imagine the following sequence of conflicts: folder x
, file x
, then again folder x
and file x
, with the first pair in the first MergingFileSystem
and the second pair in the second MergingFileSystem
, which are then merged into a single common MergingFileSystem
. The common MergingFileSystem
will merge the contents of the folders in this case, which (supposedly) would not be the case if all the conflicts were to happen inside a single MergingFileSystem
. This can be worked around, but the workaround is questionable.
Point #4 fails (b), can be fixed in the same way as point #1. So, a viable option.
Point #5 satisfies all the criteria, even though it's suffering a low-key bipolar disorder. So this is what we do.
|
explicit |
|
virtualdefault |
|
overrideprivatevirtual |
Implements FileSystem.
|
overrideprivatevirtual |
Implements FileSystem.
|
overrideprivatevirtual |
Implements FileSystem.
|
overrideprivatevirtual |
Implements FileSystem.
|
overrideprivatevirtual |
Implements FileSystem.
|
overrideprivatevirtual |
Implements FileSystem.
|
private |
|
private |
|
private |