]> git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/os/seastore/onode_manager/staged-fltree/super.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / crimson / os / seastore / onode_manager / staged-fltree / super.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #pragma once
5
6 #include <memory>
7
8 #include "crimson/common/type_helpers.h"
9
10 #include "fwd.h"
11
12 namespace crimson::os::seastore::onode {
13
14 class Node;
15 class Super;
16
17 /**
18 * RootNodeTracker
19 *
20 * An abstracted tracker to get the root node by Transaction.
21 */
22 class RootNodeTracker {
23 public:
24 virtual ~RootNodeTracker() = default;
25 virtual bool is_clean() const = 0;
26 virtual Ref<Node> get_root(Transaction&) const = 0;
27 static RootNodeTrackerURef create(bool read_isolated);
28 protected:
29 RootNodeTracker() = default;
30 RootNodeTracker(const RootNodeTracker&) = delete;
31 RootNodeTracker(RootNodeTracker&&) = delete;
32 RootNodeTracker& operator=(const RootNodeTracker&) = delete;
33 RootNodeTracker& operator=(RootNodeTracker&&) = delete;
34 virtual void do_track_super(Transaction&, Super&) = 0;
35 virtual void do_untrack_super(Transaction&, Super&) = 0;
36 friend class Super;
37 };
38
39 /**
40 * Super
41 *
42 * The parent of root node. It contains the relationship between a Transaction
43 * and a root node address.
44 */
45 class Super {
46 public:
47 using URef = std::unique_ptr<Super>;
48 Super(const Super&) = delete;
49 Super(Super&&) = delete;
50 Super& operator=(const Super&) = delete;
51 Super& operator=(Super&&) = delete;
52 virtual ~Super() {
53 assert(tracked_root_node == nullptr);
54 tracker.do_untrack_super(t, *this);
55 }
56
57 virtual laddr_t get_root_laddr() const = 0;
58 virtual void write_root_laddr(context_t, laddr_t) = 0;
59
60 void do_track_root(Node& root) {
61 assert(tracked_root_node == nullptr);
62 tracked_root_node = &root;
63 }
64 void do_untrack_root(Node& root) {
65 assert(tracked_root_node == &root);
66 tracked_root_node = nullptr;
67 }
68 Node* get_p_root() const {
69 assert(tracked_root_node != nullptr);
70 return tracked_root_node;
71 }
72
73 protected:
74 Super(Transaction& t, RootNodeTracker& tracker)
75 : t{t}, tracker{tracker} {
76 tracker.do_track_super(t, *this);
77 }
78
79 private:
80 Transaction& t;
81 RootNodeTracker& tracker;
82 Node* tracked_root_node = nullptr;
83 };
84
85 /**
86 * RootNodeTrackerIsolated
87 *
88 * A concrete RootNodeTracker implementation which provides root node isolation
89 * between Transactions for Seastore backend.
90 */
91 class RootNodeTrackerIsolated final : public RootNodeTracker {
92 public:
93 ~RootNodeTrackerIsolated() override { assert(is_clean()); }
94 protected:
95 bool is_clean() const override {
96 return tracked_supers.empty();
97 }
98 void do_track_super(Transaction& t, Super& super) override {
99 assert(tracked_supers.find(&t) == tracked_supers.end());
100 tracked_supers[&t] = &super;
101 }
102 void do_untrack_super(Transaction& t, Super& super) override {
103 [[maybe_unused]] auto removed = tracked_supers.erase(&t);
104 assert(removed);
105 }
106 ::Ref<Node> get_root(Transaction& t) const override;
107 std::map<Transaction*, Super*> tracked_supers;
108 };
109
110 /**
111 * RootNodeTrackerShared
112 *
113 * A concrete RootNodeTracker implementation which has no isolation between
114 * Transactions for Dummy backend.
115 */
116 class RootNodeTrackerShared final : public RootNodeTracker {
117 public:
118 ~RootNodeTrackerShared() override { assert(is_clean()); }
119 protected:
120 bool is_clean() const override {
121 return tracked_super == nullptr;
122 }
123 void do_track_super(Transaction&, Super& super) override {
124 assert(is_clean());
125 tracked_super = &super;
126 }
127 void do_untrack_super(Transaction&, Super& super) override {
128 assert(tracked_super == &super);
129 tracked_super = nullptr;
130 }
131 ::Ref<Node> get_root(Transaction&) const override;
132 Super* tracked_super = nullptr;
133 };
134
135 inline RootNodeTrackerURef RootNodeTracker::create(bool read_isolated) {
136 if (read_isolated) {
137 return RootNodeTrackerURef(new RootNodeTrackerIsolated());
138 } else {
139 return RootNodeTrackerURef(new RootNodeTrackerShared());
140 }
141 }
142
143 }