1 #include "support/MemoryTree.h"
2 #include "Trace.h"
3 #include "llvm/ADT/STLExtras.h"
4 #include "llvm/ADT/StringRef.h"
5 #include <cstddef>
6 
7 namespace clang {
8 namespace clangd {
9 
10 namespace {
11 
traverseTree(const MemoryTree & MT,std::string & ComponentName,const trace::Metric & Out)12 size_t traverseTree(const MemoryTree &MT, std::string &ComponentName,
13                     const trace::Metric &Out) {
14   size_t OriginalLen = ComponentName.size();
15   if (!ComponentName.empty())
16     ComponentName += '.';
17   size_t Total = MT.self();
18   for (const auto &Entry : MT.children()) {
19     ComponentName += Entry.first;
20     Total += traverseTree(Entry.getSecond(), ComponentName, Out);
21     ComponentName.resize(OriginalLen + 1);
22   }
23   ComponentName.resize(OriginalLen);
24   Out.record(Total, ComponentName);
25   return Total;
26 }
27 } // namespace
28 
createChild(llvm::StringRef Name)29 MemoryTree &MemoryTree::createChild(llvm::StringRef Name) {
30   auto &Child = Children.try_emplace(Name, DetailAlloc).first->getSecond();
31   return Child;
32 }
33 
34 const llvm::DenseMap<llvm::StringRef, MemoryTree> &
children() const35 MemoryTree::children() const {
36   return Children;
37 }
38 
total() const39 size_t MemoryTree::total() const {
40   size_t Total = Size;
41   for (const auto &Entry : Children)
42     Total += Entry.getSecond().total();
43   return Total;
44 }
45 
record(const MemoryTree & MT,std::string RootName,const trace::Metric & Out)46 void record(const MemoryTree &MT, std::string RootName,
47             const trace::Metric &Out) {
48   traverseTree(MT, RootName, Out);
49 }
50 } // namespace clangd
51 } // namespace clang
52