aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/lwtrace/mon/analytics/util.h
blob: e4b067f8a9e5e88ecd826a0a03fa88d9185df2a1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#pragma once

#include "data.h"
#include <util/generic/algorithm.h>
#include <util/generic/hash_set.h>
#include <util/string/vector.h>

namespace NAnalytics {

// Get rid of NaNs and INFs
inline double Finitize(double x, double notFiniteValue = 0.0)
{
    return isfinite(x)? x: notFiniteValue;
}

inline void ParseNameAndOpts(const TString& nameAndOpts, TString& name, THashSet<TString>& opts) 
{
    name.clear();
    opts.clear();
    bool first = true;
    auto vs = SplitString(nameAndOpts, "-");
    for (const auto& s : vs) {
        if (first) {
            name = s;
            first = false;
        } else {
            opts.insert(s);
        }
    }
}

inline TString ParseName(const TString& nameAndOpts) 
{
    auto vs = SplitString(nameAndOpts, "-");
    if (vs.empty()) {
        return TString(); 
    } else {
        return vs[0];
    }
}

template <class R, class T>
inline R AccumulateIfExist(const TString& name, const TTable& table, R r, T t) 
{
    ForEach(table.begin(), table.end(), [=,&r] (const TRow& row) {
        double value;
        if (row.Get(name, value)) {
            r = t(r, value);
        }
    });
    return r;
}

inline double MinValue(const TString& nameAndOpts, const TTable& table) 
{
    TString name; 
    THashSet<TString> opts; 
    ParseNameAndOpts(nameAndOpts, name, opts);
    bool stack = opts.contains("stack");
    if (stack) {
        return 0.0;
    } else {
        auto zero = 0.0;

        return AccumulateIfExist(name, table, 1.0 / zero /*+inf*/, [] (double x, double y) {
            return Min(x, y);
        });
    }
}

inline double MaxValue(const TString& nameAndOpts, const TTable& table) 
{
    TString name; 
    THashSet<TString> opts; 
    ParseNameAndOpts(nameAndOpts, name, opts);
    bool stack = opts.contains("stack");
    if (stack) {
        return AccumulateIfExist(name, table, 0.0, [] (double x, double y) {
            return x + y;
        });
    } else {
        auto zero = 0.0;

        return AccumulateIfExist(name, table, -1.0 / zero /*-inf*/, [] (double x, double y) {
            return Max(x, y);
        });
    }
}

template <class T>
inline void Map(TTable& table, const TString& rname, T t) 
{
    ForEach(table.begin(), table.end(), [=] (TRow& row) {
        row[rname] = t(row);
    });
}

inline std::function<bool(const TRow&)> HasNoValueFor(TString name) 
{
    return [=] (const TRow& row) -> bool {
        double value;
        return !row.Get(name, value);
    };
}


inline std::function<double(const TRow&)> GetValueFor(TString name, double defVal = 0.0) 
{
    return [=] (const TRow& row) -> double {
        double value;
        return row.Get(name, value)? value: defVal;
    };
}

inline std::function<double(const TRow&)> Const(double defVal = 0.0)
{
    return [=] (const TRow&) {
        return defVal;
    };
}

}