Skip to content

Commit 519ea5a

Browse files
[CAS] Rewrite the OnDiskCAS printer. NFC
Rewrite the CAS print function with a visitor class that can be extended with more error handling and be used to traversal the trie with other functions. (cherry picked from commit cc5d7d9)
1 parent 518df4d commit 519ea5a

File tree

1 file changed

+166
-86
lines changed

1 file changed

+166
-86
lines changed

llvm/lib/CAS/OnDiskHashMappedTrie.cpp

Lines changed: 166 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ Error DatabaseFile::validate(MappedFileRegion &Region) {
270270
namespace {
271271

272272
class SubtrieHandle;
273+
class TrieVisitor;
273274
class SubtrieSlotValue {
274275
public:
275276
explicit operator bool() const { return !isEmpty(); }
@@ -355,6 +356,7 @@ class SubtrieHandle {
355356
}
356357

357358
int64_t getSize() const { return getSize(H->NumBits); }
359+
size_t getNumSlots() const { return Slots.size(); }
358360

359361
SubtrieSlotValue load(size_t I) const {
360362
return SubtrieSlotValue(Slots[I].load());
@@ -364,9 +366,6 @@ class SubtrieHandle {
364366
}
365367

366368
void printHash(raw_ostream &OS, ArrayRef<uint8_t> Bytes) const;
367-
void print(raw_ostream &OS, HashMappedTrieHandle Trie,
368-
SmallVectorImpl<int64_t> &Records,
369-
std::optional<std::string> Prefix = std::nullopt) const;
370369

371370
/// Return None on success, or the existing offset on failure.
372371
bool compare_exchange_strong(size_t I, SubtrieSlotValue &Expected,
@@ -881,39 +880,6 @@ static void printHexDigits(raw_ostream &OS, ArrayRef<uint8_t> Bytes,
881880
}
882881
}
883882

884-
void HashMappedTrieHandle::print(
885-
raw_ostream &OS, function_ref<void(ArrayRef<char>)> PrintRecordData) const {
886-
OS << "hash-num-bits=" << getNumHashBits()
887-
<< " hash-size=" << getNumHashBytes()
888-
<< " record-data-size=" << getRecordDataSize() << "\n";
889-
SubtrieHandle Root = getRoot();
890-
891-
SmallVector<int64_t> Records;
892-
if (Root)
893-
Root.print(OS, *this, Records);
894-
895-
if (Records.empty())
896-
return;
897-
llvm::sort(Records);
898-
OS << "records\n";
899-
for (int64_t Offset : Records) {
900-
OS << "- addr=" << (void *)Offset << " ";
901-
HashMappedTrieHandle Trie = *this;
902-
HashMappedTrieHandle::RecordData Record =
903-
Trie.getRecord(SubtrieSlotValue::getDataOffset(Offset));
904-
if (PrintRecordData) {
905-
PrintRecordData(Record.Proxy.Data);
906-
} else {
907-
OS << "bytes=";
908-
ArrayRef<uint8_t> Data(
909-
reinterpret_cast<const uint8_t *>(Record.Proxy.Data.data()),
910-
Record.Proxy.Data.size());
911-
printHexDigits(OS, Data, 0, Data.size() * 8);
912-
}
913-
OS << "\n";
914-
}
915-
}
916-
917883
static void printBits(raw_ostream &OS, ArrayRef<uint8_t> Bytes, size_t StartBit,
918884
size_t NumBits) {
919885
assert(StartBit + NumBits <= Bytes.size() * 8u);
@@ -966,56 +932,6 @@ static void printPrefix(raw_ostream &OS, StringRef Prefix) {
966932
OS << "[" << Prefix << "]";
967933
}
968934

969-
void SubtrieHandle::print(raw_ostream &OS, HashMappedTrieHandle Trie,
970-
SmallVectorImpl<int64_t> &Records,
971-
std::optional<std::string> Prefix) const {
972-
if (!Prefix) {
973-
OS << "root";
974-
Prefix.emplace();
975-
} else {
976-
OS << "subtrie=";
977-
printPrefix(OS, *Prefix);
978-
}
979-
980-
OS << " addr="
981-
<< (void *)(reinterpret_cast<const char *>(H) - Region->data());
982-
983-
const size_t NumSlots = Slots.size();
984-
OS << " num-slots=" << NumSlots << "\n";
985-
SmallVector<SubtrieHandle> Subs;
986-
SmallVector<std::string> Prefixes;
987-
for (size_t I = 0, E = NumSlots; I != E; ++I) {
988-
SubtrieSlotValue Slot = load(I);
989-
if (!Slot)
990-
continue;
991-
OS << "- index=";
992-
for (size_t Pad : {10, 100, 1000})
993-
if (I < Pad && NumSlots >= Pad)
994-
OS << "0";
995-
OS << I << " ";
996-
if (Slot.isSubtrie()) {
997-
SubtrieHandle S(*Region, Slot);
998-
std::string SubtriePrefix = *Prefix;
999-
appendIndexBits(SubtriePrefix, I, NumSlots);
1000-
OS << "addr=" << (void *)Slot.asSubtrie();
1001-
OS << " subtrie=";
1002-
printPrefix(OS, SubtriePrefix);
1003-
OS << "\n";
1004-
Subs.push_back(S);
1005-
Prefixes.push_back(SubtriePrefix);
1006-
continue;
1007-
}
1008-
Records.push_back(Slot.asData());
1009-
HashMappedTrieHandle::RecordData Record = Trie.getRecord(Slot);
1010-
OS << "addr=" << (void *)Record.getFileOffset().get();
1011-
OS << " content=";
1012-
printHash(OS, Record.Proxy.Hash);
1013-
OS << "\n";
1014-
}
1015-
for (size_t I = 0, E = Subs.size(); I != E; ++I)
1016-
Subs[I].print(OS, Trie, Records, Prefixes[I]);
1017-
}
1018-
1019935
LLVM_DUMP_METHOD void OnDiskHashMappedTrie::dump() const { print(dbgs()); }
1020936

1021937
static Expected<size_t> checkParameter(StringRef Label, size_t Max,
@@ -1142,6 +1058,170 @@ OnDiskHashMappedTrie::create(const Twine &PathTwine, const Twine &TrieNameTwine,
11421058
return OnDiskHashMappedTrie(std::make_unique<ImplType>(std::move(Impl)));
11431059
}
11441060

1061+
//===----------------------------------------------------------------------===//
1062+
// TrieVisitor data structures.
1063+
//===----------------------------------------------------------------------===//
1064+
1065+
namespace {
1066+
// A vistior to traverse the Trie.
1067+
class TrieVisitor {
1068+
public:
1069+
TrieVisitor(HashMappedTrieHandle Trie) : Trie(Trie) {}
1070+
virtual ~TrieVisitor() = default;
1071+
Error visit(HashMappedTrieHandle Root);
1072+
1073+
private:
1074+
virtual Error visitSubTrie(StringRef Prefix, SubtrieHandle SubTrie) {
1075+
return Error::success();
1076+
}
1077+
1078+
virtual Error visitSlot(unsigned I, SubtrieHandle Subtrie, StringRef Prefix,
1079+
SubtrieSlotValue Slot) {
1080+
return Error::success();
1081+
}
1082+
1083+
protected:
1084+
HashMappedTrieHandle Trie;
1085+
1086+
private:
1087+
Error traverseTrieNode(SubtrieHandle Node, StringRef Prefix);
1088+
};
1089+
1090+
class TriePrinter : public TrieVisitor {
1091+
public:
1092+
TriePrinter(HashMappedTrieHandle Trie, raw_ostream &OS,
1093+
function_ref<void(ArrayRef<char>)> PrintRecordData)
1094+
: TrieVisitor(Trie), OS(OS), PrintRecordData(PrintRecordData) {}
1095+
1096+
Error printRecords() {
1097+
if (Records.empty())
1098+
return Error::success();
1099+
1100+
OS << "records\n";
1101+
llvm::sort(Records);
1102+
for (int64_t Offset : Records) {
1103+
HashMappedTrieHandle::RecordData Record =
1104+
Trie.getRecord(SubtrieSlotValue::getDataOffset(Offset));
1105+
if (auto Err = printRecord(Record))
1106+
return Err;
1107+
}
1108+
return Error::success();
1109+
}
1110+
1111+
Error printRecord(HashMappedTrieHandle::RecordData &Record) {
1112+
OS << "- addr=" << (void*)Record.getFileOffset().get() << " ";
1113+
if (PrintRecordData) {
1114+
PrintRecordData(Record.Proxy.Data);
1115+
} else {
1116+
OS << "bytes=";
1117+
ArrayRef<uint8_t> Data(
1118+
reinterpret_cast<const uint8_t *>(Record.Proxy.Data.data()),
1119+
Record.Proxy.Data.size());
1120+
printHexDigits(OS, Data, 0, Data.size() * 8);
1121+
}
1122+
OS << "\n";
1123+
return Error::success();
1124+
}
1125+
1126+
Error visitSubTrie(StringRef Prefix, SubtrieHandle SubTrie) override {
1127+
if (Prefix.empty()) {
1128+
OS << "root";
1129+
} else {
1130+
OS << "subtrie=";
1131+
printPrefix(OS, Prefix);
1132+
}
1133+
1134+
OS << " addr="
1135+
<< (void *)(reinterpret_cast<const char *>(&SubTrie.getHeader()) -
1136+
Trie.getRegion().data());
1137+
OS << " num-slots=" << SubTrie.getNumSlots() << "\n";
1138+
return Error::success();
1139+
}
1140+
1141+
Error visitSlot(unsigned I, SubtrieHandle Subtrie, StringRef Prefix,
1142+
SubtrieSlotValue Slot) override {
1143+
OS << "- index=";
1144+
for (size_t Pad : {10, 100, 1000})
1145+
if (I < Pad && Subtrie.getNumSlots() >= Pad)
1146+
OS << "0";
1147+
OS << I << " ";
1148+
if (Slot.isSubtrie()) {
1149+
OS << "addr=" << (void *)Slot.asSubtrie();
1150+
OS << " subtrie=";
1151+
printPrefix(OS, Prefix);
1152+
OS << "\n";
1153+
return Error::success();
1154+
}
1155+
HashMappedTrieHandle::RecordData Record = Trie.getRecord(Slot);
1156+
OS << "addr=" << (void *)Record.getFileOffset().get();
1157+
OS << " content=";
1158+
Subtrie.printHash(OS, Record.Proxy.Hash);
1159+
OS << "\n";
1160+
Records.push_back(Slot.asData());
1161+
return Error::success();
1162+
}
1163+
1164+
private:
1165+
raw_ostream &OS;
1166+
function_ref<void(ArrayRef<char>)> PrintRecordData;
1167+
SmallVector<int64_t> Records;
1168+
};
1169+
} // namespace
1170+
1171+
Error TrieVisitor::visit(HashMappedTrieHandle Trie) {
1172+
auto Root = Trie.getRoot();
1173+
if (!Root)
1174+
return Error::success();
1175+
1176+
if (auto Err = traverseTrieNode(Root, ""))
1177+
return Err;
1178+
return Error::success();
1179+
}
1180+
1181+
Error TrieVisitor::traverseTrieNode(SubtrieHandle Node, StringRef Prefix) {
1182+
if (auto Err = visitSubTrie(Prefix, Node))
1183+
return Err;
1184+
1185+
SmallVector<SubtrieHandle> Subs;
1186+
SmallVector<std::string> Prefixes;
1187+
const size_t NumSlots = Node.getNumSlots();
1188+
for (size_t I = 0, E = NumSlots; I != E; ++I) {
1189+
SubtrieSlotValue Slot = Node.load(I);
1190+
if (!Slot)
1191+
continue;
1192+
std::string SubtriePrefix = Prefix.str();
1193+
appendIndexBits(SubtriePrefix, I, NumSlots);
1194+
if (Slot.isSubtrie()) {
1195+
SubtrieHandle S(Trie.getRegion(), Slot);
1196+
Subs.push_back(S);
1197+
Prefixes.push_back(SubtriePrefix);
1198+
}
1199+
if (auto Err = visitSlot(I, Node, SubtriePrefix, Slot))
1200+
return Err;
1201+
}
1202+
for (size_t I = 0, E = Subs.size(); I != E; ++I)
1203+
if (auto Err = traverseTrieNode(Subs[I], Prefixes[I]))
1204+
return Err;
1205+
1206+
return Error::success();
1207+
}
1208+
1209+
void HashMappedTrieHandle::print(
1210+
raw_ostream &OS, function_ref<void(ArrayRef<char>)> PrintRecordData) const {
1211+
OS << "hash-num-bits=" << getNumHashBits()
1212+
<< " hash-size=" << getNumHashBytes()
1213+
<< " record-data-size=" << getRecordDataSize() << "\n";
1214+
1215+
TriePrinter Printer(*this, OS, PrintRecordData);
1216+
if (auto Err = Printer.visit(*this))
1217+
OS << "error: " << toString(std::move(Err)) << "\n";
1218+
1219+
if (auto Err = Printer.printRecords())
1220+
OS << "error: " << toString(std::move(Err)) << "\n";
1221+
1222+
return;
1223+
}
1224+
11451225
//===----------------------------------------------------------------------===//
11461226
// DataAllocator data structures.
11471227
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)