58 char const* cur = s.data();
59 char const* next = s.data();
63 char const* lastSpace =
nullptr;
64 char const* previousLastSpace =
nullptr;
67 auto previousState =
state;
70 switch (previousState) {
72 if (strncmp(cur,
"[METRIC] ", 9) == 0) {
75 match.beginKey = cur + 9;
79 next = strpbrk(cur,
",/\n");
80 if (next ==
nullptr || *next ==
'\n' || ((cur == next) && (
match.endKey -
match.beginKey == 0))) {
81 }
else if (*next ==
'/') {
89 }
else if (*next ==
',') {
95 match.firstIndex = strtol(cur, &err, 10);
99 }
else if (*next ==
',') {
110 match.firstIndex = -1;
111 match.endKey = next + 1;
116 match.lastIndex = strtol(cur, &err, 10);
119 }
else if (*next ==
',') {
127 }
else if (*next ==
' ') {
136 match.beginStringValue = next + 1;
137 match.endStringValue = next + 1;
141 if (strncmp(
match.beginKey,
"data_relayer/", 13) == 0 &&
match.beginKey[13] !=
'w' &&
match.beginKey[13] !=
'h') {
147 match.intValue = strtol(cur, &err, 10);
150 }
else if (*next ==
' ') {
157 match.uint64Value = strtoull(cur, &err, 10);
160 }
else if (*next ==
' ') {
167 match.floatValue = strtof(cur, &err);
170 }
else if (*next ==
' ') {
177 next = (
char*)memchr(cur,
' ', s.data() + s.size() - cur);
178 if (next ==
nullptr) {
179 auto timestamp = strtoull(cur, &err, 10);
180 if (*err !=
'\n' && *err !=
'\0') {
184 match.endStringValue = previousLastSpace;
185 next = previousLastSpace;
189 match.endStringValue = lastSpace;
190 match.timestamp = timestamp;
196 }
else if (*next ==
' ') {
197 previousLastSpace = lastSpace;
204 match.timestamp = strtoull(cur, &err, 10);
207 }
else if (*next ==
' ') {
209 }
else if (next == s.data() + s.size() || *next ==
'\n') {
339 auto slash =
key.find_first_of(
"/");
340 if (slash == std::string_view::npos) {
343 auto prefix = std::string_view(
key.data(), slash);
346 auto cmpPrefixFn = [&prefixes = info.metricPrefixes](
MetricPrefixIndex const&
a, std::string_view
b) ->
bool {
347 return std::string_view(prefixes[
a.index].prefix, prefixes[
a.index].size) <
b;
350 auto pi = std::lower_bound(info.metricLabelsPrefixesSortedIdx.begin(),
351 info.metricLabelsPrefixesSortedIdx.end(),
354 bool hasPrefix = pi != info.metricLabelsPrefixesSortedIdx.end() && (std::string_view(info.metricPrefixes[pi->index].prefix, info.metricPrefixes[pi->index].size) == prefix);
356 auto rb = info.metricLabelsAlphabeticallySortedIdx.begin() + (hasPrefix ? info.metricPrefixes[pi->index].begin : 0);
357 auto re = info.metricLabelsAlphabeticallySortedIdx.begin() + (hasPrefix ? info.metricPrefixes[pi->index].end : info.metricLabelsAlphabeticallySortedIdx.size());
363 auto mi = std::lower_bound(rb, re,
key, cmpFn);
365 auto miIndex = std::distance(info.metricLabelsAlphabeticallySortedIdx.begin(), mi);
366 auto miInsertionPoint = info.metricLabelsAlphabeticallySortedIdx.begin() + miIndex;
376 metricLabel.
size = strlen(metricLabel.
label);
384 auto metricIndex = info.metrics.size();
388 info.metricLabelsAlphabeticallySortedIdx.insert(miInsertionPoint, metricLabelIdx);
391 info.metricLabels.push_back(metricLabel);
392 updatePrefix(prefix, info, hasPrefix, pi);
393 info.metrics.emplace_back(metricInfo);
403 size_t metricIndex = -1;
406 switch (
match.type) {
414 memcpy(stringValue.
data,
match.beginStringValue, lastChar);
415 stringValue.
data[lastChar] =
'\0';
425 auto slash =
key.find_first_of(
"/");
426 if (slash == std::string_view::npos) {
429 auto prefix = std::string_view(
key.data(), slash);
432 auto cmpPrefixFn = [&prefixes = info.metricPrefixes](
MetricPrefixIndex const&
a, std::string_view
b) ->
bool {
433 return std::string_view(prefixes[
a.index].prefix, prefixes[
a.index].size) <
b;
436 auto pi = std::lower_bound(info.metricLabelsPrefixesSortedIdx.begin(),
437 info.metricLabelsPrefixesSortedIdx.end(),
440 bool hasPrefix = pi != info.metricLabelsPrefixesSortedIdx.end() && (std::string_view(info.metricPrefixes[pi->index].prefix, info.metricPrefixes[pi->index].size) == prefix);
442 auto rb = info.metricLabelsAlphabeticallySortedIdx.begin() + (hasPrefix ? info.metricPrefixes[pi->index].begin : 0);
443 auto re = info.metricLabelsAlphabeticallySortedIdx.begin() + (hasPrefix ? info.metricPrefixes[pi->index].end : info.metricLabelsAlphabeticallySortedIdx.size());
450 auto mi = std::lower_bound(rb, re,
key, cmpFn);
452 auto miIndex = std::distance(info.metricLabelsAlphabeticallySortedIdx.begin(), mi);
453 auto miInsertionPoint = info.metricLabelsAlphabeticallySortedIdx.begin() + miIndex;
465 memcpy(metricLabel.
label,
match.beginKey, lastChar);
466 metricLabel.
label[lastChar] =
'\0';
467 metricLabel.
size = lastChar;
469 metricLabelIdx.
index = info.metrics.size();
470 info.metricLabels.push_back(metricLabel);
471 info.metricLabelsAlphabeticallySortedIdx.insert(miInsertionPoint, metricLabelIdx);
473 updatePrefix(prefix, info, hasPrefix, pi);
476 metricIndex = info.metrics.size();
477 assert(metricInfo.storeIdx != -1);
478 assert(metricLabel.
label[0] !=
'\0');
479 if (newMetricsCallback !=
nullptr) {
480 newMetricsCallback(metricLabel.
label, metricInfo,
match.intValue, metricIndex);
482 info.metrics.push_back(metricInfo);
484 metricIndex = mi->index;
486 assert(metricIndex != -1);
488 MetricInfo& metricInfo = info.metrics[metricIndex];
491 auto sizeOfCollection = 0;
492 switch (metricInfo.
type) {
495 sizeOfCollection = info.intMetrics[metricInfo.
storeIdx].size();
499 info.stringMetrics[metricInfo.
storeIdx][metricInfo.
pos] = stringValue;
500 sizeOfCollection = info.stringMetrics[metricInfo.
storeIdx].size();
501 info.stringTimestamps[metricInfo.
storeIdx][metricInfo.
pos] =
match.timestamp;
505 sizeOfCollection = info.floatMetrics[metricInfo.
storeIdx].size();
506 info.floatTimestamps[metricInfo.
storeIdx][metricInfo.
pos] =
match.timestamp;
509 info.uint64Metrics[metricInfo.
storeIdx][metricInfo.
pos] =
match.uint64Value;
510 sizeOfCollection = info.uint64Metrics[metricInfo.
storeIdx].size();
511 info.uint64Timestamps[metricInfo.
storeIdx][metricInfo.
pos] =
match.timestamp;
515 sizeOfCollection = info.enumMetrics[metricInfo.
storeIdx].size();
525 info.minDomain[metricIndex] = std::min(info.minDomain[metricIndex], (
size_t)
match.timestamp);
526 info.maxDomain[metricIndex] = std::max(info.maxDomain[metricIndex], (
size_t)
match.timestamp);
527 info.max[metricIndex] = std::max(info.max[metricIndex],
match.floatValue);
528 info.min[metricIndex] = std::min(info.min[metricIndex],
match.floatValue);
529 auto onlineAverage = [](
float nextValue,
float previousAverage,
float previousCount) {
530 return previousAverage + (nextValue - previousAverage) / (previousCount + 1);
532 info.average[metricIndex] = onlineAverage(
match.floatValue, info.average[metricIndex], metricInfo.
filledMetrics);
534 metricInfo.
pos = (metricInfo.
pos + 1) % sizeOfCollection;
537 info.changed[metricIndex] =
true;