1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
2 // vim: ts=8 sw=2 smarttab
8 #include "crimson/common/type_helpers.h"
12 namespace crimson::os::seastore::onode
{
20 * An abstracted tracker to get the root node by Transaction.
22 class RootNodeTracker
{
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
);
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;
42 * The parent of root node. It contains the relationship between a Transaction
43 * and a root node address.
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;
53 assert(tracked_root_node
== nullptr);
54 tracker
.do_untrack_super(t
, *this);
57 virtual laddr_t
get_root_laddr() const = 0;
58 virtual void write_root_laddr(context_t
, laddr_t
) = 0;
60 void do_track_root(Node
& root
) {
61 assert(tracked_root_node
== nullptr);
62 tracked_root_node
= &root
;
64 void do_untrack_root(Node
& root
) {
65 assert(tracked_root_node
== &root
);
66 tracked_root_node
= nullptr;
68 Node
* get_p_root() const {
69 assert(tracked_root_node
!= nullptr);
70 return tracked_root_node
;
74 Super(Transaction
& t
, RootNodeTracker
& tracker
)
75 : t
{t
}, tracker
{tracker
} {
76 tracker
.do_track_super(t
, *this);
81 RootNodeTracker
& tracker
;
82 Node
* tracked_root_node
= nullptr;
86 * RootNodeTrackerIsolated
88 * A concrete RootNodeTracker implementation which provides root node isolation
89 * between Transactions for Seastore backend.
91 class RootNodeTrackerIsolated final
: public RootNodeTracker
{
93 ~RootNodeTrackerIsolated() override
{ assert(is_clean()); }
95 bool is_clean() const override
{
96 return tracked_supers
.empty();
98 void do_track_super(Transaction
& t
, Super
& super
) override
{
99 assert(tracked_supers
.find(&t
) == tracked_supers
.end());
100 tracked_supers
[&t
] = &super
;
102 void do_untrack_super(Transaction
& t
, Super
& super
) override
{
103 [[maybe_unused
]] auto removed
= tracked_supers
.erase(&t
);
106 ::Ref
<Node
> get_root(Transaction
& t
) const override
;
107 std::map
<Transaction
*, Super
*> tracked_supers
;
111 * RootNodeTrackerShared
113 * A concrete RootNodeTracker implementation which has no isolation between
114 * Transactions for Dummy backend.
116 class RootNodeTrackerShared final
: public RootNodeTracker
{
118 ~RootNodeTrackerShared() override
{ assert(is_clean()); }
120 bool is_clean() const override
{
121 return tracked_super
== nullptr;
123 void do_track_super(Transaction
&, Super
& super
) override
{
125 tracked_super
= &super
;
127 void do_untrack_super(Transaction
&, Super
& super
) override
{
128 assert(tracked_super
== &super
);
129 tracked_super
= nullptr;
131 ::Ref
<Node
> get_root(Transaction
&) const override
;
132 Super
* tracked_super
= nullptr;
135 inline RootNodeTrackerURef
RootNodeTracker::create(bool read_isolated
) {
137 return RootNodeTrackerURef(new RootNodeTrackerIsolated());
139 return RootNodeTrackerURef(new RootNodeTrackerShared());