WRITE_CLASS_ENCODER(PastIntervals::pg_interval_t)
-class pi_simple_rep : public PastIntervals::interval_rep {
- map<epoch_t, PastIntervals::pg_interval_t> interval_map;
-
- pi_simple_rep(
- bool ec_pool,
- std::list<PastIntervals::pg_interval_t> &&intervals) {
- for (auto &&i: intervals)
- add_interval(ec_pool, i);
- }
-
-public:
- pi_simple_rep() = default;
- pi_simple_rep(const pi_simple_rep &) = default;
- pi_simple_rep(pi_simple_rep &&) = default;
- pi_simple_rep &operator=(pi_simple_rep &&) = default;
- pi_simple_rep &operator=(const pi_simple_rep &) = default;
-
- size_t size() const override { return interval_map.size(); }
- bool empty() const override { return interval_map.empty(); }
- void clear() override { interval_map.clear(); }
- pair<epoch_t, epoch_t> get_bounds() const override {
- auto iter = interval_map.begin();
- if (iter != interval_map.end()) {
- auto riter = interval_map.rbegin();
- return make_pair(
- iter->second.first,
- riter->second.last + 1);
- } else {
- return make_pair(0, 0);
- }
- }
- set<pg_shard_t> get_all_participants(
- bool ec_pool) const override {
- set<pg_shard_t> all_participants;
-
- // We need to decide who might have unfound objects that we need
- auto p = interval_map.rbegin();
- auto end = interval_map.rend();
- for (; p != end; ++p) {
- const PastIntervals::pg_interval_t &interval(p->second);
- // If nothing changed, we don't care about this interval.
- if (!interval.maybe_went_rw)
- continue;
-
- int i = 0;
- std::vector<int>::const_iterator a = interval.acting.begin();
- std::vector<int>::const_iterator a_end = interval.acting.end();
- for (; a != a_end; ++a, ++i) {
- pg_shard_t shard(*a, ec_pool ? shard_id_t(i) : shard_id_t::NO_SHARD);
- if (*a != CRUSH_ITEM_NONE)
- all_participants.insert(shard);
- }
- }
- return all_participants;
- }
- void add_interval(
- bool ec_pool,
- const PastIntervals::pg_interval_t &interval) override {
- interval_map[interval.first] = interval;
- }
- unique_ptr<PastIntervals::interval_rep> clone() const override {
- return unique_ptr<PastIntervals::interval_rep>(new pi_simple_rep(*this));
- }
- ostream &print(ostream &out) const override {
- return out << interval_map;
- }
- void encode(bufferlist &bl) const override {
- ::encode(interval_map, bl);
- }
- void decode(bufferlist::iterator &bl) override {
- ::decode(interval_map, bl);
- }
- void dump(Formatter *f) const override {
- f->open_array_section("PastIntervals::compat_rep");
- for (auto &&i: interval_map) {
- f->open_object_section("pg_interval_t");
- f->dump_int("epoch", i.first);
- f->open_object_section("interval");
- i.second.dump(f);
- f->close_section();
- f->close_section();
- }
- f->close_section();
- }
- bool is_classic() const override {
- return true;
- }
- static void generate_test_instances(list<pi_simple_rep*> &o) {
- using ival = PastIntervals::pg_interval_t;
- using ivallst = std::list<ival>;
- o.push_back(
- new pi_simple_rep(
- true, ivallst
- { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0}
- , ival{{ 1, 2}, { 1, 2}, 21, 30, true, 1, 1}
- , ival{{ 2}, { 2}, 31, 35, false, 2, 2}
- , ival{{0, 2}, {0, 2}, 36, 50, true, 0, 0}
- }));
- o.push_back(
- new pi_simple_rep(
- false, ivallst
- { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0}
- , ival{{ 1, 2}, { 1, 2}, 20, 30, true, 1, 1}
- , ival{{ 2}, { 2}, 31, 35, false, 2, 2}
- , ival{{0, 2}, {0, 2}, 36, 50, true, 0, 0}
- }));
- o.push_back(
- new pi_simple_rep(
- true, ivallst
- { ival{{2, 1, 0}, {2, 1, 0}, 10, 20, true, 1, 1}
- , ival{{ 0, 2}, { 0, 2}, 21, 30, true, 0, 0}
- , ival{{ 0, 2}, {2, 0}, 31, 35, true, 2, 2}
- , ival{{ 0, 2}, { 0, 2}, 36, 50, true, 0, 0}
- }));
- return;
- }
- void iterate_mayberw_back_to(
- bool ec_pool,
- epoch_t les,
- std::function<void(epoch_t, const set<pg_shard_t> &)> &&f) const override {
- for (auto i = interval_map.rbegin(); i != interval_map.rend(); ++i) {
- if (!i->second.maybe_went_rw)
- continue;
- if (i->second.last < les)
- break;
- set<pg_shard_t> actingset;
- for (unsigned j = 0; j < i->second.acting.size(); ++j) {
- if (i->second.acting[j] == CRUSH_ITEM_NONE)
- continue;
- actingset.insert(
- pg_shard_t(
- i->second.acting[j],
- ec_pool ? shard_id_t(j) : shard_id_t::NO_SHARD));
- }
- f(i->second.first, actingset);
- }
- }
-
- bool has_full_intervals() const override { return true; }
- void iterate_all_intervals(
- std::function<void(const PastIntervals::pg_interval_t &)> &&f
- ) const override {
- for (auto &&i: interval_map) {
- f(i.second);
- }
- }
- virtual ~pi_simple_rep() override {}
-};
/**
* pi_compact_rep
f->close_section();
f->close_section();
}
- bool is_classic() const override {
- return false;
- }
static void generate_test_instances(list<pi_compact_rep*> &o) {
using ival = PastIntervals::pg_interval_t;
using ivallst = std::list<ival>;
};
WRITE_CLASS_ENCODER(pi_compact_rep)
+PastIntervals::PastIntervals()
+{
+ past_intervals.reset(new pi_compact_rep);
+}
+
PastIntervals::PastIntervals(const PastIntervals &rhs)
: past_intervals(rhs.past_intervals ?
rhs.past_intervals->clone() :
case 0:
break;
case 1:
- past_intervals.reset(new pi_simple_rep);
- past_intervals->decode(bl);
+ assert(0 == "pi_simple_rep support removed post-luminous");
break;
case 2:
past_intervals.reset(new pi_compact_rep);
DECODE_FINISH(bl);
}
-void PastIntervals::decode_classic(bufferlist::iterator &bl)
-{
- past_intervals.reset(new pi_simple_rep);
- past_intervals->decode(bl);
-}
-
void PastIntervals::generate_test_instances(list<PastIntervals*> &o)
{
- {
- list<pi_simple_rep *> simple;
- pi_simple_rep::generate_test_instances(simple);
- for (auto &&i: simple) {
- // takes ownership of contents
- o.push_back(new PastIntervals(i));
- }
- }
{
list<pi_compact_rep *> compact;
pi_compact_rep::generate_test_instances(compact);
return;
}
-void PastIntervals::update_type(bool ec_pool, bool compact)
-{
- if (!compact) {
- if (!past_intervals) {
- past_intervals.reset(new pi_simple_rep);
- } else {
- // we never convert from compact back to classic
- assert(is_classic());
- }
- } else {
- if (!past_intervals) {
- past_intervals.reset(new pi_compact_rep);
- } else if (is_classic()) {
- auto old = std::move(past_intervals);
- past_intervals.reset(new pi_compact_rep);
- assert(old->has_full_intervals());
- old->iterate_all_intervals([&](const pg_interval_t &i) {
- past_intervals->add_interval(ec_pool, i);
- });
- }
- }
-}
-
-void PastIntervals::update_type_from_map(bool ec_pool, const OSDMap &osdmap)
-{
- update_type(ec_pool, osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS);
-}
-
bool PastIntervals::is_new_interval(
int old_acting_primary,
int new_acting_primary,
static void generate_test_instances(list<pg_interval_t*>& o);
};
- PastIntervals() = default;
- PastIntervals(bool ec_pool, const OSDMap &osdmap) : PastIntervals() {
- update_type_from_map(ec_pool, osdmap);
- }
- PastIntervals(bool ec_pool, bool compact) : PastIntervals() {
- update_type(ec_pool, compact);
- }
+ PastIntervals();
PastIntervals(PastIntervals &&rhs) = default;
PastIntervals &operator=(PastIntervals &&rhs) = default;
virtual void encode(bufferlist &bl) const = 0;
virtual void decode(bufferlist::iterator &bl) = 0;
virtual void dump(Formatter *f) const = 0;
- virtual bool is_classic() const = 0;
virtual void iterate_mayberw_back_to(
bool ec_pool,
epoch_t les,
virtual ~interval_rep() {}
};
- friend class pi_simple_rep;
friend class pi_compact_rep;
private:
return past_intervals->add_interval(ec_pool, interval);
}
- bool is_classic() const {
- assert(past_intervals);
- return past_intervals->is_classic();
- }
-
void encode(bufferlist &bl) const {
ENCODE_START(1, 1, bl);
if (past_intervals) {
- __u8 type = is_classic() ? 1 : 2;
+ __u8 type = 2;
::encode(type, bl);
past_intervals->encode(bl);
} else {
}
ENCODE_FINISH(bl);
}
- void encode_classic(bufferlist &bl) const {
- if (past_intervals) {
- assert(past_intervals->is_classic());
- past_intervals->encode(bl);
- } else {
- // it's a map<>
- ::encode((uint32_t)0, bl);
- }
- }
void decode(bufferlist::iterator &bl);
- void decode_classic(bufferlist::iterator &bl);
void dump(Formatter *f) const {
assert(past_intervals);
friend class PastIntervals;
};
- void update_type(bool ec_pool, bool compact);
- void update_type_from_map(bool ec_pool, const OSDMap &osdmap);
-
template <typename... Args>
PriorSet get_prior_set(Args&&... args) const {
return PriorSet(*this, std::forward<Args>(args)...);
{
// iterate through all 4 combinations
for (unsigned i = 0; i < 4; ++i) {
- bool compact = i & 1;
- bool ec_pool = i & 2;
//
// Create a situation where osdmaps are the same so that
// each test case can diverge from it using minimal code.
// being split
//
{
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ASSERT_TRUE(past_intervals.empty());
ASSERT_FALSE(PastIntervals::check_new_interval(old_primary,
int _new_primary = osd_id + 1;
new_acting.push_back(_new_primary);
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ASSERT_TRUE(past_intervals.empty());
ASSERT_TRUE(PastIntervals::check_new_interval(old_primary,
int _new_primary = osd_id + 1;
new_up.push_back(_new_primary);
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ASSERT_TRUE(past_intervals.empty());
ASSERT_TRUE(PastIntervals::check_new_interval(old_primary,
vector<int> new_up;
int _new_up_primary = osd_id + 1;
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ASSERT_TRUE(past_intervals.empty());
ASSERT_TRUE(PastIntervals::check_new_interval(old_primary,
inc.new_pools[pool_id].set_pg_num(new_pg_num);
osdmap->apply_incremental(inc);
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ASSERT_TRUE(past_intervals.empty());
ASSERT_TRUE(PastIntervals::check_new_interval(old_primary,
inc.new_pools[pool_id].set_pg_num(pg_num);
osdmap->apply_incremental(inc);
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ASSERT_TRUE(past_intervals.empty());
ASSERT_TRUE(PastIntervals::check_new_interval(old_primary,
{
vector<int> old_acting;
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ostringstream out;
ostringstream out;
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ASSERT_TRUE(past_intervals.empty());
ASSERT_TRUE(PastIntervals::check_new_interval(old_primary,
ostringstream out;
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ASSERT_TRUE(past_intervals.empty());
ASSERT_TRUE(PastIntervals::check_new_interval(old_primary,
ostringstream out;
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ASSERT_TRUE(past_intervals.empty());
ASSERT_TRUE(PastIntervals::check_new_interval(old_primary,
ostringstream out;
- PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact);
+ PastIntervals past_intervals;
ASSERT_TRUE(past_intervals.empty());
ASSERT_TRUE(PastIntervals::check_new_interval(old_primary,
pg_down,
new RequiredPredicate(rec_pred));
- PastIntervals simple, compact;
- simple.update_type(ec_pool, false);
- compact.update_type(ec_pool, true);
+ PastIntervals compact;
for (auto &&i: intervals) {
- simple.add_interval(ec_pool, i);
compact.add_interval(ec_pool, i);
}
- PI::PriorSet simple_ps = simple.get_prior_set(
- ec_pool,
- last_epoch_started,
- new RequiredPredicate(rec_pred),
- map_pred,
- up,
- acting,
- nullptr);
PI::PriorSet compact_ps = compact.get_prior_set(
ec_pool,
last_epoch_started,
up,
acting,
nullptr);
- ASSERT_EQ(correct, simple_ps);
ASSERT_EQ(correct, compact_ps);
}
};