@@ -270,6 +270,7 @@ Error DatabaseFile::validate(MappedFileRegion &Region) {
270270namespace {
271271
272272class SubtrieHandle ;
273+ class TrieVisitor ;
273274class SubtrieSlotValue {
274275public:
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-
917883static 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-
1019935LLVM_DUMP_METHOD void OnDiskHashMappedTrie::dump () const { print (dbgs ()); }
1020936
1021937static 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