chunk_strcat(out, "#fe guid,");
for (i = 0; i < ST_I_PX_MAX; ++i) {
col = &stat_cols_px[i];
- if (stcol_nature(col) == FN_COUNTER && (col->cap & (STATS_PX_CAP_FE|STATS_PX_CAP_LI)))
+ if (stcol_is_generic(col) &&
+ col->cap & (STATS_PX_CAP_FE|STATS_PX_CAP_LI)) {
chunk_appendf(out, "%s,", col->name);
+ }
}
}
else {
chunk_appendf(out, "#be guid,");
for (i = 0; i < ST_I_PX_MAX; ++i) {
col = &stat_cols_px[i];
- if (stcol_nature(col) == FN_COUNTER && (col->cap & (STATS_PX_CAP_BE|STATS_PX_CAP_SRV)))
+ if (stcol_is_generic(col) &&
+ col->cap & (STATS_PX_CAP_BE|STATS_PX_CAP_SRV)) {
chunk_appendf(out, "%s,", col->name);
+ }
}
}
return 1;
}
+/* Preload an individual counter instance stored at <counter> with <token>
+ * value> for the <col> stat column.
+ *
+ * Returns 0 on success else non-zero if counter was not updated.
+ */
+static int load_ctr(const struct stat_col *col, const struct ist token,
+ void* counter)
+{
+ const enum field_nature fn = stcol_nature(col);
+ const enum field_format ff = stcol_format(col);
+ const char *ptr = istptr(token);
+ struct field value;
+
+ switch (ff) {
+ case FF_U64:
+ value.u.u64 = read_uint64(&ptr, istend(token));
+ break;
+
+ default:
+ /* Unsupported field nature. */
+ return 1;
+ }
+
+ /* Do not load value if non numeric characters present. */
+ if (ptr != istend(token))
+ return 1;
+
+ if (fn == FN_COUNTER && ff == FF_U64) {
+ *(uint64_t *)counter = value.u.u64;
+ }
+ else {
+ /* Unsupported field format/nature combination. */
+ return 1;
+ }
+
+ return 0;
+}
+
/* Parse a non header stats-file line <line>. Specify current parsing <domain>
* and <cols> stats column matrix derived from the last header line.
*
i = 0;
while (istlen(line) && i < STAT_FILE_MAX_COL_COUNT) {
const struct stat_col *col = cols[i++];
- enum field_format ff;
token = istsplit(&line, ',');
if (!istlen(token))
if (!col)
continue;
- ff = stcol_format(col);
- if (ff == FF_U64) {
- uint64_t *offset, value;
- const char *ptr;
-
- ptr = istptr(token);
- value = read_uint64(&ptr, istend(token));
- /* Do not load value if non numeric characters present. */
- if (ptr == istend(token)) {
- offset = (uint64_t *)(base_off + col->metric.offset[off]);
- *offset = value;
- }
- }
+ load_ctr(col, token, base_off + col->metric.offset[off]);
}
return 0;
.cap = (cap_f), \
}
-/* Returns true if <col> is fully defined, false if only used as name-desc. */
-static int stcol_is_generic(const struct stat_col *col)
-{
- return !!(col->cap);
-}
-
/* Convert stat_col <col> to old-style <name> as name_desc. */
static void stcol2ndesc(struct name_desc *name, const struct stat_col *col)
{
THREAD_LOCAL void *trash_counters;
-/* Insert into <st_tree> all stat columns from <cols> indexed by their name. */
+/* Insert <cols> generic stat columns into <st_tree> indexed by their name. */
int generate_stat_tree(struct eb_root *st_tree, const struct stat_col cols[])
{
const struct stat_col *col;
for (i = 0; i < ST_I_PX_MAX; ++i) {
col = &cols[i];
- if (stcol_nature(col) == FN_COUNTER) {
+
+ if (stcol_is_generic(col)) {
len = strlen(col->name);
node = malloc(sizeof(struct stcol_node) + len + 1);
if (!node)
const void *counters, uint8_t cap,
int stat_file)
{
+ enum field_nature fn;
struct field value;
void *counter = NULL;
int wrong_side = 0;
return (struct field){ .type = FF_EMPTY };
}
- switch (stcol_format(col)) {
- case FF_U64:
- value = mkf_u64(stcol_nature(col), *(uint64_t *)counter);
- break;
- default:
- /* only FF_U64 counters currently use generic metric calculation */
+ fn = stcol_nature(col);
+ if (fn == FN_COUNTER) {
+ switch (stcol_format(col)) {
+ case FF_U64:
+ value = mkf_u64(FN_COUNTER, *(uint64_t *)counter);
+ break;
+ default:
+ /* only FF_U64 counters currently use generic metric calculation */
+ ABORT_NOW();
+ }
+ }
+ else {
+ /* No generic column available for other field nature. */
ABORT_NOW();
}