Skip to content

Commit 11f7f8c

Browse files
committed
[cas] FileSystem::printImpl for CAS-related filesystems
For IncludeTreeFileSystem, contents (and recursive contents, since there is no distinction) prints the list of files in sorted order along with the casid of their contents. For CASFileSystem, contents prints the root casid, while recursive contents additionally walks the full recursive contents printing each entry. For CachingOnDiskFileSystem this is currently a stub that just prints the name of the filesystem with no contents. This is still helpful to know what kind of filesystem is in use for debugging.
1 parent a5da7ed commit 11f7f8c

File tree

5 files changed

+161
-13
lines changed

5 files changed

+161
-13
lines changed

clang/lib/CAS/IncludeTree.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,27 @@ class IncludeTreeFileSystem final : public llvm::cas::CASBackedFileSystem {
10391039
createThreadSafeProxyFS() override {
10401040
llvm::report_fatal_error("not implemented");
10411041
}
1042+
1043+
void printImpl(raw_ostream &OS, PrintType Type,
1044+
unsigned IndentLevel) const final {
1045+
printIndent(OS, IndentLevel);
1046+
IndentLevel += 1;
1047+
OS << "IncludeTreeFileSystem\n";
1048+
if (Type == PrintType::Summary)
1049+
return;
1050+
1051+
// Files is unordered, so sort by name to get a deterministic order.
1052+
std::vector<std::pair<StringRef, ObjectRef>> FileRefs;
1053+
for (auto &[Name, F] : Files) {
1054+
FileRefs.emplace_back(Name, F.ContentsRef);
1055+
}
1056+
llvm::sort(FileRefs, [](auto &&A, auto &&B) { return A.first < B.first; });
1057+
1058+
for (auto &[Name, ContentsRef] : FileRefs) {
1059+
printIndent(OS, IndentLevel);
1060+
OS << Name << ' ' << CAS.getID(ContentsRef) << '\n';
1061+
}
1062+
}
10421063
};
10431064
} // namespace
10441065

clang/unittests/CAS/IncludeTreeTest.cpp

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -296,27 +296,29 @@ TEST(IncludeTree, IncludeTreeFileListDuplicates) {
296296
EXPECT_EQ(I, Files.size());
297297
}
298298

299-
TEST(IncludeTree, IncludeTreeFileSystemOverlay) {
300-
StringRef PathSep = llvm::sys::path::get_separator();
301-
std::shared_ptr<ObjectStore> DB = llvm::cas::createInMemoryCAS();
299+
static Expected<IntrusiveRefCntPtr<llvm::vfs::FileSystem>>
300+
createTestInclueTreeFS(ObjectStore &DB, unsigned NumFiles = 10) {
302301
SmallVector<IncludeTree::FileList::FileEntry> Files;
303-
for (unsigned I = 0; I < 10; ++I) {
302+
for (unsigned I = 0; I < NumFiles; ++I) {
304303
std::optional<IncludeTree::File> File;
305304
std::string Path = "/file" + std::to_string(I);
306305
static constexpr StringRef Bytes = "123456789";
307306
std::optional<ObjectRef> Content;
308-
ASSERT_THAT_ERROR(
309-
DB->storeFromString({}, Bytes.substr(0, I)).moveInto(Content),
310-
llvm::Succeeded());
311-
ASSERT_THAT_ERROR(
312-
IncludeTree::File::create(*DB, Path, *Content).moveInto(File),
313-
llvm::Succeeded());
307+
if (auto E = DB.storeFromString({}, Bytes.substr(0, I)).moveInto(Content))
308+
return std::move(E);
309+
if (auto E = IncludeTree::File::create(DB, Path, *Content).moveInto(File))
310+
return std::move(E);
314311
Files.push_back({File->getRef(), I});
315312
}
313+
return createIncludeTreeFileSystem(DB, Files);
314+
}
315+
316+
TEST(IncludeTree, IncludeTreeFileSystemOverlay) {
317+
StringRef PathSep = llvm::sys::path::get_separator();
318+
std::shared_ptr<ObjectStore> DB = llvm::cas::createInMemoryCAS();
316319
IntrusiveRefCntPtr<llvm::vfs::FileSystem> IncludeTreeFS;
317-
ASSERT_THAT_ERROR(
318-
createIncludeTreeFileSystem(*DB, Files).moveInto(IncludeTreeFS),
319-
llvm::Succeeded());
320+
ASSERT_THAT_ERROR(createTestInclueTreeFS(*DB).moveInto(IncludeTreeFS),
321+
llvm::Succeeded());
320322

321323
auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
322324
FS->setCurrentWorkingDirectory("/dir");
@@ -338,3 +340,32 @@ TEST(IncludeTree, IncludeTreeFileSystemOverlay) {
338340
}
339341
ASSERT_EQ(NumFile, 2);
340342
}
343+
344+
TEST(IncludeTree, IncludeTreeFileSystemPrint) {
345+
std::shared_ptr<ObjectStore> DB = llvm::cas::createInMemoryCAS();
346+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> IncludeTreeFS;
347+
ASSERT_THAT_ERROR(
348+
createTestInclueTreeFS(*DB, /*NumFiles=*/3).moveInto(IncludeTreeFS),
349+
llvm::Succeeded());
350+
351+
{
352+
std::string FSStr;
353+
llvm::raw_string_ostream OS(FSStr);
354+
IncludeTreeFS->print(OS, llvm::vfs::FileSystem::PrintType::Summary);
355+
EXPECT_EQ(FSStr, "IncludeTreeFileSystem\n");
356+
}
357+
{
358+
std::string FSStr;
359+
llvm::raw_string_ostream OS(FSStr);
360+
IncludeTreeFS->print(OS, llvm::vfs::FileSystem::PrintType::Contents);
361+
StringRef Printed(FSStr);
362+
EXPECT_TRUE(Printed.consume_front("IncludeTreeFileSystem")) << Printed;
363+
EXPECT_TRUE(Printed.consume_front("\n /file0 llvmcas://")) << Printed;
364+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
365+
EXPECT_TRUE(Printed.consume_front("\n /file1 llvmcas://")) << Printed;
366+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
367+
EXPECT_TRUE(Printed.consume_front("\n /file2 llvmcas://")) << Printed;
368+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
369+
EXPECT_EQ(Printed, "\n"); // Final newline.
370+
}
371+
}

llvm/lib/CAS/CASFileSystem.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ class CASFileSystem final
9696
return WorkingDirectory.Path;
9797
}
9898

99+
void printImpl(raw_ostream &OS, PrintType Type,
100+
unsigned IndentLevel) const final;
101+
99102
Error initialize(ObjectRef Root);
100103

101104
CASFileSystem(std::shared_ptr<ObjectStore> DB, sys::path::Style PathStyle)
@@ -184,6 +187,46 @@ std::error_code CASFileSystem::setCurrentWorkingDirectory(const Twine &Path) {
184187
return std::error_code();
185188
}
186189

190+
void CASFileSystem::printImpl(raw_ostream &OS, PrintType Type,
191+
unsigned IndentLevel) const {
192+
printIndent(OS, IndentLevel);
193+
OS << "CASFileSystem\n";
194+
if (Type == PrintType::Summary)
195+
return;
196+
197+
IndentLevel += 1;
198+
printIndent(OS, IndentLevel);
199+
StringRef path_separator = get_separator(PathStyle);
200+
auto &Root = Cache->getRoot(path_separator);
201+
OS << "root: " << Root.getTreePath();
202+
assert(Root.getRef() && "missing ID for primary CASFileSystem root");
203+
if (Root.getRef())
204+
OS << ' ' << DB.getID(*Root.getRef()) << '\n';
205+
206+
if (Type == PrintType::Contents)
207+
return;
208+
209+
IndentLevel += 1;
210+
TreeSchema Schema(DB);
211+
auto TreeN = DB.getProxy(*Root.getRef());
212+
if (!TreeN) {
213+
OS << toString(TreeN.takeError()) << '\n';
214+
return;
215+
}
216+
Error E = Schema.walkFileTreeRecursively(
217+
DB, TreeN->getRef(),
218+
[&](const NamedTreeEntry &Entry, std::optional<TreeProxy> Tree) -> Error {
219+
if (Entry.getKind() != TreeEntry::Tree) {
220+
printIndent(OS, IndentLevel);
221+
Entry.print(OS, DB);
222+
return Error::success();
223+
}
224+
return Error::success();
225+
});
226+
if (E)
227+
OS << toString(std::move(E)) << '\n';
228+
}
229+
187230
Error CASFileSystem::loadDirectory(DirectoryEntry &Parent) {
188231
Directory &D = Parent.asDirectory();
189232
if (D.isComplete())

llvm/lib/CAS/CachingOnDiskFileSystem.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ class CachingOnDiskFileSystemImpl final : public CachingOnDiskFileSystem {
121121
return makeIntrusiveRefCnt<CachingOnDiskFileSystemImpl>(*this);
122122
}
123123

124+
void printImpl(raw_ostream &OS, PrintType Type,
125+
unsigned IndentLevel) const final;
126+
124127
CachingOnDiskFileSystemImpl(std::shared_ptr<ObjectStore> DB)
125128
: CachingOnDiskFileSystem(std::move(DB)) {
126129
initializeWorkingDirectory();
@@ -894,6 +897,13 @@ CachingOnDiskFileSystemImpl::createTreeBuilder() {
894897
return std::make_unique<TreeBuilder>(*this);
895898
}
896899

900+
void CachingOnDiskFileSystemImpl::printImpl(raw_ostream &OS, PrintType Type,
901+
unsigned IndentLevel) const {
902+
printIndent(OS, IndentLevel);
903+
OS << "CachingOnDiskFileSystem\n";
904+
// FIXME: print contents
905+
}
906+
897907
void CachingOnDiskFileSystemImpl::TreeBuilder::pushSymlink(
898908
const DirectoryEntry &Entry) {
899909
assert(Entry.isSymlink());

llvm/unittests/CAS/CASFileSystemTest.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,3 +516,46 @@ TEST(CASFileSystemTest, recursiveDirectoryIteratorNested) {
516516
sys::fs::file_type::regular_file));
517517
ASSERT_TRUE(isEnd(D, EC));
518518
}
519+
520+
TEST(CASFileSystemTest, print) {
521+
std::unique_ptr<ObjectStore> CAS = createInMemoryCAS();
522+
ASSERT_TRUE(CAS);
523+
std::optional<ObjectProxy> Tree;
524+
ASSERT_THAT_ERROR(createNestedTree(*CAS).moveInto(Tree), Succeeded());
525+
std::unique_ptr<vfs::FileSystem> CASFS;
526+
ASSERT_THAT_ERROR(createFS(*CAS, *Tree).moveInto(CASFS), Succeeded());
527+
528+
{
529+
std::string FSStr;
530+
llvm::raw_string_ostream OS(FSStr);
531+
CASFS->print(OS, vfs::FileSystem::PrintType::Summary);
532+
EXPECT_EQ(FSStr, "CASFileSystem\n");
533+
}
534+
{
535+
std::string FSStr;
536+
llvm::raw_string_ostream OS(FSStr);
537+
CASFS->print(OS, vfs::FileSystem::PrintType::Contents);
538+
std::string Expected = "CASFileSystem\n";
539+
Expected += " root: / " + Tree->getID().toString() + "\n";
540+
EXPECT_EQ(FSStr, Expected);
541+
}
542+
{
543+
std::string FSStr;
544+
llvm::raw_string_ostream OS(FSStr);
545+
CASFS->print(OS, vfs::FileSystem::PrintType::RecursiveContents);
546+
std::string Expected = "CASFileSystem\n";
547+
Expected += " root: / " + Tree->getID().toString() + "\n";
548+
StringRef Printed(FSStr);
549+
EXPECT_TRUE(Printed.consume_front("CASFileSystem")) << Printed;
550+
EXPECT_TRUE(Printed.consume_front("\n root: / llvmcas://")) << Printed;
551+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
552+
EXPECT_TRUE(Printed.consume_front("\n file llvmcas://")) << Printed;
553+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
554+
EXPECT_TRUE(Printed.consume_front(" /d2")) << Printed;
555+
EXPECT_TRUE(Printed.consume_front("\n file llvmcas://")) << Printed;
556+
Printed = Printed.drop_front(64); // 32 hash bytes in hex
557+
EXPECT_TRUE(Printed.consume_front(" /t1/d1\n")) << Printed;
558+
// ...
559+
EXPECT_TRUE(Printed.consume_back("/t3/t2/d2\n")) << Printed;
560+
}
561+
}

0 commit comments

Comments
 (0)