]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #pragma once | |
5 | ||
6 | #include "include/utime.h" | |
7 | #include "common/Formatter.h" | |
8 | ||
9 | #include <stack> | |
10 | #include <vector> | |
11 | #include <boost/circular_buffer.hpp> | |
12 | ||
9f95a23c TL |
13 | class PGStateHistory; |
14 | ||
15 | struct EpochSource { | |
16 | virtual epoch_t get_osdmap_epoch() const = 0; | |
17 | virtual ~EpochSource() {} | |
18 | }; | |
19 | ||
20 | struct NamedState { | |
21 | PGStateHistory *pgsh; | |
22 | const char *state_name; | |
23 | utime_t enter_time; | |
24 | const char *get_state_name() { return state_name; } | |
25 | NamedState( | |
26 | PGStateHistory *pgsh, | |
27 | const char *state_name_); | |
28 | virtual ~NamedState(); | |
29 | }; | |
30 | ||
31 | using state_history_entry = std::tuple<utime_t, utime_t, const char*>; | |
32 | using embedded_state = std::pair<utime_t, const char*>; | |
33 | ||
34 | struct PGStateInstance { | |
35 | // Time spent in pg states | |
36 | ||
37 | void setepoch(const epoch_t current_epoch) { | |
38 | this_epoch = current_epoch; | |
39 | } | |
40 | ||
41 | void enter_state(const utime_t entime, const char* state) { | |
42 | embedded_states.push(std::make_pair(entime, state)); | |
43 | } | |
44 | ||
45 | void exit_state(const utime_t extime) { | |
46 | embedded_state this_state = embedded_states.top(); | |
47 | state_history.push_back(state_history_entry{ | |
48 | this_state.first, extime, this_state.second}); | |
49 | embedded_states.pop(); | |
50 | } | |
51 | ||
52 | bool empty() const { | |
53 | return embedded_states.empty(); | |
54 | } | |
55 | ||
56 | epoch_t this_epoch; | |
57 | std::vector<state_history_entry> state_history; | |
58 | std::stack<embedded_state> embedded_states; | |
59 | }; | |
60 | ||
61 | class PGStateHistory { | |
62 | public: | |
63 | PGStateHistory(const EpochSource &es) : buffer(10), es(es) {} | |
64 | ||
65 | void enter(const utime_t entime, const char* state); | |
66 | ||
67 | void exit(const char* state); | |
68 | ||
69 | void reset() { | |
70 | buffer.push_back(std::move(pi)); | |
71 | pi = nullptr; | |
72 | } | |
73 | ||
f67539c2 | 74 | void dump(ceph::Formatter* f) const; |
9f95a23c TL |
75 | |
76 | const char *get_current_state() const { | |
77 | if (pi == nullptr) return "unknown"; | |
78 | return std::get<1>(pi->embedded_states.top()); | |
79 | } | |
80 | ||
81 | private: | |
82 | std::unique_ptr<PGStateInstance> pi; | |
83 | boost::circular_buffer<std::unique_ptr<PGStateInstance>> buffer; | |
84 | const EpochSource &es; | |
85 | }; |