13
13
#pragma once
14
14
15
15
#include < cstring>
16
+ #include < optional>
17
+ #include < tuple>
18
+ #include < utility>
16
19
20
+ #include " common/config.h"
17
21
#include " common/rid.h"
18
22
#include " concurrency/lock_manager.h"
19
23
#include " recovery/log_manager.h"
20
24
#include " storage/page/page.h"
25
+ #include " storage/table/table_heap.h"
21
26
#include " storage/table/tuple.h"
22
27
23
- static constexpr uint64_t DELETE_MASK = (1U << (8 * sizeof (uint32_t ) - 1 ));
24
-
25
28
namespace bustub {
26
29
30
+ static constexpr uint64_t TABLE_PAGE_HEADER_SIZE = 8 ;
31
+
27
32
/* *
28
33
* Slotted page format:
29
34
* ---------------------------------------------------------
@@ -34,176 +39,66 @@ namespace bustub {
34
39
*
35
40
* Header format (size in bytes):
36
41
* ----------------------------------------------------------------------------
37
- * | PageId (4)| LSN (4)| PrevPageId (4)| NextPageId (4)| FreeSpacePointer(4 ) |
42
+ * | NextPageId (4)| NumTuples(2) | NumDeletedTuples(2 ) |
38
43
* ----------------------------------------------------------------------------
39
44
* ----------------------------------------------------------------
40
- * | TupleCount (4) | Tuple_1 offset (4) | Tuple_1 size (4) | ... |
45
+ * | Tuple_1 offset+size (4) | Tuple_2 offset+ size (4) | ... |
41
46
* ----------------------------------------------------------------
42
47
*
48
+ * Tuple format:
49
+ * | meta | data |
43
50
*/
44
- class TablePage : public Page {
51
+
52
+ class TablePage {
45
53
public:
46
54
/* *
47
55
* Initialize the TablePage header.
48
- * @param page_id the page ID of this table page
49
- * @param page_size the size of this table page
50
- * @param prev_page_id the previous table page ID
51
- * @param log_manager the log manager in use
52
- * @param txn the transaction that this page is created in
53
56
*/
54
- void Init (page_id_t page_id, uint32_t page_size, page_id_t prev_page_id, LogManager *log_manager, Transaction *txn);
55
-
56
- /* * @return the page ID of this table page */
57
- auto GetTablePageId () -> page_id_t { return *reinterpret_cast <page_id_t *>(GetData ()); }
57
+ void Init ();
58
58
59
- /* * @return the page ID of the previous table page */
60
- auto GetPrevPageId () -> page_id_t { return * reinterpret_cast < page_id_t *>( GetData () + OFFSET_PREV_PAGE_ID) ; }
59
+ /* * @return number of tuples in this page */
60
+ auto GetNumTuples () const -> uint32_t { return num_tuples_ ; }
61
61
62
62
/* * @return the page ID of the next table page */
63
- auto GetNextPageId () -> page_id_t { return *reinterpret_cast <page_id_t *>(GetData () + OFFSET_NEXT_PAGE_ID); }
64
-
65
- /* * Set the page id of the previous page in the table. */
66
- void SetPrevPageId (page_id_t prev_page_id) {
67
- memcpy (GetData () + OFFSET_PREV_PAGE_ID, &prev_page_id, sizeof (page_id_t ));
68
- }
63
+ auto GetNextPageId () const -> page_id_t { return next_page_id_; }
69
64
70
65
/* * Set the page id of the next page in the table. */
71
- void SetNextPageId (page_id_t next_page_id) {
72
- memcpy (GetData () + OFFSET_NEXT_PAGE_ID, &next_page_id, sizeof (page_id_t ));
73
- }
66
+ void SetNextPageId (page_id_t next_page_id) { next_page_id_ = next_page_id; }
67
+
68
+ /* * Get the next offset to insert, return nullopt if this tuple cannot fit in this page */
69
+ auto GetNextTupleOffset (const TupleMeta &meta, const Tuple &tuple) const -> std::optional<uint16_t>;
74
70
75
71
/* *
76
72
* Insert a tuple into the table.
77
73
* @param tuple tuple to insert
78
- * @param[out] rid rid of the inserted tuple
79
- * @param txn transaction performing the insert
80
- * @param lock_manager the lock manager
81
- * @param log_manager the log manager
82
74
* @return true if the insert is successful (i.e. there is enough space)
83
75
*/
84
- auto InsertTuple (const Tuple &tuple, RID *rid, Transaction *txn, LockManager *lock_manager, LogManager *log_manager)
85
- -> bool;
86
-
87
- /* *
88
- * Mark a tuple as deleted. This does not actually delete the tuple.
89
- * @param rid rid of the tuple to mark as deleted
90
- * @param txn transaction performing the delete
91
- * @param lock_manager the lock manager
92
- * @param log_manager the log manager
93
- * @return true if marking the tuple as deleted is successful (i.e the tuple exists)
94
- */
95
- auto MarkDelete (const RID &rid, Transaction *txn, LockManager *lock_manager, LogManager *log_manager) -> bool;
76
+ auto InsertTuple (const TupleMeta &meta, const Tuple &tuple) -> std::optional<uint16_t>;
96
77
97
78
/* *
98
79
* Update a tuple.
99
- * @param new_tuple new value of the tuple
100
- * @param[out] old_tuple old value of the tuple
101
- * @param rid rid of the tuple
102
- * @param txn transaction performing the update
103
- * @param lock_manager the lock manager
104
- * @param log_manager the log manager
105
- * @return true if updating the tuple succeeded
106
80
*/
107
- auto UpdateTuple (const Tuple &new_tuple, Tuple *old_tuple, const RID &rid, Transaction *txn,
108
- LockManager *lock_manager, LogManager *log_manager) -> bool;
109
-
110
- /* * To be called on commit or abort. Actually perform the delete or rollback an insert. */
111
- void ApplyDelete (const RID &rid, Transaction *txn, LogManager *log_manager);
112
-
113
- /* * To be called on abort. Rollback a delete, i.e. this reverses a MarkDelete. */
114
- void RollbackDelete (const RID &rid, Transaction *txn, LogManager *log_manager);
81
+ void UpdateTupleMeta (const TupleMeta &meta, const RID &rid);
115
82
116
83
/* *
117
84
* Read a tuple from a table.
118
- * @param rid rid of the tuple to read
119
- * @param[out] tuple the tuple that was read
120
- * @param txn transaction performing the read
121
- * @param lock_manager the lock manager
122
- * @return true if the read is successful (i.e. the tuple exists)
123
85
*/
124
- auto GetTuple (const RID &rid, Tuple *tuple, Transaction *txn, LockManager *lock_manager) -> bool;
125
-
126
- /* * @return the rid of the first tuple in this page */
86
+ auto GetTuple (const RID &rid) const -> std::pair<TupleMeta, Tuple>;
127
87
128
- /* *
129
- * @param[out] first_rid the RID of the first tuple in this page
130
- * @return true if the first tuple exists, false otherwise
131
- */
132
- auto GetFirstTupleRid (RID *first_rid) -> bool;
133
-
134
- /* *
135
- * @param cur_rid the RID of the current tuple
136
- * @param[out] next_rid the RID of the tuple following the current tuple
137
- * @return true if the next tuple exists, false otherwise
138
- */
139
- auto GetNextTupleRid (const RID &cur_rid, RID *next_rid) -> bool;
140
-
141
- private:
142
88
static_assert (sizeof (page_id_t ) == 4 );
143
89
144
- static constexpr size_t SIZE_TABLE_PAGE_HEADER = 24 ;
145
- static constexpr size_t SIZE_TUPLE = 8 ;
146
- static constexpr size_t OFFSET_PREV_PAGE_ID = 8 ;
147
- static constexpr size_t OFFSET_NEXT_PAGE_ID = 12 ;
148
- static constexpr size_t OFFSET_FREE_SPACE = 16 ;
149
- static constexpr size_t OFFSET_TUPLE_COUNT = 20 ;
150
- static constexpr size_t OFFSET_TUPLE_OFFSET = 24 ; // Naming things is hard.
151
- static constexpr size_t OFFSET_TUPLE_SIZE = 28 ;
152
-
153
- /* * @return pointer to the end of the current free space, see header comment */
154
- auto GetFreeSpacePointer () -> uint32_t { return * reinterpret_cast < uint32_t *>( GetData () + OFFSET_FREE_SPACE); }
90
+ private:
91
+ using TupleInfo = std::tuple< uint16_t , uint16_t , TupleMeta> ;
92
+ char page_start_[ 0 ] ;
93
+ page_id_t next_page_id_ ;
94
+ uint16_t num_tuples_ ;
95
+ uint16_t num_deleted_tuples_ ;
96
+ TupleInfo tuple_info_[ 0 ];
97
+
98
+ static constexpr size_t TUPLE_INFO_SIZE = 16 ;
99
+ static_assert ( sizeof (TupleInfo) == TUPLE_INFO_SIZE);
100
+ };
155
101
156
- /* * Sets the pointer, this should be the end of the current free space. */
157
- void SetFreeSpacePointer (uint32_t free_space_pointer) {
158
- memcpy (GetData () + OFFSET_FREE_SPACE, &free_space_pointer, sizeof (uint32_t ));
159
- }
102
+ static_assert (sizeof (TablePage) == TABLE_PAGE_HEADER_SIZE);
160
103
161
- /* *
162
- * @note returned tuple count may be an overestimate because some slots may be empty
163
- * @return at least the number of tuples in this page
164
- */
165
- auto GetTupleCount () -> uint32_t { return *reinterpret_cast <uint32_t *>(GetData () + OFFSET_TUPLE_COUNT); }
166
-
167
- /* * Set the number of tuples in this page. */
168
- void SetTupleCount (uint32_t tuple_count) { memcpy (GetData () + OFFSET_TUPLE_COUNT, &tuple_count, sizeof (uint32_t )); }
169
-
170
- auto GetFreeSpaceRemaining () -> uint32_t {
171
- return GetFreeSpacePointer () - SIZE_TABLE_PAGE_HEADER - SIZE_TUPLE * GetTupleCount ();
172
- }
173
-
174
- /* * @return tuple offset at slot slot_num */
175
- auto GetTupleOffsetAtSlot (uint32_t slot_num) -> uint32_t {
176
- return *reinterpret_cast <uint32_t *>(GetData () + OFFSET_TUPLE_OFFSET + SIZE_TUPLE * slot_num);
177
- }
178
-
179
- /* * Set tuple offset at slot slot_num. */
180
- void SetTupleOffsetAtSlot (uint32_t slot_num, uint32_t offset) {
181
- memcpy (GetData () + OFFSET_TUPLE_OFFSET + SIZE_TUPLE * slot_num, &offset, sizeof (uint32_t ));
182
- }
183
-
184
- /* * @return tuple size at slot slot_num */
185
- auto GetTupleSize (uint32_t slot_num) -> uint32_t {
186
- return *reinterpret_cast <uint32_t *>(GetData () + OFFSET_TUPLE_SIZE + SIZE_TUPLE * slot_num);
187
- }
188
-
189
- /* * Set tuple size at slot slot_num. */
190
- void SetTupleSize (uint32_t slot_num, uint32_t size) {
191
- memcpy (GetData () + OFFSET_TUPLE_SIZE + SIZE_TUPLE * slot_num, &size, sizeof (uint32_t ));
192
- }
193
-
194
- /* * @return true if the tuple is deleted or empty */
195
- static auto IsDeleted (uint32_t tuple_size) -> bool {
196
- return static_cast <bool >(tuple_size & DELETE_MASK) || tuple_size == 0 ;
197
- }
198
-
199
- /* * @return tuple size with the deleted flag set */
200
- static auto SetDeletedFlag (uint32_t tuple_size) -> uint32_t {
201
- return static_cast <uint32_t >(tuple_size | DELETE_MASK);
202
- }
203
-
204
- /* * @return tuple size with the deleted flag unset */
205
- static auto UnsetDeletedFlag (uint32_t tuple_size) -> uint32_t {
206
- return static_cast <uint32_t >(tuple_size & (~DELETE_MASK));
207
- }
208
- };
209
104
} // namespace bustub
0 commit comments