]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_period_history.h
import ceph pacific 16.2.5
[ceph.git] / ceph / src / rgw / rgw_period_history.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #ifndef RGW_PERIOD_HISTORY_H
5 #define RGW_PERIOD_HISTORY_H
6
7 #include <deque>
8 #include <mutex>
9 #include <system_error>
10 #include <boost/intrusive/avl_set.hpp>
11 #include "include/ceph_assert.h"
12 #include "include/types.h"
13 #include "common/async/yield_context.h"
14 #include "common/dout.h"
15
16 namespace bi = boost::intrusive;
17
18 class RGWPeriod;
19
20 /**
21 * RGWPeriodHistory tracks the relative history of all inserted periods,
22 * coordinates the pulling of missing intermediate periods, and provides a
23 * Cursor object for traversing through the connected history.
24 */
25 class RGWPeriodHistory final {
26 private:
27 /// an ordered history of consecutive periods
28 class History;
29
30 // comparisons for avl_set ordering
31 friend bool operator<(const History& lhs, const History& rhs);
32 friend struct NewestEpochLess;
33
34 class Impl;
35 std::unique_ptr<Impl> impl;
36
37 public:
38 /**
39 * Puller is a synchronous interface for pulling periods from the master
40 * zone. The abstraction exists mainly to support unit testing.
41 */
42 class Puller {
43 public:
44 virtual ~Puller() = default;
45
46 virtual int pull(const DoutPrefixProvider *dpp, const std::string& period_id, RGWPeriod& period,
47 optional_yield y) = 0;
48 };
49
50 RGWPeriodHistory(CephContext* cct, Puller* puller,
51 const RGWPeriod& current_period);
52 ~RGWPeriodHistory();
53
54 /**
55 * Cursor tracks a position in the period history and allows forward and
56 * backward traversal. Only periods that are fully connected to the
57 * current_period are reachable via a Cursor, because other histories are
58 * temporary and can be merged away. Cursors to periods in disjoint
59 * histories, as provided by insert() or lookup(), are therefore invalid and
60 * their operator bool() will return false.
61 */
62 class Cursor final {
63 public:
64 Cursor() = default;
65 explicit Cursor(int error) : error(error) {}
66
67 int get_error() const { return error; }
68
69 /// return false for a default-constructed or error Cursor
70 operator bool() const { return history != nullptr; }
71
72 epoch_t get_epoch() const { return epoch; }
73 const RGWPeriod& get_period() const;
74
75 bool has_prev() const;
76 bool has_next() const;
77
78 void prev() { epoch--; }
79 void next() { epoch++; }
80
81 friend bool operator==(const Cursor& lhs, const Cursor& rhs);
82 friend bool operator!=(const Cursor& lhs, const Cursor& rhs);
83
84 private:
85 // private constructors for RGWPeriodHistory
86 friend class RGWPeriodHistory::Impl;
87
88 Cursor(const History* history, std::mutex* mutex, epoch_t epoch)
89 : history(history), mutex(mutex), epoch(epoch) {}
90
91 int error{0};
92 const History* history{nullptr};
93 std::mutex* mutex{nullptr};
94 epoch_t epoch{0}; //< realm epoch of cursor position
95 };
96
97 /// return a cursor to the current period
98 Cursor get_current() const;
99
100 /// build up a connected period history that covers the span between
101 /// current_period and the given period, reading predecessor periods or
102 /// fetching them from the master as necessary. returns a cursor at the
103 /// given period that can be used to traverse the current_history
104 Cursor attach(const DoutPrefixProvider *dpp, RGWPeriod&& period, optional_yield y);
105
106 /// insert the given period into an existing history, or create a new
107 /// unconnected history. similar to attach(), but it doesn't try to fetch
108 /// missing periods. returns a cursor to the inserted period iff it's in
109 /// the current_history
110 Cursor insert(RGWPeriod&& period);
111
112 /// search for a period by realm epoch, returning a valid Cursor iff it's in
113 /// the current_history
114 Cursor lookup(epoch_t realm_epoch);
115 };
116
117 #endif // RGW_PERIOD_HISTORY_H