| 108 | } |
| 109 | |
| 110 | void TNetStatSampler::UpdateFromData(const TString& data) { |
| 111 | TStringInput input(data); |
| 112 | |
| 113 | struct TNetStatEntry { |
| 114 | TString Header; |
| 115 | TVector<TString> Names; |
| 116 | TVector<i64> Values; |
| 117 | }; |
| 118 | |
| 119 | TString line; |
| 120 | while (input.ReadLine(line)) { |
| 121 | TNetStatEntry entry; |
| 122 | |
| 123 | // Odd line: a list of names |
| 124 | { |
| 125 | auto pos = line.find(':'); |
| 126 | entry.Header = line.substr(0, pos); |
| 127 | auto tail = TStringBuf(line.data() + pos + 2, line.data() + line.size()); |
| 128 | StringSplitter(tail).Split(' ').Consume([&](TStringBuf token) { |
| 129 | entry.Names.emplace_back(token); |
| 130 | }); |
| 131 | } |
| 132 | |
| 133 | // Even line : a list of values |
| 134 | { |
| 135 | input.ReadLine(line); |
| 136 | auto pos = line.find(':'); |
| 137 | entry.Header = line.substr(0, pos); |
| 138 | auto tail = TStringBuf(line.data() + pos + 2, line.data() + line.size()); |
| 139 | StringSplitter(tail).Split(' ').Consume([&](TStringBuf token) { |
| 140 | entry.Values.emplace_back(FromString<i64>(token)); |
| 141 | }); |
| 142 | } |
| 143 | |
| 144 | for (size_t i : xrange(entry.Names.size())) { |
| 145 | TString name = TStringBuilder() << entry.Header << '.' << entry.Names[i]; |
| 146 | auto it = Values.find(name); |
| 147 | if (it != Values.end()) { |
| 148 | it->second.Update(entry.Values[i]); |
| 149 | } else if (AllowAllKeys) { |
| 150 | Values[name].Update(entry.Values[i]); |
| 151 | } |
| 152 | } |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | void TNetStatSampler::Publish(TTracer& tracer) const { |
| 157 | for (const auto& item : Values) { |
nothing calls this directly
no test coverage detected