-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathheap_table.hpp
More file actions
221 lines (181 loc) · 6.9 KB
/
heap_table.hpp
File metadata and controls
221 lines (181 loc) · 6.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/**
* @file heap_table.hpp
* @brief Slot-based heap file storage for row-oriented data
*
* This implementation uses a slotted page structure to manage variable-length
* records within fixed-size database pages.
*
* @defgroup storage Storage Engine
* @{
*/
#ifndef CLOUDSQL_STORAGE_HEAP_TABLE_HPP
#define CLOUDSQL_STORAGE_HEAP_TABLE_HPP
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include "executor/types.hpp"
#include "storage/buffer_pool_manager.hpp"
namespace cloudsql::storage {
/**
* @class HeapTable
* @brief Manages a physical heap file containing database records
*/
class HeapTable {
public:
/**
* @struct TupleId
* @brief Record Identifier (RID) consisting of a page number and slot index
*/
struct TupleId {
uint32_t page_num; /**< Physical page index in the file */
uint16_t slot_num; /**< Logical slot index within the page */
TupleId() : page_num(0), slot_num(0) {}
TupleId(uint32_t page, uint16_t slot) : page_num(page), slot_num(slot) {}
/** @return true if the ID represents a null/invalid record */
[[nodiscard]] bool is_null() const { return page_num == 0 && slot_num == 0; }
/** @return Human-readable string representation */
[[nodiscard]] std::string to_string() const {
return "(" + std::to_string(page_num) + ", " + std::to_string(slot_num) + ")";
}
bool operator==(const TupleId& other) const {
return page_num == other.page_num && slot_num == other.slot_num;
}
};
/**
* @struct PageHeader
* @brief Fixed-size header present at the beginning of every database page
*/
struct PageHeader {
uint32_t next_page; /**< Next page in the heap chain */
uint16_t num_slots; /**< Total slots allocated in this page */
uint16_t free_space_offset; /**< Pointer to the start of free space */
uint16_t flags; /**< Page-level metadata flags */
};
/**
* @struct TupleHeader
* @brief MVCC metadata prepended to every tuple
*/
struct TupleHeader {
uint64_t xmin; /**< Transaction ID that created this tuple */
uint64_t xmax; /**< Transaction ID that deleted this tuple (0 if active) */
};
/**
* @struct TupleMeta
* @brief Container for tuple data and its MVCC metadata
*/
struct TupleMeta {
executor::Tuple tuple;
uint64_t xmin = 0;
uint64_t xmax = 0;
};
/**
* @class Iterator
* @brief Forward-only iterator for scanning heap table records
*/
class Iterator {
private:
HeapTable& table_;
TupleId next_id_; /**< ID of the next record to be checked */
TupleId last_id_; /**< ID of the record returned by the last next() call */
bool eof_ = false; /**< End-of-file indicator */
public:
explicit Iterator(HeapTable& table);
/**
* @brief Fetches the next non-deleted record from the heap
* @param[out] out_tuple Container for the retrieved record
* @return true if a record was successfully retrieved, false on EOF
*/
bool next(executor::Tuple& out_tuple);
/**
* @brief Fetches the next record including MVCC metadata
* @param[out] out_meta Container for the retrieved record and metadata
* @return true if a record was successfully retrieved, false on EOF
*/
bool next_meta(TupleMeta& out_meta);
/** @return true if the scan has reached the end of the table */
[[nodiscard]] bool is_done() const { return eof_; }
/** @return RID of the most recently retrieved record */
[[nodiscard]] const TupleId& current_id() const { return last_id_; }
};
private:
std::string table_name_;
std::string filename_;
BufferPoolManager& bpm_;
executor::Schema schema_;
public:
/**
* @brief Constructor
* @param table_name Logical name of the table
* @param bpm Reference to the global buffer pool manager
* @param schema Table schema definition
*/
HeapTable(std::string table_name, BufferPoolManager& bpm, executor::Schema schema);
~HeapTable() = default;
/* Disable copy semantics */
HeapTable(const HeapTable&) = delete;
HeapTable& operator=(const HeapTable&) = delete;
/* Enable move semantics (assignment deleted due to reference member) */
HeapTable(HeapTable&&) noexcept = default;
HeapTable& operator=(HeapTable&&) noexcept = delete;
/** @return Logical table name */
[[nodiscard]] const std::string& table_name() const { return table_name_; }
/** @return Schema definition */
[[nodiscard]] const executor::Schema& schema() const { return schema_; }
/**
* @brief Inserts a new record into the heap
* @param tuple The data to insert
* @param xmin Transaction ID creating this tuple
* @return Unique identifier assigned to the new record
*/
TupleId insert(const executor::Tuple& tuple, uint64_t xmin = 0);
/**
* @brief Logically deletes a record by setting xmax
* @param tuple_id The record to delete
* @param xmax Transaction ID deleting this tuple
* @return true on success
*/
bool remove(const TupleId& tuple_id, uint64_t xmax);
/**
* @brief Physically removes a record (used for rollback)
* @return true on success
*/
bool physical_remove(const TupleId& tuple_id);
/**
* @brief Resets xmax to 0 (used for rollback of a DELETE)
* @return true on success
*/
bool undo_remove(const TupleId& tuple_id);
/**
* @brief Replaces an existing record with new data
* @param tuple_id The record to update
* @param tuple The new data
* @param txn_id ID of the transaction performing the update
* @return true on success
*/
bool update(const TupleId& tuple_id, const executor::Tuple& tuple, uint64_t txn_id);
/**
* @brief Retrieves a specific record by its ID
* @return true if the record exists and was retrieved
*/
bool get(const TupleId& tuple_id, executor::Tuple& out_tuple) const;
/**
* @brief Retrieves a specific record with metadata by its ID
* @return true if the record exists and was retrieved
*/
bool get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const;
/** @return Total count of non-deleted records in the table */
[[nodiscard]] uint64_t tuple_count() const;
/** @return An iterator starting at the first page */
[[nodiscard]] Iterator scan() { return Iterator(*this); }
/** @brief Initializes the physical heap file */
bool create();
/** @brief Removes the physical heap file */
bool drop();
private:
bool read_page(uint32_t page_num, char* buffer) const;
bool write_page(uint32_t page_num, const char* buffer);
};
} // namespace cloudsql::storage
#endif // CLOUDSQL_STORAGE_HEAP_TABLE_HPP
/** @} */