@@ -27,19 +27,6 @@ namespace bustub {
27
27
28
28
auto TransactionManager::UpdateUndoLink (RID rid, std::optional<UndoLink> prev_link,
29
29
std::function<bool (std::optional<UndoLink>)> &&check) -> bool {
30
- std::function<bool (std::optional<VersionUndoLink>)> wrapper_func =
31
- [check](std::optional<VersionUndoLink> link) -> bool {
32
- if (link.has_value ()) {
33
- return check (link->prev_ );
34
- }
35
- return check (std::nullopt);
36
- };
37
- return UpdateVersionLink (rid, prev_link.has_value () ? std::make_optional (VersionUndoLink{*prev_link}) : std::nullopt,
38
- check != nullptr ? wrapper_func : nullptr );
39
- }
40
-
41
- auto TransactionManager::UpdateVersionLink (RID rid, std::optional<VersionUndoLink> prev_version,
42
- std::function<bool (std::optional<VersionUndoLink>)> &&check) -> bool {
43
30
std::unique_lock<std::shared_mutex> lck (version_info_mutex_);
44
31
std::shared_ptr<PageVersionInfo> pg_ver_info = nullptr ;
45
32
auto iter = version_info_.find (rid.GetPageId ());
@@ -51,8 +38,8 @@ auto TransactionManager::UpdateVersionLink(RID rid, std::optional<VersionUndoLin
51
38
}
52
39
std::unique_lock<std::shared_mutex> lck2 (pg_ver_info->mutex_ );
53
40
lck.unlock ();
54
- auto iter2 = pg_ver_info->prev_version_ .find (rid.GetSlotNum ());
55
- if (iter2 == pg_ver_info->prev_version_ .end ()) {
41
+ auto iter2 = pg_ver_info->prev_link_ .find (rid.GetSlotNum ());
42
+ if (iter2 == pg_ver_info->prev_link_ .end ()) {
56
43
if (check != nullptr && !check (std::nullopt)) {
57
44
return false ;
58
45
}
@@ -61,15 +48,15 @@ auto TransactionManager::UpdateVersionLink(RID rid, std::optional<VersionUndoLin
61
48
return false ;
62
49
}
63
50
}
64
- if (prev_version .has_value ()) {
65
- pg_ver_info->prev_version_ [rid.GetSlotNum ()] = *prev_version ;
51
+ if (prev_link .has_value ()) {
52
+ pg_ver_info->prev_link_ [rid.GetSlotNum ()] = *prev_link ;
66
53
} else {
67
- pg_ver_info->prev_version_ .erase (rid.GetSlotNum ());
54
+ pg_ver_info->prev_link_ .erase (rid.GetSlotNum ());
68
55
}
69
56
return true ;
70
57
}
71
58
72
- auto TransactionManager::GetVersionLink (RID rid) -> std::optional<VersionUndoLink > {
59
+ auto TransactionManager::GetUndoLink (RID rid) -> std::optional<UndoLink > {
73
60
std::shared_lock<std::shared_mutex> lck (version_info_mutex_);
74
61
auto iter = version_info_.find (rid.GetPageId ());
75
62
if (iter == version_info_.end ()) {
@@ -78,21 +65,13 @@ auto TransactionManager::GetVersionLink(RID rid) -> std::optional<VersionUndoLin
78
65
std::shared_ptr<PageVersionInfo> pg_ver_info = iter->second ;
79
66
std::unique_lock<std::shared_mutex> lck2 (pg_ver_info->mutex_ );
80
67
lck.unlock ();
81
- auto iter2 = pg_ver_info->prev_version_ .find (rid.GetSlotNum ());
82
- if (iter2 == pg_ver_info->prev_version_ .end ()) {
68
+ auto iter2 = pg_ver_info->prev_link_ .find (rid.GetSlotNum ());
69
+ if (iter2 == pg_ver_info->prev_link_ .end ()) {
83
70
return std::nullopt;
84
71
}
85
72
return std::make_optional (iter2->second );
86
73
}
87
74
88
- auto TransactionManager::GetUndoLink (RID rid) -> std::optional<UndoLink> {
89
- auto version_link = GetVersionLink (rid);
90
- if (version_link.has_value ()) {
91
- return version_link->prev_ ;
92
- }
93
- return std::nullopt;
94
- }
95
-
96
75
auto TransactionManager::GetUndoLogOptional (UndoLink link) -> std::optional<UndoLog> {
97
76
std::shared_lock<std::shared_mutex> lck (txn_map_mutex_);
98
77
auto iter = txn_map_.find (link.prev_txn_ );
@@ -122,4 +101,36 @@ void Transaction::SetTainted() {
122
101
std::terminate ();
123
102
}
124
103
104
+ auto UpdateTupleAndUndoLink (
105
+ TransactionManager *txn_mgr, RID rid, std::optional<UndoLink> undo_link, TableHeap *table_heap, Transaction *txn,
106
+ const TupleMeta &meta, const Tuple &tuple,
107
+ std::function<bool (const TupleMeta &meta, const Tuple &tuple, RID rid, std::optional<UndoLink>)> &&check) -> bool {
108
+ auto page_write_guard = table_heap->AcquireTablePageWriteLock (rid);
109
+ auto page = page_write_guard.AsMut <TablePage>();
110
+
111
+ auto [base_meta, base_tuple] = page->GetTuple (rid);
112
+ if (check != nullptr && !check (base_meta, base_tuple, rid, undo_link)) {
113
+ return false ;
114
+ }
115
+
116
+ // Update tuple and tupleMeta if pass in tuple and meta are different
117
+ if (meta != base_meta || !IsTupleContentEqual (tuple, base_tuple)) {
118
+ table_heap->UpdateTupleInPlaceWithLockAcquired (meta, tuple, rid, page);
119
+ }
120
+
121
+ txn_mgr->UpdateUndoLink (rid, undo_link);
122
+
123
+ return true ;
124
+ }
125
+
126
+ auto GetTupleAndUndoLink (TransactionManager *txn_mgr, TableHeap *table_heap, RID rid)
127
+ -> std::tuple<TupleMeta, Tuple, std::optional<UndoLink>> {
128
+ auto page_read_guard = table_heap->AcquireTablePageReadLock (rid);
129
+ auto page = page_read_guard.As <TablePage>();
130
+ auto [meta, tuple] = page->GetTuple (rid);
131
+
132
+ auto undo_link = txn_mgr->GetUndoLink (rid);
133
+ return std::make_tuple (meta, tuple, undo_link);
134
+ }
135
+
125
136
} // namespace bustub
0 commit comments