summaryrefslogtreecommitdiffstats
path: root/ydb/core/load_test/archive.cpp
blob: a7bf0ab0504f774dd7efbb04c85aaab417c7cd99 (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
#include "archive.h"

#include "percentile.h"

#include <util/generic/vector.h>
#include <util/generic/xrange.h>
#include <util/string/cast.h>
#include <util/string/join.h>
#include <util/string/split.h>

#include <utility>

namespace NKikimr {

static constexpr TStringBuf kResultTablePath = ".load_test_archive";

namespace {

using TColumnDescription = TVector<std::pair<TString, TString>>;

const TColumnDescription BuildTableColumns() {
    TColumnDescription columns;
    columns.emplace_back("id", "String");
    for (const auto& name : {"start", "finish"}) {
        columns.emplace_back(name, "Datetime");
    }
    columns.emplace_back("total_nodes", "Uint32");
    columns.emplace_back("success_nodes", "Uint32");

    auto addStatsColumn = [&columns](const TString& name, const TString& typeName) {
        for (const auto& suffix : {"_min", "_avg", "_max"}) {
            columns.emplace_back(name + suffix, typeName);
        }
    };
    addStatsColumn("transactions", "Uint64");
    addStatsColumn("transactions_per_sec", "Double");
    addStatsColumn("errors_per_sec", "Double");
    for (ui32 level : xrange(EPL_COUNT_NUM)) {
        addStatsColumn("p" + ToString(static_cast<EPercentileLevel>(level)) + "_ms", "Double");
    }
    columns.emplace_back("config", "String");
    return columns;
}

const TColumnDescription& GetTableColumns() {
    static const TColumnDescription kColumns = BuildTableColumns();
    return kColumns;
}

const TVector<TString> BuildTableColumnNames() {
    TVector<TString> names;
    for (const auto& [name, _] : GetTableColumns()) {
        names.push_back(name);
    }
    return names;
}

const TVector<TString> GetTableColumnNames() {
    static const TVector<TString> kNames = BuildTableColumnNames();
    return kNames;
}

TString DatetimeFromInstant(TInstant instant) {
    return instant.FormatGmTime("Datetime(\"%Y-%m-%dT%H:%M:%SZ\")");
}

TString EscapeQuotes(const TString& rawValue) {
    TVector<TString> parts;
    Split(rawValue, "\"", parts);
    return JoinSeq("\\\"", parts);
}

}  // anonymous namespace

TString MakeTableCreationYql() {
    TVector<TString> schemaParts;
    for (const auto& [name, typeName] : GetTableColumns()) {
        schemaParts.push_back(name + " " + typeName);
    };
    schemaParts.push_back("PRIMARY KEY(id)");

    TStringStream ss;
    ss << "--!syntax_v1\n";
    ss << "CREATE TABLE `" << kResultTablePath << "` ";
    ss << "(" << JoinSeq(", ", schemaParts) << ")";
    return ss.Str();
}

TString MakeRecordInsertionYql(const TVector<TAggregatedResult>& items) {
    TStringStream ss;
    ss << "--!syntax_v1\n";
    ss << "INSERT INTO `" << kResultTablePath << "` ";
    ss << "(" << JoinSeq(", ", GetTableColumnNames()) << ") ";
    ss << "VALUES ";

    bool first = true;
    for (const auto& item : items) {
        if (first) {
            first = false;
        } else {
            ss << ", ";
        }
        ss << "(\"" << item.Uuid << "\", " <<
            DatetimeFromInstant(item.Start) << ", " <<
            DatetimeFromInstant(item.Finish) << ", " <<
            item.Stats.TotalNodes << ", " <<
            item.Stats.SuccessNodes << ", " <<
            item.Stats.Transactions << ", " <<
            item.Stats.TransactionsPerSecond << ", " <<
            item.Stats.ErrorsPerSecond << ", ";
        for (ui32 level : xrange(EPL_COUNT_NUM)) {
            ss << item.Stats.Percentiles[level] << ", ";
        }
        ss << "\"" << EscapeQuotes(item.Config) << "\")";
    }
    ss << ";";
    return ss.Str();
}

TString MakeRecordSelectionYql(int limit) {
    TStringStream ss;
    ss << "--!syntax_v1\n";
    ss << "SELECT * FROM `" << kResultTablePath << "` ";
    ss << "ORDER BY `start` DESC ";
    ss << "LIMIT " << limit;
    return ss.Str();
}

}  // namespace NKikimr