1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
6 #include "include/utime.h"
7 #include "common/Formatter.h"
11 #include <boost/circular_buffer.hpp>
16 virtual epoch_t
get_osdmap_epoch() const = 0;
17 virtual ~EpochSource() {}
22 const char *state_name
;
24 const char *get_state_name() { return state_name
; }
27 const char *state_name_
);
28 virtual ~NamedState();
31 using state_history_entry
= std::tuple
<utime_t
, utime_t
, const char*>;
32 using embedded_state
= std::pair
<utime_t
, const char*>;
34 struct PGStateInstance
{
35 // Time spent in pg states
37 void setepoch(const epoch_t current_epoch
) {
38 this_epoch
= current_epoch
;
41 void enter_state(const utime_t entime
, const char* state
) {
42 embedded_states
.push(std::make_pair(entime
, state
));
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();
53 return embedded_states
.empty();
57 std::vector
<state_history_entry
> state_history
;
58 std::stack
<embedded_state
> embedded_states
;
61 class PGStateHistory
{
63 PGStateHistory(const EpochSource
&es
) : buffer(10), es(es
) {}
65 void enter(const utime_t entime
, const char* state
);
67 void exit(const char* state
);
70 buffer
.push_back(std::move(pi
));
74 void dump(ceph::Formatter
* f
) const;
76 const char *get_current_state() const {
77 if (pi
== nullptr) return "unknown";
78 return std::get
<1>(pi
->embedded_states
.top());
82 std::unique_ptr
<PGStateInstance
> pi
;
83 boost::circular_buffer
<std::unique_ptr
<PGStateInstance
>> buffer
;
84 const EpochSource
&es
;