]>
Commit | Line | Data |
---|---|---|
224ce89b WB |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2016 Red Hat Inc. | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
14 | ||
15 | ||
16 | #pragma once | |
17 | ||
18 | #include <ostream> | |
19 | ||
20 | #include "include/types.h" | |
21 | #include "include/utime.h" | |
22 | #include "osd/OpRequest.h" | |
23 | #include "osd/PG.h" | |
24 | ||
25 | ||
26 | class OSD; | |
27 | ||
28 | ||
29 | struct PGScrub { | |
30 | epoch_t epoch_queued; | |
31 | explicit PGScrub(epoch_t e) : epoch_queued(e) {} | |
32 | ostream &operator<<(ostream &rhs) { | |
33 | return rhs << "PGScrub"; | |
34 | } | |
35 | }; | |
36 | ||
37 | struct PGSnapTrim { | |
38 | epoch_t epoch_queued; | |
39 | explicit PGSnapTrim(epoch_t e) : epoch_queued(e) {} | |
40 | ostream &operator<<(ostream &rhs) { | |
41 | return rhs << "PGSnapTrim"; | |
42 | } | |
43 | }; | |
44 | ||
45 | struct PGRecovery { | |
46 | epoch_t epoch_queued; | |
47 | uint64_t reserved_pushes; | |
48 | PGRecovery(epoch_t e, uint64_t reserved_pushes) | |
49 | : epoch_queued(e), reserved_pushes(reserved_pushes) {} | |
50 | ostream &operator<<(ostream &rhs) { | |
51 | return rhs << "PGRecovery(epoch=" << epoch_queued | |
52 | << ", reserved_pushes: " << reserved_pushes << ")"; | |
53 | } | |
54 | }; | |
55 | ||
56 | ||
57 | class PGQueueable { | |
58 | typedef boost::variant< | |
59 | OpRequestRef, | |
60 | PGSnapTrim, | |
61 | PGScrub, | |
62 | PGRecovery | |
63 | > QVariant; | |
64 | QVariant qvariant; | |
65 | int cost; | |
66 | unsigned priority; | |
67 | utime_t start_time; | |
68 | entity_inst_t owner; | |
69 | epoch_t map_epoch; ///< an epoch we expect the PG to exist in | |
70 | ||
71 | struct RunVis : public boost::static_visitor<> { | |
72 | OSD *osd; | |
73 | PGRef &pg; | |
74 | ThreadPool::TPHandle &handle; | |
75 | RunVis(OSD *osd, PGRef &pg, ThreadPool::TPHandle &handle) | |
76 | : osd(osd), pg(pg), handle(handle) {} | |
77 | void operator()(const OpRequestRef &op); | |
78 | void operator()(const PGSnapTrim &op); | |
79 | void operator()(const PGScrub &op); | |
80 | void operator()(const PGRecovery &op); | |
81 | }; // struct RunVis | |
82 | ||
83 | struct StringifyVis : public boost::static_visitor<std::string> { | |
84 | std::string operator()(const OpRequestRef &op) { | |
85 | return stringify(op); | |
86 | } | |
87 | std::string operator()(const PGSnapTrim &op) { | |
88 | return "PGSnapTrim"; | |
89 | } | |
90 | std::string operator()(const PGScrub &op) { | |
91 | return "PGScrub"; | |
92 | } | |
93 | std::string operator()(const PGRecovery &op) { | |
94 | return "PGRecovery"; | |
95 | } | |
96 | }; | |
97 | ||
98 | friend ostream& operator<<(ostream& out, const PGQueueable& q) { | |
99 | StringifyVis v; | |
100 | return out << "PGQueueable(" << boost::apply_visitor(v, q.qvariant) | |
101 | << " prio " << q.priority << " cost " << q.cost | |
102 | << " e" << q.map_epoch << ")"; | |
103 | } | |
104 | ||
105 | public: | |
106 | ||
107 | PGQueueable(OpRequestRef op, epoch_t e) | |
108 | : qvariant(op), cost(op->get_req()->get_cost()), | |
109 | priority(op->get_req()->get_priority()), | |
110 | start_time(op->get_req()->get_recv_stamp()), | |
111 | owner(op->get_req()->get_source_inst()), | |
112 | map_epoch(e) | |
113 | {} | |
114 | PGQueueable( | |
115 | const PGSnapTrim &op, int cost, unsigned priority, utime_t start_time, | |
116 | const entity_inst_t &owner, epoch_t e) | |
117 | : qvariant(op), cost(cost), priority(priority), start_time(start_time), | |
118 | owner(owner), map_epoch(e) {} | |
119 | PGQueueable( | |
120 | const PGScrub &op, int cost, unsigned priority, utime_t start_time, | |
121 | const entity_inst_t &owner, epoch_t e) | |
122 | : qvariant(op), cost(cost), priority(priority), start_time(start_time), | |
123 | owner(owner), map_epoch(e) {} | |
124 | PGQueueable( | |
125 | const PGRecovery &op, int cost, unsigned priority, utime_t start_time, | |
126 | const entity_inst_t &owner, epoch_t e) | |
127 | : qvariant(op), cost(cost), priority(priority), start_time(start_time), | |
128 | owner(owner), map_epoch(e) {} | |
129 | ||
130 | const boost::optional<OpRequestRef> maybe_get_op() const { | |
131 | const OpRequestRef *op = boost::get<OpRequestRef>(&qvariant); | |
132 | return op ? OpRequestRef(*op) : boost::optional<OpRequestRef>(); | |
133 | } | |
134 | uint64_t get_reserved_pushes() const { | |
135 | const PGRecovery *op = boost::get<PGRecovery>(&qvariant); | |
136 | return op ? op->reserved_pushes : 0; | |
137 | } | |
138 | void run(OSD *osd, PGRef &pg, ThreadPool::TPHandle &handle) { | |
139 | RunVis v(osd, pg, handle); | |
140 | boost::apply_visitor(v, qvariant); | |
141 | } | |
142 | unsigned get_priority() const { return priority; } | |
143 | int get_cost() const { return cost; } | |
144 | utime_t get_start_time() const { return start_time; } | |
145 | entity_inst_t get_owner() const { return owner; } | |
146 | epoch_t get_map_epoch() const { return map_epoch; } | |
147 | const QVariant& get_variant() const { return qvariant; } | |
148 | }; // struct PGQueueable |