aboutsummaryrefslogtreecommitdiffstats
path: root/yt/yt/core/misc/statistics.h
blob: 9467477600982bf9d94df6ec1a909de4c20c33d1 (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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#pragma once

#include "public.h"

#include <yt/yt/core/yson/forwarding_consumer.h>
#include <yt/yt/core/yson/consumer.h>
#include <yt/yt/core/yson/building_consumer.h>

#include <yt/yt/core/ytree/tree_builder.h>
#include <yt/yt/core/ytree/convert.h>

#include <yt/yt/core/actions/callback.h>

#include <yt/yt/core/misc/property.h>

#include <util/generic/iterator_range.h>

namespace NYT {

////////////////////////////////////////////////////////////////////////////////

class TSummary
{
public:
    TSummary();

    TSummary(i64 sum, i64 count, i64 min, i64 max, std::optional<i64> last);

    void AddSample(i64 sample);

    void Merge(const TSummary& summary);

    void Reset();

    DEFINE_BYVAL_RO_PROPERTY(i64, Sum);
    DEFINE_BYVAL_RO_PROPERTY(i64, Count);
    DEFINE_BYVAL_RO_PROPERTY(i64, Min);
    DEFINE_BYVAL_RO_PROPERTY(i64, Max);
    DEFINE_BYVAL_RO_PROPERTY(std::optional<i64>, Last);

    void Persist(const TStreamPersistenceContext& context);

    bool operator == (const TSummary& other) const;

    friend class TStatisticsBuildingConsumer;
};

void Serialize(const TSummary& summary, NYson::IYsonConsumer* consumer);

////////////////////////////////////////////////////////////////////////////////

class TStatistics
{
public:
    using TSummaryMap = std::map<NYPath::TYPath, TSummary>;
    using TSummaryRange = TIteratorRange<TSummaryMap::const_iterator>;
    DEFINE_BYREF_RO_PROPERTY(TSummaryMap, Data);
    DEFINE_BYVAL_RW_PROPERTY(std::optional<TInstant>, Timestamp);

public:
    void AddSample(const NYPath::TYPath& path, i64 sample);

    void AddSample(const NYPath::TYPath& path, const NYTree::INodePtr& sample);

    template <class T>
    void AddSample(const NYPath::TYPath& path, const T& sample);

    void ReplacePathWithSample(const NYPath::TYPath& path, i64 sample);

    void ReplacePathWithSample(const NYPath::TYPath& path, const NYTree::INodePtr& sample);

    template <class T>
    void ReplacePathWithSample(const NYPath::TYPath& path, const T& sample);

    //! Merge statistics by merging summaries for each common statistics path.
    void Merge(const TStatistics& statistics);
    //! Merge statistics by taking summary from #statistics for each common statistics path.
    void MergeWithOverride(const TStatistics& statistics);

    //! Get range of all elements whose path starts with a given strict prefix path (possibly empty).
    /*!
     * Pre-requisites: `prefixPath` must not have terminating slash.
     * Examples: /a/b is a prefix path for /a/b/hij but not for /a/bcd/efg nor /a/b itself.
     */
    TSummaryRange GetRangeByPrefix(const TString& prefixPath) const;

    //! Remove all the elements starting from prefixPath.
    //! The requirements for prefixPath are the same as in GetRangeByPrefix.
    void RemoveRangeByPrefix(const TString& prefixPath);

    void Persist(const TStreamPersistenceContext& context);

private:
    template <class TCallback>
    void ProcessNodeWithCallback(const NYPath::TYPath& path, const NYTree::INodePtr& sample, TCallback callback);

    TSummary& GetSummary(const NYPath::TYPath& path);

    friend class TStatisticsBuildingConsumer;
};

i64 GetNumericValue(const TStatistics& statistics, const TString& path);

std::optional<i64> FindNumericValue(const TStatistics& statistics, const TString& path);
std::optional<TSummary> FindSummary(const TStatistics& statistics, const TString& path);

////////////////////////////////////////////////////////////////////////////////

void Serialize(const TStatistics& statistics, NYson::IYsonConsumer* consumer);

void CreateBuildingYsonConsumer(std::unique_ptr<NYson::IBuildingYsonConsumer<TStatistics>>* buildingConsumer, NYson::EYsonType ysonType);

////////////////////////////////////////////////////////////////////////////////

class TStatisticsConsumer
    : public NYson::TForwardingYsonConsumer
{
public:
    using TSampleHandler = TCallback<void(const NYTree::INodePtr& sample)>;
    explicit TStatisticsConsumer(TSampleHandler consumer);

private:
    const std::unique_ptr<NYTree::ITreeBuilder> TreeBuilder_;
    const TSampleHandler SampleHandler_;

    void OnMyListItem() override;
};

////////////////////////////////////////////////////////////////////////////////

template <class TTags>
class TTaggedStatistics
{
public:
    using TTaggedSummaries = THashMap<TTags, TSummary>;
    using TSummaryMap = std::map<NYPath::TYPath, TTaggedSummaries>;

    void AppendStatistics(const TStatistics& statistics, TTags tags);
    void AppendTaggedSummary(const NYPath::TYPath& path, const TTaggedSummaries& taggedSummaries);

    const TTaggedSummaries* FindTaggedSummaries(const NYPath::TYPath& path) const;
    const TSummaryMap& GetData() const;

    void Persist(const TStreamPersistenceContext& context);

private:
    TSummaryMap Data_;
};

////////////////////////////////////////////////////////////////////////////////

template <class TTags>
void Serialize(const TTaggedStatistics<TTags>& statistics, NYson::IYsonConsumer* consumer);

////////////////////////////////////////////////////////////////////////////////

template <class TValue>
void SerializeYsonPathsMap(
    const std::map<NYTree::TYPath, TValue>& map,
    NYson::IYsonConsumer* consumer,
    const std::function<void(const TValue&, NYson::IYsonConsumer*)>& valueSerializer);

////////////////////////////////////////////////////////////////////////////////

} // namespace NYT

#define STATISTICS_INL_H_
#include "statistics-inl.h"
#undef STATISTICS_INL_H_