Skip to content

Commit 269f8de

Browse files
authored
Merge pull request #3 from poyrazK/chore/gtest-migration-v2
chore: migrate to GoogleTest and restore coverage
2 parents 2cdf09d + 509b893 commit 269f8de

19 files changed

Lines changed: 2340 additions & 560 deletions

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,15 @@ jobs:
7373
./transaction_manager_tests
7474
./statement_tests
7575
./recovery_tests
76+
./recovery_manager_tests
77+
./buffer_pool_tests
7678
7779
- name: Generate Coverage Report
7880
if: matrix.sanitizer == 'address' && matrix.compiler == 'clang++'
7981
run: |
8082
cd build
8183
lcov --directory . --capture --output-file coverage.info --gcov-tool "$GITHUB_WORKSPACE/.github/scripts/llvm-gcov.sh" --ignore-errors inconsistent
82-
lcov --remove coverage.info '/usr/*' '*/tests/*' '*/CMakeFiles/*' --output-file filtered_coverage.info --ignore-errors inconsistent,unused
84+
lcov --remove coverage.info '/usr/*' '*/tests/*' '*/CMakeFiles/*' '*/_deps/*' --output-file filtered_coverage.info --ignore-errors inconsistent,unused
8385
genhtml filtered_coverage.info --output-directory out_coverage --ignore-errors inconsistent
8486
8587
- name: Upload Coverage

include/storage/buffer_pool_manager.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define CLOUDSQL_STORAGE_BUFFER_POOL_MANAGER_HPP
88

99
#include <list>
10+
#include <memory>
1011
#include <mutex>
1112
#include <string>
1213
#include <unordered_map>
@@ -95,6 +96,11 @@ class BufferPoolManager {
9596
*/
9697
void flush_all_pages();
9798

99+
/**
100+
* @brief Get pointer to log manager
101+
*/
102+
[[nodiscard]] recovery::LogManager* get_log_manager() const { return log_manager_; }
103+
98104
private:
99105
/**
100106
* @brief Generates a unique string key for file and page mapping
@@ -111,7 +117,7 @@ class BufferPoolManager {
111117
std::mutex latch_;
112118

113119
// The actual array of pages
114-
std::vector<Page> pages_;
120+
std::unique_ptr<Page[]> pages_;
115121

116122
// Replacer instance
117123
LRUReplacer replacer_;

include/storage/storage_manager.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,18 @@ class StorageManager {
7373
*/
7474
bool write_page(const std::string& filename, uint32_t page_num, const char* buffer);
7575

76+
/**
77+
* @brief Allocate a new page in the database file
78+
* @param filename Name of the database file
79+
* @return index of the newly allocated page
80+
*/
81+
uint32_t allocate_page(const std::string& filename);
82+
83+
/**
84+
* @brief Deallocate a page (stub for future use)
85+
*/
86+
static void deallocate_page(const std::string& filename, uint32_t page_num);
87+
7688
/**
7789
* @brief Check if a file exists
7890
*/

include/transaction/transaction.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ class Transaction {
109109
exclusive_locks_.insert(rid);
110110
}
111111

112-
[[nodiscard]] const std::unordered_set<std::string>& get_shared_locks() {
112+
[[nodiscard]] std::unordered_set<std::string> get_shared_lock_set() {
113113
const std::scoped_lock<std::mutex> lock(lock_set_mutex_);
114114
return shared_locks_;
115115
}
116-
[[nodiscard]] const std::unordered_set<std::string>& get_exclusive_locks() {
116+
[[nodiscard]] std::unordered_set<std::string> get_exclusive_lock_set() {
117117
const std::scoped_lock<std::mutex> lock(lock_set_mutex_);
118118
return exclusive_locks_;
119119
}

include/transaction/transaction_manager.hpp

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,77 @@
77
#define CLOUDSQL_TRANSACTION_TRANSACTION_MANAGER_HPP
88

99
#include <atomic>
10+
#include <deque>
1011
#include <memory>
12+
#include <mutex>
1113
#include <unordered_map>
14+
#include <vector>
1215

1316
#include "catalog/catalog.hpp"
14-
#include "recovery/log_manager.hpp"
1517
#include "storage/buffer_pool_manager.hpp"
1618
#include "transaction/lock_manager.hpp"
1719
#include "transaction/transaction.hpp"
1820

1921
namespace cloudsql::transaction {
2022

23+
/**
24+
* @brief Manages the lifecycle of transactions
25+
*/
2126
class TransactionManager {
22-
private:
23-
std::atomic<txn_id_t> next_txn_id_{1};
24-
std::unordered_map<txn_id_t, std::unique_ptr<Transaction>> active_transactions_;
25-
std::unordered_map<txn_id_t, std::unique_ptr<Transaction>> completed_transactions_;
26-
LockManager& lock_manager_;
27-
Catalog& catalog_;
28-
storage::BufferPoolManager& bpm_;
29-
recovery::LogManager* log_manager_;
30-
std::mutex manager_latch_;
31-
32-
void undo_transaction(Transaction* txn);
33-
3427
public:
3528
explicit TransactionManager(LockManager& lock_manager, Catalog& catalog,
3629
storage::BufferPoolManager& bpm,
37-
recovery::LogManager* log_manager = nullptr)
38-
: lock_manager_(lock_manager), catalog_(catalog), bpm_(bpm), log_manager_(log_manager) {}
30+
recovery::LogManager* log_manager = nullptr);
31+
32+
~TransactionManager() = default;
3933

34+
// Disable copy/move
35+
TransactionManager(const TransactionManager&) = delete;
36+
TransactionManager& operator=(const TransactionManager&) = delete;
37+
TransactionManager(TransactionManager&&) = delete;
38+
TransactionManager& operator=(TransactionManager&&) = delete;
39+
40+
/**
41+
* @brief Start a new transaction
42+
* @param level Isolation level
43+
* @return Pointer to the new transaction
44+
*/
4045
Transaction* begin(IsolationLevel level = IsolationLevel::REPEATABLE_READ);
46+
47+
/**
48+
* @brief Commit a transaction
49+
*/
4150
void commit(Transaction* txn);
51+
52+
/**
53+
* @brief Abort a transaction
54+
*/
4255
void abort(Transaction* txn);
4356

57+
/**
58+
* @brief Get transaction by ID
59+
*/
4460
Transaction* get_transaction(txn_id_t txn_id);
61+
62+
private:
63+
LockManager& lock_manager_;
64+
Catalog& catalog_;
65+
storage::BufferPoolManager& bpm_;
66+
recovery::LogManager* log_manager_;
67+
68+
std::atomic<txn_id_t> next_txn_id_{1};
69+
std::mutex manager_latch_;
70+
71+
// All active transactions
72+
std::unordered_map<txn_id_t, std::unique_ptr<Transaction>> active_transactions_;
73+
74+
// Transactions that have recently finished (for cleanup/safety)
75+
std::deque<std::unique_ptr<Transaction>> completed_transactions_;
76+
77+
/**
78+
* @brief Undo changes made by a transaction
79+
*/
80+
void undo_transaction(Transaction* txn);
4581
};
4682

4783
} // namespace cloudsql::transaction

src/catalog/catalog.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <iostream>
1616
#include <memory>
1717
#include <optional>
18+
#include <stdexcept>
1819
#include <string>
1920
#include <utility>
2021
#include <vector>
@@ -70,6 +71,10 @@ bool Catalog::save(const std::string& filename) const {
7071
* @brief Create a new table
7172
*/
7273
oid_t Catalog::create_table(const std::string& table_name, std::vector<ColumnInfo> columns) {
74+
if (table_exists_by_name(table_name)) {
75+
throw std::runtime_error("Table already exists: " + table_name);
76+
}
77+
7378
auto table = std::make_unique<TableInfo>();
7479
table->table_id = next_oid_++;
7580
table->name = table_name;
@@ -139,6 +144,13 @@ oid_t Catalog::create_index(const std::string& index_name, oid_t table_id,
139144
return 0;
140145
}
141146

147+
auto& table = *table_opt.value();
148+
for (const auto& existing_idx : table.indexes) {
149+
if (existing_idx.name == index_name) {
150+
throw std::runtime_error("Index already exists: " + index_name);
151+
}
152+
}
153+
142154
IndexInfo index;
143155
index.index_id = next_oid_++;
144156
index.name = index_name;
@@ -148,7 +160,7 @@ oid_t Catalog::create_index(const std::string& index_name, oid_t table_id,
148160
index.is_unique = is_unique;
149161

150162
const oid_t id = index.index_id;
151-
(*table_opt)->indexes.push_back(std::move(index));
163+
table.indexes.push_back(std::move(index));
152164
return id;
153165
}
154166

0 commit comments

Comments
 (0)