crimson/common/operation: trim AggregateBlockingEvent::events entries

PglogBasedRecovery and BackfillRecovery reuse the same Operation
until their respective operations are complete.  Each recovery
operation adds an entry to AggregateBlockingEvent::events.  This
way, we only retain entries that are currently blocking.

Signed-off-by: Samuel Just <sjust@redhat.com>
This commit is contained in:
Samuel Just 2022-05-07 07:02:58 +00:00
parent d0708b5452
commit 29a00b4482

View File

@ -232,28 +232,58 @@ private:
template <class T> template <class T>
struct AggregateBlockingEvent { struct AggregateBlockingEvent {
struct TriggerI { struct TriggerI {
protected:
struct TriggerContainerI {
virtual typename T::TriggerI& get_trigger() = 0;
virtual ~TriggerContainerI() = default;
};
using TriggerContainerIRef = std::unique_ptr<TriggerContainerI>;
virtual TriggerContainerIRef create_part_trigger() = 0;
public:
template <class FutureT> template <class FutureT>
auto maybe_record_blocking(FutureT&& fut, auto maybe_record_blocking(FutureT&& fut,
const typename T::Blocker& blocker) { const typename T::Blocker& blocker) {
// AggregateBlockingEvent is supposed to be used on relatively cold // AggregateBlockingEvent is supposed to be used on relatively cold
// paths (recovery), so we don't need to worry about the dynamic // paths (recovery), so we don't need to worry about the dynamic
// polymothps / dynamic memory's overhead. // polymothps / dynamic memory's overhead.
return create_part_trigger()->maybe_record_blocking( auto tcont = create_part_trigger();
std::move(fut), blocker); return tcont->get_trigger().maybe_record_blocking(
std::move(fut), blocker
).finally([tcont=std::move(tcont)] {});
} }
virtual std::unique_ptr<typename T::TriggerI> create_part_trigger() = 0;
virtual ~TriggerI() = default; virtual ~TriggerI() = default;
}; };
template <class OpT> template <class OpT>
struct Trigger : TriggerI { struct Trigger final : TriggerI {
Trigger(AggregateBlockingEvent& event, const OpT& op) Trigger(AggregateBlockingEvent& event, const OpT& op)
: event(event), op(op) {} : event(event), op(op) {}
std::unique_ptr<typename T::TriggerI> create_part_trigger() override { class TriggerContainer final : public TriggerI::TriggerContainerI {
return std::make_unique<typename T::template Trigger<OpT>>( AggregateBlockingEvent& event;
event.events.emplace_back(), op); typename decltype(event.events)::iterator iter;
typename T::template Trigger<OpT> trigger;
typename T::TriggerI &get_trigger() final {
return trigger;
}
public:
TriggerContainer(AggregateBlockingEvent& _event, const OpT& op) :
event(_event),
iter(event.events.emplace(event.events.end())),
trigger(*iter, op) {}
~TriggerContainer() final {
event.events.erase(iter);
}
};
protected:
typename TriggerI::TriggerContainerIRef create_part_trigger() final {
return std::make_unique<TriggerContainer>(event, op);
} }
private: private: