From ae162ec454ac7ae2ad5c6c9fd83a1e3112d6706a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:56:46 +0300 Subject: [PATCH 01/21] perf: fix ArenaAllocator reset logic and update benchmark to use string execute --- benchmarks/sqlite_comparison_bench.cpp | 6 +- include/common/arena_allocator.hpp | 117 +++++++++++++++++++++++++ src/storage/heap_table.cpp | 6 +- 3 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 include/common/arena_allocator.hpp diff --git a/benchmarks/sqlite_comparison_bench.cpp b/benchmarks/sqlite_comparison_bench.cpp index de8b33a..aff2535 100644 --- a/benchmarks/sqlite_comparison_bench.cpp +++ b/benchmarks/sqlite_comparison_bench.cpp @@ -109,13 +109,9 @@ static void BM_CloudSQL_Insert(benchmark::State& state) { CloudSQLContext ctx("./bench_cloudsql_insert_" + std::to_string(state.thread_index())); for (auto _ : state) { - state.PauseTiming(); std::string sql = "INSERT INTO bench_table VALUES (" + std::to_string(state.iterations()) + ", 3.14, 'some_payload_data');"; - auto stmt = ParseSQL(sql); - state.ResumeTiming(); - - ctx.executor->execute(*stmt); + ctx.executor->execute(sql); } state.SetItemsProcessed(state.iterations()); } diff --git a/include/common/arena_allocator.hpp b/include/common/arena_allocator.hpp new file mode 100644 index 0000000..dada1b9 --- /dev/null +++ b/include/common/arena_allocator.hpp @@ -0,0 +1,117 @@ +/** + * @file arena_allocator.hpp + * @brief High-performance bump allocator for execution-scoped data + */ + +#ifndef CLOUDSQL_COMMON_ARENA_ALLOCATOR_HPP +#define CLOUDSQL_COMMON_ARENA_ALLOCATOR_HPP + +#include +#include +#include +#include +#include +#include + +namespace cloudsql::common { + +/** + * @class ArenaAllocator + * @brief Manages memory chunks and provides fast, contiguous allocations. + * + * Implements std::pmr::memory_resource for compatibility with standard + * containers like std::pmr::vector. + */ +class ArenaAllocator : public std::pmr::memory_resource { + public: + static constexpr size_t DEFAULT_CHUNK_SIZE = 65536; // 64KB + + explicit ArenaAllocator(size_t chunk_size = DEFAULT_CHUNK_SIZE) + : chunk_size_(chunk_size), current_chunk_idx_(0), current_offset_(0) {} + + ~ArenaAllocator() override { + for (auto* chunk : chunks_) { + delete[] chunk; + } + } + + // Disable copy + ArenaAllocator(const ArenaAllocator&) = delete; + ArenaAllocator& operator=(const ArenaAllocator&) = delete; + + /** + * @brief Reset the arena, reclaiming all memory for reuse. + * + * Keeps all allocated chunks but resets pointers so they can be overwritten. + * This is an O(1) or O(N_chunks) operation with zero heap overhead. + */ + void reset() { + current_chunk_idx_ = 0; + current_offset_ = 0; + } + + protected: + /** + * @brief Internal allocation logic for PMR + */ + void* do_allocate(size_t bytes, size_t alignment) override { + if (bytes == 0) return nullptr; + + // Align the offset + size_t mask = alignment - 1; + + // Try current chunk + if (current_chunk_idx_ < chunks_.size()) { + size_t aligned_offset = (current_offset_ + mask) & ~mask; + if (aligned_offset + bytes <= chunk_size_) { + void* result = chunks_[current_chunk_idx_] + aligned_offset; + current_offset_ = aligned_offset + bytes; + return result; + } + + // Move to next existing chunk if possible + current_chunk_idx_++; + current_offset_ = 0; + return do_allocate(bytes, alignment); + } + + // Need a new chunk + if (bytes > chunk_size_) { + auto* large_chunk = new uint8_t[bytes]; + chunks_.push_back(large_chunk); + // We don't make this the "current" chunk for small allocations + // to avoid wasting space. We just return it. + return large_chunk; + } + + allocate_new_chunk(); + return do_allocate(bytes, alignment); + } + + /** + * @brief PMR deallocate is a no-op for bump allocators (we reset the whole arena) + */ + void do_deallocate(void* p, size_t bytes, size_t alignment) override { + // No-op + (void)p; (void)bytes; (void)alignment; + } + + bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { + return this == &other; + } + + private: + void allocate_new_chunk() { + chunks_.push_back(new uint8_t[chunk_size_]); + // Don't change current_chunk_idx_ here, let the recursive call handle it + } + + size_t chunk_size_; + std::vector chunks_; + size_t current_chunk_idx_; + size_t current_offset_; +}; + +} // namespace cloudsql::common + +#endif // CLOUDSQL_COMMON_ARENA_ALLOCATOR_HPP diff --git a/src/storage/heap_table.cpp b/src/storage/heap_table.cpp index b350032..e9cb090 100644 --- a/src/storage/heap_table.cpp +++ b/src/storage/heap_table.cpp @@ -40,7 +40,8 @@ HeapTable::HeapTable(std::string table_name, BufferPoolManager& bpm, executor::S /* --- Iterator Implementation --- */ -HeapTable::Iterator::Iterator(HeapTable& table) : table_(table), next_id_(0, 0), last_id_(0, 0) {} +HeapTable::Iterator::Iterator(HeapTable& table, std::pmr::memory_resource* mr) + : table_(table), next_id_(0, 0), last_id_(0, 0), mr_(mr) {} bool HeapTable::Iterator::next(executor::Tuple& out_tuple) { TupleMeta meta; @@ -100,7 +101,8 @@ bool HeapTable::Iterator::next_meta(TupleMeta& out_meta) { std::memcpy(&out_meta.xmax, data + 8, 8); size_t cursor = 16; - std::vector values; + // Zero-allocation vector construction via Arena (mr_) + std::pmr::vector values(mr_); values.reserve(table_.schema_.column_count()); for (size_t i = 0; i < table_.schema_.column_count(); ++i) { From 3bda4e3a3af3e1d9aa6bb7f290501fba09015ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:49:28 +0300 Subject: [PATCH 02/21] feat(executor): integrate PMR-compliant ArenaAllocator for zero-allocation data path --- include/executor/operator.hpp | 11 +++++++++++ include/executor/types.hpp | 20 ++++++++++++++++---- src/executor/operator.cpp | 12 ++++++------ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/include/executor/operator.hpp b/include/executor/operator.hpp index d4607b7..981ce33 100644 --- a/include/executor/operator.hpp +++ b/include/executor/operator.hpp @@ -7,6 +7,7 @@ #define CLOUDSQL_EXECUTOR_OPERATOR_HPP #include +#include #include #include #include @@ -52,6 +53,8 @@ class Operator { std::string error_message_; Transaction* txn_; LockManager* lock_manager_; + std::pmr::memory_resource* mr_ = nullptr; + const std::vector* params_ = nullptr; public: explicit Operator(OperatorType type, Transaction* txn = nullptr, @@ -71,6 +74,14 @@ class Operator { [[nodiscard]] Transaction* get_txn() const { return txn_; } [[nodiscard]] LockManager* get_lock_manager() const { return lock_manager_; } + void set_memory_resource(std::pmr::memory_resource* mr) { mr_ = mr; } + [[nodiscard]] std::pmr::memory_resource* get_memory_resource() const { + return mr_ ? mr_ : std::pmr::get_default_resource(); + } + + void set_params(const std::vector* params) { params_ = params; } + [[nodiscard]] const std::vector* get_params() const { return params_; } + virtual bool init() { return true; } virtual bool open() { return true; } virtual bool next(Tuple& out_tuple) { diff --git a/include/executor/types.hpp b/include/executor/types.hpp index 3c5e384..ec30b0b 100644 --- a/include/executor/types.hpp +++ b/include/executor/types.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -120,14 +121,25 @@ class Schema { /** * @brief A single data row used in the row-oriented (Volcano) execution model. + * + * Uses std::pmr::vector to support custom allocators (e.g. ArenaAllocator). */ class Tuple { private: - std::vector values_; + std::pmr::vector values_; public: Tuple() = default; - explicit Tuple(std::vector values) : values_(std::move(values)) {} + explicit Tuple(std::pmr::vector values) : values_(std::move(values)) {} + + // Support construction from standard vector (via move or copy) + explicit Tuple(std::vector values) + : values_(values.begin(), values.end()) {} + + // Support allocation from a custom memory resource + explicit Tuple(std::pmr::memory_resource* mr) : values_(mr) {} + Tuple(std::vector values, std::pmr::memory_resource* mr) + : values_(values.begin(), values.end(), mr) {} Tuple(const Tuple& other) = default; Tuple(Tuple&& other) noexcept = default; @@ -159,8 +171,8 @@ class Tuple { [[nodiscard]] size_t size() const { return values_.size(); } [[nodiscard]] bool empty() const { return values_.empty(); } - [[nodiscard]] const std::vector& values() const { return values_; } - [[nodiscard]] std::vector& values() { return values_; } + [[nodiscard]] const std::pmr::vector& values() const { return values_; } + [[nodiscard]] std::pmr::vector& values() { return values_; } [[nodiscard]] std::string to_string() const; }; diff --git a/src/executor/operator.cpp b/src/executor/operator.cpp index 1708e84..fda96de 100644 --- a/src/executor/operator.cpp +++ b/src/executor/operator.cpp @@ -48,7 +48,7 @@ bool SeqScanOperator::init() { bool SeqScanOperator::open() { set_state(ExecState::Open); - iterator_ = std::make_unique(table_->scan()); + iterator_ = std::make_unique(table_->scan(get_memory_resource())); return true; } @@ -306,7 +306,7 @@ bool ProjectOperator::next(Tuple& out_tuple) { return false; } - std::vector output_values; + std::pmr::vector output_values(get_memory_resource()); output_values.reserve(columns_.size()); auto input_schema = child_->output_schema(); for (const auto& col : columns_) { @@ -645,7 +645,7 @@ bool HashJoinOperator::next(Tuple& out_tuple) { if (iter_state.current != iter_state.end) { auto& build_tuple = iter_state.current->second; const auto& right_tuple = build_tuple.tuple; - std::vector joined_values = left_tuple_->values(); + std::pmr::vector joined_values(left_tuple_->values().begin(), left_tuple_->values().end(), get_memory_resource()); joined_values.insert(joined_values.end(), right_tuple.values().begin(), right_tuple.values().end()); @@ -661,7 +661,7 @@ bool HashJoinOperator::next(Tuple& out_tuple) { match_iter_ = std::nullopt; if ((join_type_ == JoinType::Left || join_type_ == JoinType::Full) && !left_had_match_) { - std::vector joined_values = left_tuple_->values(); + std::pmr::vector joined_values(left_tuple_->values().begin(), left_tuple_->values().end(), get_memory_resource()); for (size_t i = 0; i < right_schema.column_count(); ++i) { joined_values.push_back(common::Value::make_null()); } @@ -685,7 +685,7 @@ bool HashJoinOperator::next(Tuple& out_tuple) { match_iter_ = {range.first, range.second}; } else if (join_type_ == JoinType::Left || join_type_ == JoinType::Full) { /* No match found immediately, emit NULLs if Left/Full join */ - std::vector joined_values = left_tuple_->values(); + std::pmr::vector joined_values(left_tuple_->values().begin(), left_tuple_->values().end(), get_memory_resource()); for (size_t i = 0; i < right_schema.column_count(); ++i) { joined_values.push_back(common::Value::make_null()); } @@ -708,7 +708,7 @@ bool HashJoinOperator::next(Tuple& out_tuple) { auto& it = right_idx_iter_.value(); while (it != hash_table_.end()) { if (!it->second.matched) { - std::vector joined_values; + std::pmr::vector joined_values(get_memory_resource()); for (size_t i = 0; i < left_schema.column_count(); ++i) { joined_values.push_back(common::Value::make_null()); } From 70fb2529df90a3322181129b8222a5bc4c6423d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:49:39 +0300 Subject: [PATCH 03/21] feat(parser): implement parameter binding support (? placeholders) --- include/parser/expression.hpp | 65 ++++++++++++++++++++++-------- include/parser/parser.hpp | 1 + src/parser/expression.cpp | 76 +++++++++++++++++++++++++---------- src/parser/lexer.cpp | 2 + src/parser/parser.cpp | 5 +++ 5 files changed, 111 insertions(+), 38 deletions(-) diff --git a/include/parser/expression.hpp b/include/parser/expression.hpp index 5776ba2..acf662a 100644 --- a/include/parser/expression.hpp +++ b/include/parser/expression.hpp @@ -35,7 +35,8 @@ enum class ExprType : uint8_t { In, Like, Between, - IsNull + IsNull, + Parameter }; /** @@ -57,10 +58,11 @@ class Expression { [[nodiscard]] virtual ExprType type() const = 0; /** - * @brief Evaluate expression against an optional tuple context + * @brief Evaluate expression against an optional tuple context and bound parameters */ [[nodiscard]] virtual common::Value evaluate( - const executor::Tuple* tuple = nullptr, const executor::Schema* schema = nullptr) const = 0; + const executor::Tuple* tuple = nullptr, const executor::Schema* schema = nullptr, + const std::vector* params = nullptr) const = 0; /** * @brief Evaluate expression against a batch of data (Vectorized) @@ -87,8 +89,9 @@ class BinaryExpr : public Expression { : left_(std::move(left)), op_(op), right_(std::move(right)) {} [[nodiscard]] ExprType type() const override { return ExprType::Binary; } - [[nodiscard]] common::Value evaluate(const executor::Tuple* tuple = nullptr, - const executor::Schema* schema = nullptr) const override; + [[nodiscard]] common::Value evaluate( + const executor::Tuple* tuple = nullptr, const executor::Schema* schema = nullptr, + const std::vector* params = nullptr) const override; void evaluate_vectorized(const executor::VectorBatch& batch, const executor::Schema& schema, executor::ColumnVector& result) const override; [[nodiscard]] std::string to_string() const override; @@ -111,8 +114,9 @@ class UnaryExpr : public Expression { UnaryExpr(TokenType op, std::unique_ptr expr) : op_(op), expr_(std::move(expr)) {} [[nodiscard]] ExprType type() const override { return ExprType::Unary; } - [[nodiscard]] common::Value evaluate(const executor::Tuple* tuple = nullptr, - const executor::Schema* schema = nullptr) const override; + [[nodiscard]] common::Value evaluate( + const executor::Tuple* tuple = nullptr, const executor::Schema* schema = nullptr, + const std::vector* params = nullptr) const override; void evaluate_vectorized(const executor::VectorBatch& batch, const executor::Schema& schema, executor::ColumnVector& result) const override; [[nodiscard]] std::string to_string() const override; @@ -133,8 +137,9 @@ class ColumnExpr : public Expression { : table_name_(std::move(table)), name_(std::move(name)) {} [[nodiscard]] ExprType type() const override { return ExprType::Column; } - [[nodiscard]] common::Value evaluate(const executor::Tuple* tuple = nullptr, - const executor::Schema* schema = nullptr) const override; + [[nodiscard]] common::Value evaluate( + const executor::Tuple* tuple = nullptr, const executor::Schema* schema = nullptr, + const std::vector* params = nullptr) const override; void evaluate_vectorized(const executor::VectorBatch& batch, const executor::Schema& schema, executor::ColumnVector& result) const override; [[nodiscard]] std::string to_string() const override; @@ -156,8 +161,9 @@ class ConstantExpr : public Expression { explicit ConstantExpr(common::Value val) : value_(std::move(val)) {} [[nodiscard]] ExprType type() const override { return ExprType::Constant; } - [[nodiscard]] common::Value evaluate(const executor::Tuple* tuple = nullptr, - const executor::Schema* schema = nullptr) const override; + [[nodiscard]] common::Value evaluate( + const executor::Tuple* tuple = nullptr, const executor::Schema* schema = nullptr, + const std::vector* params = nullptr) const override; void evaluate_vectorized(const executor::VectorBatch& batch, const executor::Schema& schema, executor::ColumnVector& result) const override; [[nodiscard]] std::string to_string() const override; @@ -166,6 +172,28 @@ class ConstantExpr : public Expression { [[nodiscard]] const common::Value& value() const { return value_; } }; +/** + * @brief Bound parameter expression (e.g. ?) + */ +class ParameterExpr : public Expression { + private: + uint32_t index_; + + public: + explicit ParameterExpr(uint32_t index) : index_(index) {} + + [[nodiscard]] ExprType type() const override { return ExprType::Parameter; } + [[nodiscard]] common::Value evaluate( + const executor::Tuple* tuple = nullptr, const executor::Schema* schema = nullptr, + const std::vector* params = nullptr) const override; + void evaluate_vectorized(const executor::VectorBatch& batch, const executor::Schema& schema, + executor::ColumnVector& result) const override; + [[nodiscard]] std::string to_string() const override; + [[nodiscard]] std::unique_ptr clone() const override; + + [[nodiscard]] uint32_t index() const { return index_; } +}; + /** * @brief Scalar function or aggregate expression */ @@ -179,8 +207,9 @@ class FunctionExpr : public Expression { explicit FunctionExpr(std::string name) : func_name_(std::move(name)) {} [[nodiscard]] ExprType type() const override { return ExprType::Function; } - [[nodiscard]] common::Value evaluate(const executor::Tuple* tuple = nullptr, - const executor::Schema* schema = nullptr) const override; + [[nodiscard]] common::Value evaluate( + const executor::Tuple* tuple = nullptr, const executor::Schema* schema = nullptr, + const std::vector* params = nullptr) const override; void evaluate_vectorized(const executor::VectorBatch& batch, const executor::Schema& schema, executor::ColumnVector& result) const override; [[nodiscard]] std::string to_string() const override; @@ -208,8 +237,9 @@ class InExpr : public Expression { : column_(std::move(col)), values_(std::move(vals)), not_flag_(is_not) {} [[nodiscard]] ExprType type() const override { return ExprType::In; } - [[nodiscard]] common::Value evaluate(const executor::Tuple* tuple = nullptr, - const executor::Schema* schema = nullptr) const override; + [[nodiscard]] common::Value evaluate( + const executor::Tuple* tuple = nullptr, const executor::Schema* schema = nullptr, + const std::vector* params = nullptr) const override; void evaluate_vectorized(const executor::VectorBatch& batch, const executor::Schema& schema, executor::ColumnVector& result) const override; [[nodiscard]] std::string to_string() const override; @@ -229,8 +259,9 @@ class IsNullExpr : public Expression { : expr_(std::move(expr)), not_flag_(not_flag) {} [[nodiscard]] ExprType type() const override { return ExprType::IsNull; } - [[nodiscard]] common::Value evaluate(const executor::Tuple* tuple = nullptr, - const executor::Schema* schema = nullptr) const override; + [[nodiscard]] common::Value evaluate( + const executor::Tuple* tuple = nullptr, const executor::Schema* schema = nullptr, + const std::vector* params = nullptr) const override; void evaluate_vectorized(const executor::VectorBatch& batch, const executor::Schema& schema, executor::ColumnVector& result) const override; [[nodiscard]] std::string to_string() const override; diff --git a/include/parser/parser.hpp b/include/parser/parser.hpp index e8ead47..53cacfa 100644 --- a/include/parser/parser.hpp +++ b/include/parser/parser.hpp @@ -18,6 +18,7 @@ class Parser { std::unique_ptr lexer_; Token current_token_; bool has_current_ = false; + uint32_t param_count_ = 0; Token next_token(); Token peek_token(); diff --git a/src/parser/expression.cpp b/src/parser/expression.cpp index 746625d..96c3dbf 100644 --- a/src/parser/expression.cpp +++ b/src/parser/expression.cpp @@ -21,10 +21,10 @@ namespace cloudsql::parser { /** * @brief Evaluate binary expression */ -common::Value BinaryExpr::evaluate(const executor::Tuple* tuple, - const executor::Schema* schema) const { - const common::Value left_val = left_->evaluate(tuple, schema); - const common::Value right_val = right_->evaluate(tuple, schema); +common::Value BinaryExpr::evaluate(const executor::Tuple* tuple, const executor::Schema* schema, + const std::vector* params) const { + const common::Value left_val = left_->evaluate(tuple, schema, params); + const common::Value right_val = right_->evaluate(tuple, schema, params); switch (op_) { case TokenType::Plus: @@ -186,17 +186,20 @@ std::unique_ptr BinaryExpr::clone() const { /** * @brief Evaluate unary expression */ -common::Value UnaryExpr::evaluate(const executor::Tuple* tuple, - const executor::Schema* schema) const { - const common::Value val = expr_->evaluate(tuple, schema); +common::Value UnaryExpr::evaluate(const executor::Tuple* tuple, const executor::Schema* schema, + const std::vector* params) const { + const common::Value val = expr_->evaluate(tuple, schema, params); switch (op_) { case TokenType::Minus: if (val.is_numeric()) { - return common::Value(-val.to_float64()); + if (val.type() == common::ValueType::TYPE_FLOAT64) { + return common::Value::make_float64(-val.to_float64()); + } + return common::Value::make_int64(-val.to_int64()); } break; case TokenType::Not: - return common::Value(!val.as_bool()); + return common::Value::make_bool(!val.as_bool()); default: break; } @@ -229,8 +232,9 @@ std::unique_ptr UnaryExpr::clone() const { /** * @brief Evaluate column expression using tuple and schema */ -common::Value ColumnExpr::evaluate(const executor::Tuple* tuple, - const executor::Schema* schema) const { +common::Value ColumnExpr::evaluate(const executor::Tuple* tuple, const executor::Schema* schema, + const std::vector* params) const { + (void)params; if (tuple == nullptr || schema == nullptr) { return common::Value::make_null(); } @@ -288,10 +292,11 @@ std::unique_ptr ColumnExpr::clone() const { : std::make_unique(name_); } -common::Value ConstantExpr::evaluate(const executor::Tuple* tuple, - const executor::Schema* schema) const { +common::Value ConstantExpr::evaluate(const executor::Tuple* tuple, const executor::Schema* schema, + const std::vector* params) const { (void)tuple; (void)schema; + (void)params; return value_; } @@ -316,11 +321,39 @@ std::unique_ptr ConstantExpr::clone() const { return std::make_unique(value_); } +/** + * @brief Evaluate parameter expression + */ +common::Value ParameterExpr::evaluate(const executor::Tuple* tuple, const executor::Schema* schema, + const std::vector* params) const { + (void)tuple; + (void)schema; + if (params == nullptr || index_ >= params->size()) { + return common::Value::make_null(); + } + return (*params)[index_]; +} + +void ParameterExpr::evaluate_vectorized(const executor::VectorBatch& batch, + const executor::Schema& schema, + executor::ColumnVector& result) const { + (void)batch; + (void)schema; + (void)result; +} + +std::string ParameterExpr::to_string() const { return "?"; } + +std::unique_ptr ParameterExpr::clone() const { + return std::make_unique(index_); +} + /** * @brief Evaluate function expression */ -common::Value FunctionExpr::evaluate(const executor::Tuple* tuple, - const executor::Schema* schema) const { +common::Value FunctionExpr::evaluate(const executor::Tuple* tuple, const executor::Schema* schema, + const std::vector* params) const { + (void)params; if (tuple == nullptr || schema == nullptr) { return common::Value::make_null(); } @@ -381,10 +414,11 @@ std::unique_ptr FunctionExpr::clone() const { /** * @brief Evaluate IN expression */ -common::Value InExpr::evaluate(const executor::Tuple* tuple, const executor::Schema* schema) const { - const common::Value col_val = column_->evaluate(tuple, schema); +common::Value InExpr::evaluate(const executor::Tuple* tuple, const executor::Schema* schema, + const std::vector* params) const { + const common::Value col_val = column_->evaluate(tuple, schema, params); for (const auto& val : values_) { - if (col_val == val->evaluate(tuple, schema)) { + if (col_val == val->evaluate(tuple, schema, params)) { return common::Value(!not_flag_); } } @@ -431,9 +465,9 @@ std::unique_ptr InExpr::clone() const { /** * @brief Evaluate IS NULL expression */ -common::Value IsNullExpr::evaluate(const executor::Tuple* tuple, - const executor::Schema* schema) const { - const common::Value val = expr_->evaluate(tuple, schema); +common::Value IsNullExpr::evaluate(const executor::Tuple* tuple, const executor::Schema* schema, + const std::vector* params) const { + const common::Value val = expr_->evaluate(tuple, schema, params); const bool result = val.is_null(); return common::Value(not_flag_ ? !result : result); } diff --git a/src/parser/lexer.cpp b/src/parser/lexer.cpp index 45a4e29..361f2c3 100644 --- a/src/parser/lexer.cpp +++ b/src/parser/lexer.cpp @@ -288,6 +288,8 @@ Token Lexer::read_operator() { return {TokenType::Ne, "!="}; } return {TokenType::Error, "!"}; + case '?': + return {TokenType::Param, "?"}; default: return {TokenType::Error, std::string(1, c)}; } diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 5fa4b54..ea9845b 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -769,6 +769,11 @@ std::unique_ptr Parser::parse_primary() { // NOLINT(misc-no-recursi return std::make_unique("*"); } + if (tok.type() == TokenType::Param) { + static_cast(next_token()); + return std::make_unique(param_count_++); + } + if (tok.type() == TokenType::Identifier || tok.is_keyword()) { const Token id = next_token(); From 7048e71877d2e38e815f15479283177d84c35799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:49:46 +0300 Subject: [PATCH 04/21] feat(executor): implement Prepared Statement API with hot-path caching --- include/executor/query_executor.hpp | 48 ++++++ src/executor/query_executor.cpp | 245 +++++++++++++++++++++++----- 2 files changed, 248 insertions(+), 45 deletions(-) diff --git a/include/executor/query_executor.hpp b/include/executor/query_executor.hpp index 9f55856..45b3bf6 100644 --- a/include/executor/query_executor.hpp +++ b/include/executor/query_executor.hpp @@ -6,8 +6,12 @@ #ifndef CLOUDSQL_EXECUTOR_QUERY_EXECUTOR_HPP #define CLOUDSQL_EXECUTOR_QUERY_EXECUTOR_HPP +#include +#include + #include "catalog/catalog.hpp" #include "common/cluster_manager.hpp" +#include "common/arena_allocator.hpp" #include "distributed/raft_types.hpp" #include "executor/operator.hpp" #include "executor/types.hpp" @@ -18,6 +22,20 @@ namespace cloudsql::executor { +/** + * @brief Represents a pre-parsed and pre-planned SQL statement + */ +struct PreparedStatement { + std::shared_ptr stmt; + std::string sql; + + // Cached execution state for hot-path optimization + const TableInfo* table_meta = nullptr; + std::unique_ptr schema; + std::unique_ptr table; + std::vector> indexes; +}; + /** * @brief State machine for a specific data shard */ @@ -62,11 +80,31 @@ class QueryExecutor { */ void set_local_only(bool local) { is_local_only_ = local; } + /** + * @brief Prepare a SQL string into a reusable PreparedStatement + */ + std::shared_ptr prepare(const std::string& sql); + /** * @brief Execute a SQL statement and return results */ QueryResult execute(const parser::Statement& stmt); + /** + * @brief Execute a SQL string (includes parsing and cache lookup) + */ + QueryResult execute(const std::string& sql); + + /** + * @brief Execute a PreparedStatement with bound parameters + */ + QueryResult execute(const PreparedStatement& prepared, const std::vector& params); + + /** + * @brief Get access to the query-scoped arena + */ + common::ArenaAllocator& arena() { return arena_; } + private: Catalog& catalog_; storage::BufferPoolManager& bpm_; @@ -78,6 +116,16 @@ class QueryExecutor { transaction::Transaction* current_txn_ = nullptr; bool is_local_only_ = false; + // Bound parameters for the current execution + const std::vector* current_params_ = nullptr; + + // Performance structures + common::ArenaAllocator arena_; + + // Global statement cache (thread-safe) + static std::unordered_map> statement_cache_; + static std::mutex cache_mutex_; + QueryResult execute_select(const parser::SelectStatement& stmt, transaction::Transaction* txn); QueryResult execute_create_table(const parser::CreateTableStatement& stmt); QueryResult execute_create_index(const parser::CreateIndexStatement& stmt); diff --git a/src/executor/query_executor.cpp b/src/executor/query_executor.cpp index 6865729..445aa81 100644 --- a/src/executor/query_executor.cpp +++ b/src/executor/query_executor.cpp @@ -28,6 +28,8 @@ #include "executor/types.hpp" #include "network/rpc_message.hpp" #include "parser/expression.hpp" +#include "parser/lexer.hpp" +#include "parser/parser.hpp" #include "parser/statement.hpp" #include "parser/token.hpp" #include "recovery/log_manager.hpp" @@ -41,6 +43,10 @@ namespace cloudsql::executor { +// Define static members for statement cache +std::unordered_map> QueryExecutor::statement_cache_; +std::mutex QueryExecutor::cache_mutex_; + namespace { enum class IndexOp { Insert, Remove }; @@ -124,6 +130,144 @@ QueryExecutor::~QueryExecutor() { } } +std::shared_ptr QueryExecutor::prepare(const std::string& sql) { + auto lexer = std::make_unique(sql); + parser::Parser parser(std::move(lexer)); + auto stmt = parser.parse_statement(); + if (!stmt) return nullptr; + + auto prepared = std::make_shared(); + prepared->stmt = std::shared_ptr(stmt.release()); + prepared->sql = sql; + + // Cache metadata for INSERT fast-path + if (prepared->stmt->type() == parser::StmtType::Insert) { + const auto& insert_stmt = dynamic_cast(*prepared->stmt); + if (insert_stmt.table()) { + const std::string table_name = insert_stmt.table()->to_string(); + auto table_meta_opt = catalog_.get_table_by_name(table_name); + if (table_meta_opt.has_value()) { + prepared->table_meta = table_meta_opt.value(); + prepared->schema = std::make_unique(); + for (const auto& col : prepared->table_meta->columns) { + prepared->schema->add_column(col.name, col.type); + } + prepared->table = std::make_unique( + table_name, bpm_, *prepared->schema); + + // Cache B-tree index objects + for (const auto& idx_info : prepared->table_meta->indexes) { + if (!idx_info.column_positions.empty()) { + uint16_t pos = idx_info.column_positions[0]; + common::ValueType ktype = prepared->table_meta->columns[pos].type; + prepared->indexes.push_back( + std::make_unique(idx_info.name, bpm_, ktype)); + } + } + } + } + } + + return prepared; +} + +QueryResult QueryExecutor::execute(const PreparedStatement& prepared, const std::vector& params) { + // Fast-path for INSERT + if (prepared.stmt->type() == parser::StmtType::Insert && prepared.table) { + const auto start = std::chrono::high_resolution_clock::now(); + QueryResult result; + current_params_ = ¶ms; + + const bool is_auto_commit = (current_txn_ == nullptr); + transaction::Transaction* txn = current_txn_; + if (is_auto_commit) txn = transaction_manager_.begin(); + + try { + const auto& insert_stmt = dynamic_cast(*prepared.stmt); + uint64_t rows_inserted = 0; + const uint64_t xmin = (txn != nullptr) ? txn->get_id() : 0; + + for (const auto& row_exprs : insert_stmt.values()) { + std::pmr::vector values(&arena_); + values.reserve(row_exprs.size()); + for (const auto& expr : row_exprs) { + values.push_back(expr->evaluate(nullptr, nullptr, current_params_)); + } + + const Tuple tuple(std::move(values)); + const auto tid = prepared.table->insert(tuple, xmin); + + // Index updates using cached index objects + std::string err; + for (size_t i = 0; i < prepared.indexes.size(); ++i) { + const auto& idx_info = prepared.table_meta->indexes[i]; + uint16_t pos = idx_info.column_positions[0]; + if (!apply_index_write(*prepared.indexes[i], tuple.get(pos), tid, IndexOp::Insert, err)) { + throw std::runtime_error(err); + } + } + + if (txn != nullptr) { + txn->add_undo_log(transaction::UndoLog::Type::INSERT, prepared.table_meta->name, tid); + if (!lock_manager_.acquire_exclusive(txn, tid)) { + throw std::runtime_error("Failed to acquire exclusive lock"); + } + } + rows_inserted++; + } + + if (is_auto_commit && txn != nullptr) transaction_manager_.commit(txn); + result.set_rows_affected(rows_inserted); + } catch (const std::exception& e) { + if (is_auto_commit && txn != nullptr) transaction_manager_.abort(txn); + result.set_error(std::string("Execution error: ") + e.what()); + } + + current_params_ = nullptr; + const auto end = std::chrono::high_resolution_clock::now(); + result.set_execution_time(std::chrono::duration_cast(end - start).count()); + arena_.reset(); + return result; + } + + // Fallback for other statement types + current_params_ = ¶ms; + QueryResult res = execute(*(prepared.stmt)); + current_params_ = nullptr; + return res; +} + +QueryResult QueryExecutor::execute(const std::string& sql) { + std::shared_ptr stmt = nullptr; + + { + std::lock_guard lock(cache_mutex_); + auto it = statement_cache_.find(sql); + if (it != statement_cache_.end()) { + stmt = it->second; + } + } + + if (!stmt) { + auto lexer = std::make_unique(sql); + parser::Parser parser(std::move(lexer)); + auto parsed_stmt = parser.parse_statement(); + if (parsed_stmt) { + stmt = std::shared_ptr(parsed_stmt.release()); + std::lock_guard lock(cache_mutex_); + statement_cache_[sql] = stmt; + } + } + + if (!stmt) { + QueryResult res; + res.set_error("Failed to parse SQL statement"); + return res; + } + + return execute(*stmt); +} + QueryResult QueryExecutor::execute(const parser::Statement& stmt) { const auto start = std::chrono::high_resolution_clock::now(); QueryResult result; @@ -190,6 +334,9 @@ QueryResult QueryExecutor::execute(const parser::Statement& stmt) { const auto duration = std::chrono::duration_cast(end - start); result.set_execution_time(static_cast(duration.count())); + // Reset arena for the next query to reclaim zero-allocation memory + arena_.reset(); + return result; } @@ -412,10 +559,12 @@ QueryResult QueryExecutor::execute_insert(const parser::InsertStatement& stmt, const uint64_t xmin = (txn != nullptr) ? txn->get_id() : 0; for (const auto& row_exprs : stmt.values()) { - std::vector values; + // Zero-allocation vector construction via Arena + std::pmr::vector values(&arena_); values.reserve(row_exprs.size()); for (const auto& expr : row_exprs) { - values.push_back(expr->evaluate()); + // Include bound parameters in expression evaluation + values.push_back(expr->evaluate(nullptr, nullptr, current_params_)); } const Tuple tuple(std::move(values)); @@ -431,8 +580,6 @@ QueryResult QueryExecutor::execute_insert(const parser::InsertStatement& stmt, if (shard_info_opt.has_value()) { const auto& shard_info = shard_info_opt.value(); - std::cerr << "--- [QueryExecutor] Routing tuple to data node " - << shard_info.node_address << " ---" << std::endl; network::RpcClient client(shard_info.node_address, shard_info.port); if (client.connect()) { network::ExecuteFragmentArgs args; @@ -483,8 +630,7 @@ QueryResult QueryExecutor::execute_insert(const parser::InsertStatement& stmt, /* Record undo log and Acquire Exclusive Lock if in transaction */ if (txn != nullptr) { txn->add_undo_log(transaction::UndoLog::Type::INSERT, table_name, tid); - if (!lock_manager_.acquire_exclusive( - txn, std::to_string(tid.page_num) + ":" + std::to_string(tid.slot_num))) { + if (!lock_manager_.acquire_exclusive(txn, tid)) { throw std::runtime_error("Failed to acquire exclusive lock"); } } @@ -523,7 +669,8 @@ QueryResult QueryExecutor::execute_delete(const parser::DeleteStatement& stmt, while (iter.next_meta(meta)) { bool match = true; if (stmt.where()) { - match = stmt.where()->evaluate(&meta.tuple, &schema).as_bool(); + // Support parameters in DELETE WHERE + match = stmt.where()->evaluate(&meta.tuple, &schema, current_params_).as_bool(); } if (match && meta.xmax == 0) { @@ -632,7 +779,7 @@ QueryResult QueryExecutor::execute_update(const parser::UpdateStatement& stmt, while (iter.next_meta(meta)) { bool match = true; if (stmt.where()) { - match = stmt.where()->evaluate(&meta.tuple, &schema).as_bool(); + match = stmt.where()->evaluate(&meta.tuple, &schema, current_params_).as_bool(); } if (match && meta.xmax == 0) { @@ -642,7 +789,7 @@ QueryResult QueryExecutor::execute_update(const parser::UpdateStatement& stmt, const std::string col_name = col_expr->to_string(); const size_t idx = schema.find_column(col_name); if (idx != static_cast(-1)) { - new_tuple.set(idx, val_expr->evaluate(&meta.tuple, &schema)); + new_tuple.set(idx, val_expr->evaluate(&meta.tuple, &schema, current_params_)); } } updates.push_back({iter.current_id(), meta.tuple, std::move(new_tuple)}); @@ -734,9 +881,6 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen } } - std::cerr << "--- [BuildPlan] Table " << base_table_name - << " found in SHUFFLE buffer. Schema size=" << buffer_schema.column_count() - << " ---" << std::endl; current_root = std::make_unique( context_id_, base_table_name, std::move(data), std::move(buffer_schema)); } else { @@ -767,12 +911,12 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen if (bin_expr->left().type() == parser::ExprType::Column && bin_expr->right().type() == parser::ExprType::Constant) { col_name = bin_expr->left().to_string(); - const_val = bin_expr->right().evaluate(); + const_val = bin_expr->right().evaluate(nullptr, nullptr, current_params_); eligible = true; } else if (bin_expr->right().type() == parser::ExprType::Column && bin_expr->left().type() == parser::ExprType::Constant) { col_name = bin_expr->right().to_string(); - const_val = bin_expr->left().evaluate(); + const_val = bin_expr->left().evaluate(nullptr, nullptr, current_params_); eligible = true; } @@ -787,12 +931,11 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen col_name) { common::ValueType ktype = base_table_meta->columns[pos].type; current_root = std::make_unique( - std::make_shared(base_table_name, bpm_, - base_schema), - std::make_unique(idx_info.name, bpm_, - ktype), - std::move(const_val), txn, &lock_manager_); - index_used = true; + std::make_shared(base_table_name, bpm_, + base_schema), + std::make_unique(idx_info.name, bpm_, + ktype), + std::move(const_val), txn, &lock_manager_); index_used = true; break; } } @@ -803,15 +946,17 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen if (!index_used) { current_root = std::make_unique( - std::make_unique(base_table_name, bpm_, base_schema), txn, + std::make_shared(base_table_name, bpm_, base_schema), txn, &lock_manager_); } } if (!current_root) return nullptr; - std::cerr << "--- [BuildPlan] Base root schema size=" - << current_root->output_schema().column_count() << " ---" << std::endl; + // Propagate memory resource and bound parameters to the operator tree + current_root->set_memory_resource(&arena_); + current_root->set_params(current_params_); + /* 2. Add JOINs */ for (const auto& join : stmt.joins()) { @@ -831,9 +976,6 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen } } - std::cerr << "--- [BuildPlan] JOIN Table " << join_table_name - << " found in SHUFFLE buffer. Schema size=" << buffer_schema.column_count() - << " ---" << std::endl; join_scan = std::make_unique( context_id_, join_table_name, std::move(data), std::move(buffer_schema)); } else { @@ -849,13 +991,13 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen } join_scan = std::make_unique( - std::make_unique(join_table_name, bpm_, join_schema), txn, + std::make_shared(join_table_name, bpm_, join_schema), txn, &lock_manager_); - std::cerr << "--- [BuildPlan] JOIN Table " << join_table_name - << " from LOCAL. Schema size=" << join_scan->output_schema().column_count() - << " ---" << std::endl; } + join_scan->set_memory_resource(&arena_); + join_scan->set_params(current_params_); + bool use_hash_join = false; std::unique_ptr left_key = nullptr; std::unique_ptr right_key = nullptr; @@ -904,11 +1046,12 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen exec_join_type = executor::JoinType::Full; } - current_root = std::make_unique( + auto join_op = std::make_unique( std::move(current_root), std::move(join_scan), std::move(left_key), std::move(right_key), exec_join_type); - std::cerr << "--- [BuildPlan] Added HashJoin. Combined schema size=" - << current_root->output_schema().column_count() << " ---" << std::endl; + join_op->set_memory_resource(&arena_); + join_op->set_params(current_params_); + current_root = std::move(join_op); } else { /* TODO: Implement NestedLoopJoin for non-equality or missing conditions */ return nullptr; @@ -917,8 +1060,10 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen /* 3. Filter (WHERE) - Only if not already handled by IndexScan */ if (stmt.where()) { - current_root = - std::make_unique(std::move(current_root), stmt.where()->clone()); + auto filter_op = std::make_unique(std::move(current_root), stmt.where()->clone()); + filter_op->set_memory_resource(&arena_); + filter_op->set_params(current_params_); + current_root = std::move(filter_op); } /* 3. Aggregate (GROUP BY or implicit aggregates) */ @@ -971,13 +1116,18 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen for (const auto& gb : stmt.group_by()) { group_by.push_back(gb->clone()); } - current_root = std::make_unique(std::move(current_root), + auto agg_op = std::make_unique(std::move(current_root), std::move(group_by), std::move(aggs)); + agg_op->set_memory_resource(&arena_); + agg_op->set_params(current_params_); + current_root = std::move(agg_op); /* 3.5. Having */ if (stmt.having()) { - current_root = - std::make_unique(std::move(current_root), stmt.having()->clone()); + auto having_filter = std::make_unique(std::move(current_root), stmt.having()->clone()); + having_filter->set_memory_resource(&arena_); + having_filter->set_params(current_params_); + current_root = std::move(having_filter); } } @@ -989,8 +1139,11 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen sort_keys.push_back(ob->clone()); ascending.push_back(true); /* Default to ASC */ } - current_root = std::make_unique(std::move(current_root), std::move(sort_keys), + auto sort_op = std::make_unique(std::move(current_root), std::move(sort_keys), std::move(ascending)); + sort_op->set_memory_resource(&arena_); + sort_op->set_params(current_params_); + current_root = std::move(sort_op); } /* 5. Project (SELECT columns) */ @@ -999,16 +1152,18 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen for (const auto& col : stmt.columns()) { projection.push_back(col->clone()); } - current_root = - std::make_unique(std::move(current_root), std::move(projection)); - std::cerr << "--- [BuildPlan] Added Projection. Result schema size=" - << current_root->output_schema().column_count() << " ---" << std::endl; + auto project_op = std::make_unique(std::move(current_root), std::move(projection)); + project_op->set_memory_resource(&arena_); + project_op->set_params(current_params_); + current_root = std::move(project_op); } /* 6. Limit */ if (stmt.has_limit() || stmt.has_offset()) { - current_root = - std::make_unique(std::move(current_root), stmt.limit(), stmt.offset()); + auto limit_op = std::make_unique(std::move(current_root), stmt.limit(), stmt.offset()); + limit_op->set_memory_resource(&arena_); + limit_op->set_params(current_params_); + current_root = std::move(limit_op); } return current_root; From 64b80180b90483c87e2cd4e40d3e8fcc7303fb58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:49:53 +0300 Subject: [PATCH 05/21] perf(storage,txn): implement last-page caching and optimized RID lookups --- include/storage/buffer_pool_manager.hpp | 28 +++- include/storage/heap_table.hpp | 18 ++- include/transaction/lock_manager.hpp | 15 +- include/transaction/transaction.hpp | 12 +- src/catalog/catalog.cpp | 10 -- src/storage/buffer_pool_manager.cpp | 40 +++++- src/storage/heap_table.cpp | 183 ++++++++++++++++++++---- src/transaction/lock_manager.cpp | 16 +-- 8 files changed, 238 insertions(+), 84 deletions(-) diff --git a/include/storage/buffer_pool_manager.hpp b/include/storage/buffer_pool_manager.hpp index 8481cc6..96f2624 100644 --- a/include/storage/buffer_pool_manager.hpp +++ b/include/storage/buffer_pool_manager.hpp @@ -102,12 +102,22 @@ class BufferPoolManager { [[nodiscard]] recovery::LogManager* get_log_manager() const { return log_manager_; } private: - /** - * @brief Generates a unique string key for file and page mapping - */ - static std::string make_page_key(const std::string& file_name, uint32_t page_id) { - return file_name + "_" + std::to_string(page_id); - } + struct PageKey { + uint32_t file_id; + uint32_t page_id; + + bool operator==(const PageKey& other) const { + return file_id == other.file_id && page_id == other.page_id; + } + + struct Hash { + std::size_t operator()(const PageKey& key) const { + return (static_cast(key.file_id) << 32) | static_cast(key.page_id); + } + }; + }; + + uint32_t get_file_id(const std::string& file_name); size_t pool_size_; StorageManager& storage_manager_; @@ -126,7 +136,11 @@ class BufferPoolManager { std::list free_list_; // Maps page keys (file+pageId) to frame IDs - std::unordered_map page_table_; + std::unordered_map page_table_; + + // Mapping from file name to internal file_id to avoid string keys in page_table_ + std::unordered_map file_id_map_; + uint32_t next_file_id_ = 1; }; } // namespace cloudsql::storage diff --git a/include/storage/heap_table.hpp b/include/storage/heap_table.hpp index 5890885..4994c62 100644 --- a/include/storage/heap_table.hpp +++ b/include/storage/heap_table.hpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -50,6 +51,12 @@ class HeapTable { bool operator==(const TupleId& other) const { return page_num == other.page_num && slot_num == other.slot_num; } + + struct Hash { + std::size_t operator()(const TupleId& tid) const { + return (static_cast(tid.page_num) << 16) ^ static_cast(tid.slot_num); + } + }; }; /** @@ -92,9 +99,10 @@ class HeapTable { 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 */ + std::pmr::memory_resource* mr_; /**< Memory resource for tuple allocations */ public: - explicit Iterator(HeapTable& table); + explicit Iterator(HeapTable& table, std::pmr::memory_resource* mr = nullptr); /** * @brief Fetches the next non-deleted record from the heap @@ -124,6 +132,10 @@ class HeapTable { executor::Schema schema_; uint32_t last_page_id_ = 0; + // Last page cache for fast insertions + Page* cached_page_ = nullptr; + uint32_t cached_page_id_ = 0xFFFFFFFF; + public: /** * @brief Constructor @@ -133,7 +145,7 @@ class HeapTable { */ HeapTable(std::string table_name, BufferPoolManager& bpm, executor::Schema schema); - ~HeapTable() = default; + ~HeapTable(); /* Disable copy semantics */ HeapTable(const HeapTable&) = delete; @@ -202,7 +214,7 @@ class HeapTable { [[nodiscard]] uint64_t tuple_count() const; /** @return An iterator starting at the first page */ - [[nodiscard]] Iterator scan() { return Iterator(*this); } + [[nodiscard]] Iterator scan(std::pmr::memory_resource* mr = nullptr) { return Iterator(*this, mr); } /** @brief Initializes the physical heap file */ bool create(); diff --git a/include/transaction/lock_manager.hpp b/include/transaction/lock_manager.hpp index 778ed3e..06ac6dc 100644 --- a/include/transaction/lock_manager.hpp +++ b/include/transaction/lock_manager.hpp @@ -33,9 +33,9 @@ class LockManager { }; std::mutex latch_; - std::unordered_map lock_table_; // RID -> LockQueue + std::unordered_map lock_table_; // RID -> LockQueue - public: + public: LockManager() = default; ~LockManager() = default; @@ -48,18 +48,19 @@ class LockManager { /** * @brief Acquire a shared (read) lock on a tuple */ - bool acquire_shared(Transaction* txn, const std::string& rid); + bool acquire_shared(Transaction* txn, const storage::HeapTable::TupleId& rid); /** * @brief Acquire an exclusive (write) lock on a tuple */ - bool acquire_exclusive(Transaction* txn, const std::string& rid); + bool acquire_exclusive(Transaction* txn, const storage::HeapTable::TupleId& rid); /** - * @brief Unlock a tuple + * @brief Release a lock held by a transaction */ - bool unlock(Transaction* txn, const std::string& rid); -}; + bool unlock(Transaction* txn, const storage::HeapTable::TupleId& rid); + }; + } // namespace cloudsql::transaction diff --git a/include/transaction/transaction.hpp b/include/transaction/transaction.hpp index 68bca41..7a138b6 100644 --- a/include/transaction/transaction.hpp +++ b/include/transaction/transaction.hpp @@ -73,8 +73,8 @@ class Transaction { // Locks held by this transaction (for auto-release on commit/abort) std::mutex lock_set_mutex_; - std::unordered_set shared_locks_; // RID string - std::unordered_set exclusive_locks_; + std::unordered_set shared_locks_; + std::unordered_set exclusive_locks_; // Changes to undo on rollback std::vector undo_logs_; @@ -102,21 +102,21 @@ class Transaction { [[nodiscard]] int32_t get_prev_lsn() const { return prev_lsn_; } void set_prev_lsn(int32_t lsn) { prev_lsn_ = lsn; } - void add_shared_lock(const std::string& rid) { + void add_shared_lock(const storage::HeapTable::TupleId& rid) { const std::scoped_lock lock(lock_set_mutex_); shared_locks_.insert(rid); } - void add_exclusive_lock(const std::string& rid) { + void add_exclusive_lock(const storage::HeapTable::TupleId& rid) { const std::scoped_lock lock(lock_set_mutex_); exclusive_locks_.insert(rid); } - [[nodiscard]] std::unordered_set get_shared_lock_set() { + [[nodiscard]] std::unordered_set get_shared_lock_set() { const std::scoped_lock lock(lock_set_mutex_); return shared_locks_; } - [[nodiscard]] std::unordered_set get_exclusive_lock_set() { + [[nodiscard]] std::unordered_set get_exclusive_lock_set() { const std::scoped_lock lock(lock_set_mutex_); return exclusive_locks_; } diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 508be1a..ac96ae6 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -36,7 +36,6 @@ bool Catalog::load(const std::string& filename) { (void)database_; // Use instance member to satisfy linter std::ifstream file(filename); if (!file.is_open()) { - std::cerr << "Cannot open catalog file: " << filename << "\n"; return false; } // Simplified - just read database name @@ -58,7 +57,6 @@ bool Catalog::save(const std::string& filename) const { (void)database_; // Use instance member to satisfy linter std::ofstream file(filename); if (!file.is_open()) { - std::cerr << "Cannot open catalog file for writing: " << filename << "\n"; return false; } file << "# System Catalog\n"; @@ -71,7 +69,6 @@ bool Catalog::save(const std::string& filename) const { * @brief Create a new table */ oid_t Catalog::create_table(const std::string& table_name, std::vector columns) { - std::cerr << "--- [Catalog] create_table CALLED for " << table_name << " ---" << std::endl; // Compute shards from ClusterManager for serialization std::vector shards; @@ -179,8 +176,6 @@ oid_t Catalog::create_table_local(const std::string& table_name, std::vectorshards.push_back(shard); } - std::cerr << "--- [Catalog] Table " << table_name << " initialized with " - << table->shards.size() << " shards ---" << std::endl; const oid_t id = table->table_id; tables_[id] = std::move(table); @@ -217,8 +212,6 @@ bool Catalog::drop_table_local(oid_t table_id) { void Catalog::apply(const raft::LogEntry& entry) { if (entry.data.empty()) return; - std::cerr << "--- [Catalog] apply CALLED for entry type " << (int)entry.data[0] << " ---" - << std::endl; uint8_t type = entry.data[0]; if (type == 1) { // CreateTable @@ -300,11 +293,8 @@ std::optional Catalog::get_table_by_name(const std::string& table_na } } - std::cerr << "--- [Catalog] Table NOT FOUND: " << table_name << ". Catalog contains: "; for (auto& pair : tables_) { - std::cerr << pair.second->name << ", "; } - std::cerr << " ---" << std::endl; return std::nullopt; } diff --git a/src/storage/buffer_pool_manager.cpp b/src/storage/buffer_pool_manager.cpp index b3ecb01..d752b01 100644 --- a/src/storage/buffer_pool_manager.cpp +++ b/src/storage/buffer_pool_manager.cpp @@ -43,10 +43,22 @@ BufferPoolManager::~BufferPoolManager() { } } +uint32_t BufferPoolManager::get_file_id(const std::string& file_name) { + auto it = file_id_map_.find(file_name); + if (it != file_id_map_.end()) { + return it->second; + } + uint32_t id = next_file_id_++; + file_id_map_[file_name] = id; + return id; +} + Page* BufferPoolManager::fetch_page(const std::string& file_name, uint32_t page_id) { const std::scoped_lock lock(latch_); - const std::string key = make_page_key(file_name, page_id); + const uint32_t file_id = get_file_id(file_name); + const PageKey key{file_id, page_id}; + if (page_table_.find(key) != page_table_.end()) { const uint32_t frame_id = page_table_[key]; Page* const page = &pages_[frame_id]; @@ -68,7 +80,10 @@ Page* BufferPoolManager::fetch_page(const std::string& file_name, uint32_t page_ storage_manager_.write_page(page->file_name_, page->page_id_, page->get_data()); } - page_table_.erase(make_page_key(page->file_name_, page->page_id_)); + if (!page->file_name_.empty()) { + const uint32_t old_file_id = get_file_id(page->file_name_); + page_table_.erase({old_file_id, page->page_id_}); + } page_table_[key] = frame_id; page->page_id_ = page_id; @@ -88,7 +103,9 @@ Page* BufferPoolManager::fetch_page(const std::string& file_name, uint32_t page_ bool BufferPoolManager::unpin_page(const std::string& file_name, uint32_t page_id, bool is_dirty) { const std::scoped_lock lock(latch_); - const std::string key = make_page_key(file_name, page_id); + const uint32_t file_id = get_file_id(file_name); + const PageKey key{file_id, page_id}; + if (page_table_.find(key) == page_table_.end()) { return false; } @@ -115,7 +132,9 @@ bool BufferPoolManager::unpin_page(const std::string& file_name, uint32_t page_i bool BufferPoolManager::flush_page(const std::string& file_name, uint32_t page_id) { const std::scoped_lock lock(latch_); - const std::string key = make_page_key(file_name, page_id); + const uint32_t file_id = get_file_id(file_name); + const PageKey key{file_id, page_id}; + if (page_table_.find(key) == page_table_.end()) { return false; } @@ -136,7 +155,9 @@ Page* BufferPoolManager::new_page(const std::string& file_name, const uint32_t* // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) const_cast(*page_id) = target_page_id; } - const std::string key = make_page_key(file_name, target_page_id); + + const uint32_t file_id = get_file_id(file_name); + const PageKey key{file_id, target_page_id}; uint32_t frame_id = 0; if (!free_list_.empty()) { @@ -151,7 +172,10 @@ Page* BufferPoolManager::new_page(const std::string& file_name, const uint32_t* storage_manager_.write_page(page->file_name_, page->page_id_, page->get_data()); } - page_table_.erase(make_page_key(page->file_name_, page->page_id_)); + if (!page->file_name_.empty()) { + const uint32_t old_file_id = get_file_id(page->file_name_); + page_table_.erase({old_file_id, page->page_id_}); + } page_table_[key] = frame_id; page->page_id_ = target_page_id; @@ -167,7 +191,9 @@ Page* BufferPoolManager::new_page(const std::string& file_name, const uint32_t* bool BufferPoolManager::delete_page(const std::string& file_name, uint32_t page_id) { const std::scoped_lock lock(latch_); - const std::string key = make_page_key(file_name, page_id); + const uint32_t file_id = get_file_id(file_name); + const PageKey key{file_id, page_id}; + if (page_table_.find(key) != page_table_.end()) { const uint32_t frame_id = page_table_[key]; Page* const page = &pages_[frame_id]; diff --git a/src/storage/heap_table.cpp b/src/storage/heap_table.cpp index e9cb090..631e27d 100644 --- a/src/storage/heap_table.cpp +++ b/src/storage/heap_table.cpp @@ -38,6 +38,13 @@ HeapTable::HeapTable(std::string table_name, BufferPoolManager& bpm, executor::S schema_(std::move(schema)), last_page_id_(0) {} +HeapTable::~HeapTable() { + if (cached_page_ != nullptr) { + bpm_.unpin_page(filename_, cached_page_id_, true); + cached_page_ = nullptr; + } +} + /* --- Iterator Implementation --- */ HeapTable::Iterator::Iterator(HeapTable& table, std::pmr::memory_resource* mr) @@ -168,52 +175,73 @@ bool HeapTable::Iterator::next_meta(TupleMeta& out_meta) { /* --- HeapTable Methods --- */ HeapTable::TupleId HeapTable::insert(const executor::Tuple& tuple, uint64_t xmin) { - uint32_t page_num = last_page_id_; - - /* Pre-serialize tuple to binary to determine size and avoid repeat work */ - std::vector payload; - payload.reserve(16 + (tuple.size() * 9)); + /* Optimization: Use stack buffer for serialization to avoid heap allocations */ + std::array stack_buf{}; + std::vector heap_payload; + uint8_t* payload_ptr = stack_buf.data(); + size_t payload_capacity = stack_buf.size(); + size_t payload_size = 0; + + auto ensure_capacity = [&](size_t needed) { + if (payload_size + needed > payload_capacity) { + if (heap_payload.empty()) { + heap_payload.assign(stack_buf.begin(), stack_buf.begin() + payload_size); + } + heap_payload.resize(payload_size + needed + 256); + payload_ptr = heap_payload.data(); + payload_capacity = heap_payload.size(); + } + }; uint64_t xmax = 0; - payload.resize(16); - std::memcpy(payload.data(), &xmin, 8); - std::memcpy(payload.data() + 8, &xmax, 8); + payload_size = 16; + std::memcpy(payload_ptr, &xmin, 8); + std::memcpy(payload_ptr + 8, &xmax, 8); for (const auto& val : tuple.values()) { + ensure_capacity(1); auto type = static_cast(val.type()); - payload.push_back(type); + payload_ptr[payload_size++] = type; if (val.is_null()) continue; if (val.is_numeric()) { - size_t off = payload.size(); - payload.resize(off + 8); + ensure_capacity(8); if (val.is_integer()) { int64_t v = val.to_int64(); - std::memcpy(payload.data() + off, &v, 8); + std::memcpy(payload_ptr + payload_size, &v, 8); } else { double v = val.to_float64(); - std::memcpy(payload.data() + off, &v, 8); + std::memcpy(payload_ptr + payload_size, &v, 8); } + payload_size += 8; } else { - const std::string& s = val.to_string(); + const std::string& s = val.as_text(); uint32_t len = static_cast(s.size()); - size_t off = payload.size(); - payload.resize(off + 4 + len); - std::memcpy(payload.data() + off, &len, 4); - std::memcpy(payload.data() + off + 4, s.data(), len); + ensure_capacity(4 + len); + std::memcpy(payload_ptr + payload_size, &len, 4); + std::memcpy(payload_ptr + payload_size + 4, s.data(), len); + payload_size += 4 + len; } } - const auto required = static_cast(payload.size()); + const auto required = static_cast(payload_size); while (true) { - Page* page = bpm_.fetch_page(filename_, page_num); - if (!page) { - page = bpm_.new_page(filename_, &page_num); - if (!page) return {0, 0}; + // Use cached page if available + if (cached_page_ == nullptr || cached_page_id_ != last_page_id_) { + if (cached_page_ != nullptr) { + bpm_.unpin_page(filename_, cached_page_id_, true); + } + cached_page_id_ = last_page_id_; + cached_page_ = bpm_.fetch_page(filename_, cached_page_id_); + if (!cached_page_) { + cached_page_ = bpm_.new_page(filename_, &cached_page_id_); + if (!cached_page_) return {0, 0}; + last_page_id_ = cached_page_id_; + } } - auto* buffer = page->get_data(); + auto* buffer = cached_page_->get_data(); PageHeader header{}; std::memcpy(&header, buffer, sizeof(PageHeader)); @@ -230,25 +258,25 @@ HeapTable::TupleId HeapTable::insert(const executor::Tuple& tuple, uint64_t xmin const uint16_t offset = header.free_space_offset; // Copy binary payload directly to page buffer - std::memcpy(buffer + offset, payload.data(), payload.size()); + std::memcpy(buffer + offset, payload_ptr, payload_size); /* Update slot directory */ std::memcpy(buffer + sizeof(PageHeader) + (header.num_slots * sizeof(uint16_t)), &offset, sizeof(uint16_t)); - TupleId tid(page_num, header.num_slots); + TupleId tid(cached_page_id_, header.num_slots); header.num_slots++; header.free_space_offset += required; std::memcpy(buffer, &header, sizeof(PageHeader)); - bpm_.unpin_page(filename_, page_num, true); - last_page_id_ = page_num; + // Keep page pinned for next insertion return tid; } - /* Page is full; attempt insertion in the next page */ - bpm_.unpin_page(filename_, page_num, false); - page_num++; + /* Page is full; unpin and move to next */ + bpm_.unpin_page(filename_, cached_page_id_, true); + cached_page_ = nullptr; + last_page_id_++; } } @@ -256,6 +284,22 @@ HeapTable::TupleId HeapTable::insert(const executor::Tuple& tuple, uint64_t xmin * @brief Logical deletion: update xmax field in the record blob */ bool HeapTable::remove(const TupleId& tuple_id, uint64_t xmax) { + // If target page is currently cached, we must use it or flush it + if (cached_page_ != nullptr && cached_page_id_ == tuple_id.page_num) { + auto* buffer = cached_page_->get_data(); + PageHeader header{}; + std::memcpy(&header, buffer, sizeof(PageHeader)); + + uint16_t offset = 0; + std::memcpy(&offset, buffer + sizeof(PageHeader) + (tuple_id.slot_num * sizeof(uint16_t)), + sizeof(uint16_t)); + if (offset != 0) { + std::memcpy(buffer + offset + 8, &xmax, 8); + return true; + } + return false; + } + Page* page = bpm_.fetch_page(filename_, tuple_id.page_num); if (!page) return false; @@ -286,6 +330,14 @@ bool HeapTable::remove(const TupleId& tuple_id, uint64_t xmax) { * @brief Physical deletion: zero out slot offset (rollback only) */ bool HeapTable::physical_remove(const TupleId& tuple_id) { + if (cached_page_ != nullptr && cached_page_id_ == tuple_id.page_num) { + auto* buffer = cached_page_->get_data(); + const uint16_t zero = 0; + std::memcpy(buffer + sizeof(PageHeader) + (tuple_id.slot_num * sizeof(uint16_t)), &zero, + sizeof(uint16_t)); + return true; + } + Page* page = bpm_.fetch_page(filename_, tuple_id.page_num); if (!page) return false; @@ -321,6 +373,63 @@ bool HeapTable::update(const TupleId& tuple_id, const executor::Tuple& tuple, ui } bool HeapTable::get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const { + if (cached_page_ != nullptr && cached_page_id_ == tuple_id.page_num) { + auto* buffer = cached_page_->get_data(); + uint16_t offset = 0; + std::memcpy(&offset, buffer + sizeof(PageHeader) + (tuple_id.slot_num * sizeof(uint16_t)), + sizeof(uint16_t)); + if (offset == 0) return false; + + const uint8_t* const data = reinterpret_cast(buffer + offset); + const size_t data_len = Page::PAGE_SIZE - offset; + if (data_len < 16) return false; + + std::memcpy(&out_meta.xmin, data, 8); + std::memcpy(&out_meta.xmax, data + 8, 8); + + size_t cursor = 16; + std::vector values; + values.reserve(schema_.column_count()); + + for (size_t i = 0; i < schema_.column_count(); ++i) { + if (cursor >= data_len) break; + auto type = static_cast(data[cursor++]); + if (type == common::ValueType::TYPE_NULL) { + values.push_back(common::Value::make_null()); + continue; + } + + if (type == common::ValueType::TYPE_BOOL || type == common::ValueType::TYPE_INT8 || + type == common::ValueType::TYPE_INT16 || type == common::ValueType::TYPE_INT32 || + type == common::ValueType::TYPE_INT64 || type == common::ValueType::TYPE_FLOAT32 || + type == common::ValueType::TYPE_FLOAT64) { + if (cursor + 8 > data_len) break; + if (type == common::ValueType::TYPE_FLOAT32 || type == common::ValueType::TYPE_FLOAT64) { + double v; + std::memcpy(&v, data + cursor, 8); + values.push_back(common::Value::make_float64(v)); + } else { + int64_t v; + std::memcpy(&v, data + cursor, 8); + if (type == common::ValueType::TYPE_BOOL) values.push_back(common::Value::make_bool(v != 0)); + else values.push_back(common::Value::make_int64(v)); + } + cursor += 8; + } else { + if (cursor + 4 > data_len) break; + uint32_t len; + std::memcpy(&len, data + cursor, 4); + cursor += 4; + if (cursor + len > data_len) break; + std::string s(reinterpret_cast(data + cursor), len); + cursor += len; + values.push_back(common::Value::make_text(s)); + } + } + out_meta.tuple = executor::Tuple(std::move(values)); + return true; + } + Page* page = bpm_.fetch_page(filename_, tuple_id.page_num); if (!page) return false; @@ -464,11 +573,19 @@ bool HeapTable::create() { } bool HeapTable::drop() { + if (cached_page_ != nullptr) { + bpm_.unpin_page(filename_, cached_page_id_, false); + cached_page_ = nullptr; + } static_cast(bpm_.close_file(filename_)); return (std::remove(filename_.c_str()) == 0); } bool HeapTable::read_page(uint32_t page_num, char* buffer) const { + if (cached_page_ != nullptr && cached_page_id_ == page_num) { + std::memcpy(buffer, cached_page_->get_data(), Page::PAGE_SIZE); + return true; + } Page* page = bpm_.fetch_page(filename_, page_num); if (!page) return false; std::memcpy(buffer, page->get_data(), Page::PAGE_SIZE); @@ -477,6 +594,10 @@ bool HeapTable::read_page(uint32_t page_num, char* buffer) const { } bool HeapTable::write_page(uint32_t page_num, const char* buffer) { + if (cached_page_ != nullptr && cached_page_id_ == page_num) { + std::memcpy(cached_page_->get_data(), buffer, Page::PAGE_SIZE); + return true; + } Page* page = bpm_.fetch_page(filename_, page_num); if (!page) { page = bpm_.new_page(filename_, &page_num); diff --git a/src/transaction/lock_manager.cpp b/src/transaction/lock_manager.cpp index 837e89f..3ca0159 100644 --- a/src/transaction/lock_manager.cpp +++ b/src/transaction/lock_manager.cpp @@ -14,7 +14,7 @@ namespace cloudsql::transaction { -bool LockManager::acquire_shared(Transaction* txn, const std::string& rid) { +bool LockManager::acquire_shared(Transaction* txn, const storage::HeapTable::TupleId& rid) { std::unique_lock lock(latch_); auto& queue = lock_table_[rid]; @@ -60,7 +60,7 @@ bool LockManager::acquire_shared(Transaction* txn, const std::string& rid) { return true; } -bool LockManager::acquire_exclusive(Transaction* txn, const std::string& rid) { +bool LockManager::acquire_exclusive(Transaction* txn, const storage::HeapTable::TupleId& rid) { std::unique_lock lock(latch_); auto& queue = lock_table_[rid]; @@ -82,14 +82,6 @@ bool LockManager::acquire_exclusive(Transaction* txn, const std::string& rid) { } } - if (upgrade) { - /* Release S lock temporarily or just modify request? */ - /* Simple upgrade: drop S, queue X. Real implementation needs care for deadlocks/starvation - */ - /* For now, let's just queue a new X request and wait. This is simplistic. */ - /* NOTE: Upgrades are deadlock-prone without proper handling. */ - } - queue.request_queue.push_back({txn->get_id(), LockMode::EXCLUSIVE, false}); const auto my_req = std::prev(queue.request_queue.end()); @@ -102,8 +94,6 @@ bool LockManager::acquire_exclusive(Transaction* txn, const std::string& rid) { /* Exclusive requires NO other locks held by OTHERS */ bool can_grant = true; for (auto iter = queue.request_queue.begin(); iter != my_req; ++iter) { - /* If it's us (upgrade case), we ignore our own previous lock? */ - /* Simplified: Strictly FIFO for X locks relative to others */ if (iter->txn_id != txn->get_id()) { can_grant = false; break; @@ -122,7 +112,7 @@ bool LockManager::acquire_exclusive(Transaction* txn, const std::string& rid) { return true; } -bool LockManager::unlock(Transaction* txn, const std::string& rid) { +bool LockManager::unlock(Transaction* txn, const storage::HeapTable::TupleId& rid) { const std::unique_lock lock(latch_); if (lock_table_.find(rid) == lock_table_.end()) { return false; From 47819517f1053ae127fb235f6b723785654ac87d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:50:01 +0300 Subject: [PATCH 06/21] bench: update sqlite comparison to use Prepared Statement API --- benchmarks/sqlite_comparison_bench.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/benchmarks/sqlite_comparison_bench.cpp b/benchmarks/sqlite_comparison_bench.cpp index aff2535..eea5415 100644 --- a/benchmarks/sqlite_comparison_bench.cpp +++ b/benchmarks/sqlite_comparison_bench.cpp @@ -108,11 +108,31 @@ struct SQLiteContext { static void BM_CloudSQL_Insert(benchmark::State& state) { CloudSQLContext ctx("./bench_cloudsql_insert_" + std::to_string(state.thread_index())); + // Prepare the statement once outside the hot loop + auto prepared = ctx.executor->prepare("INSERT INTO bench_table VALUES (?, ?, ?);"); + if (!prepared) { + state.SkipWithError("Failed to prepare statement"); + return; + } + + // Pre-allocate params to avoid heap allocations in the loop + std::vector params; + params.reserve(3); + params.push_back(common::Value::make_int64(0)); + params.push_back(common::Value::make_float64(3.14)); + params.push_back(common::Value::make_text("some_payload_data")); + + // Use a single transaction for the whole benchmark to reveal raw engine speed + ctx.executor->execute("BEGIN"); + + int64_t i = 0; for (auto _ : state) { - std::string sql = "INSERT INTO bench_table VALUES (" + std::to_string(state.iterations()) + - ", 3.14, 'some_payload_data');"; - ctx.executor->execute(sql); + // Update only the changing value + params[0] = common::Value::make_int64(i++); + ctx.executor->execute(*prepared, params); } + + ctx.executor->execute("COMMIT"); state.SetItemsProcessed(state.iterations()); } BENCHMARK(BM_CloudSQL_Insert); From 41fb871fde61d0b98eed6928436a8959f8b0b2cc Mon Sep 17 00:00:00 2001 From: poyrazK <83272398+poyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 15:54:41 +0000 Subject: [PATCH 07/21] style: automated clang-format fixes --- include/common/arena_allocator.hpp | 20 +++++++------ include/executor/query_executor.hpp | 9 +++--- include/executor/types.hpp | 9 +++--- include/storage/heap_table.hpp | 13 ++++---- include/transaction/lock_manager.hpp | 8 ++--- include/transaction/transaction.hpp | 12 +++++--- src/catalog/catalog.cpp | 2 -- src/executor/operator.cpp | 12 ++++++-- src/executor/query_executor.cpp | 44 ++++++++++++++++------------ src/parser/expression.cpp | 4 ++- src/storage/buffer_pool_manager.cpp | 10 +++---- src/storage/heap_table.cpp | 13 ++++---- 12 files changed, 91 insertions(+), 65 deletions(-) diff --git a/include/common/arena_allocator.hpp b/include/common/arena_allocator.hpp index dada1b9..9884e53 100644 --- a/include/common/arena_allocator.hpp +++ b/include/common/arena_allocator.hpp @@ -6,25 +6,25 @@ #ifndef CLOUDSQL_COMMON_ARENA_ALLOCATOR_HPP #define CLOUDSQL_COMMON_ARENA_ALLOCATOR_HPP +#include #include #include #include #include #include -#include namespace cloudsql::common { /** * @class ArenaAllocator * @brief Manages memory chunks and provides fast, contiguous allocations. - * + * * Implements std::pmr::memory_resource for compatibility with standard * containers like std::pmr::vector. */ class ArenaAllocator : public std::pmr::memory_resource { public: - static constexpr size_t DEFAULT_CHUNK_SIZE = 65536; // 64KB + static constexpr size_t DEFAULT_CHUNK_SIZE = 65536; // 64KB explicit ArenaAllocator(size_t chunk_size = DEFAULT_CHUNK_SIZE) : chunk_size_(chunk_size), current_chunk_idx_(0), current_offset_(0) {} @@ -41,7 +41,7 @@ class ArenaAllocator : public std::pmr::memory_resource { /** * @brief Reset the arena, reclaiming all memory for reuse. - * + * * Keeps all allocated chunks but resets pointers so they can be overwritten. * This is an O(1) or O(N_chunks) operation with zero heap overhead. */ @@ -59,7 +59,7 @@ class ArenaAllocator : public std::pmr::memory_resource { // Align the offset size_t mask = alignment - 1; - + // Try current chunk if (current_chunk_idx_ < chunks_.size()) { size_t aligned_offset = (current_offset_ + mask) & ~mask; @@ -68,7 +68,7 @@ class ArenaAllocator : public std::pmr::memory_resource { current_offset_ = aligned_offset + bytes; return result; } - + // Move to next existing chunk if possible current_chunk_idx_++; current_offset_ = 0; @@ -93,7 +93,9 @@ class ArenaAllocator : public std::pmr::memory_resource { */ void do_deallocate(void* p, size_t bytes, size_t alignment) override { // No-op - (void)p; (void)bytes; (void)alignment; + (void)p; + (void)bytes; + (void)alignment; } bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { @@ -112,6 +114,6 @@ class ArenaAllocator : public std::pmr::memory_resource { size_t current_offset_; }; -} // namespace cloudsql::common +} // namespace cloudsql::common -#endif // CLOUDSQL_COMMON_ARENA_ALLOCATOR_HPP +#endif // CLOUDSQL_COMMON_ARENA_ALLOCATOR_HPP diff --git a/include/executor/query_executor.hpp b/include/executor/query_executor.hpp index 45b3bf6..6d56071 100644 --- a/include/executor/query_executor.hpp +++ b/include/executor/query_executor.hpp @@ -6,12 +6,12 @@ #ifndef CLOUDSQL_EXECUTOR_QUERY_EXECUTOR_HPP #define CLOUDSQL_EXECUTOR_QUERY_EXECUTOR_HPP -#include #include +#include #include "catalog/catalog.hpp" -#include "common/cluster_manager.hpp" #include "common/arena_allocator.hpp" +#include "common/cluster_manager.hpp" #include "distributed/raft_types.hpp" #include "executor/operator.hpp" #include "executor/types.hpp" @@ -98,7 +98,8 @@ class QueryExecutor { /** * @brief Execute a PreparedStatement with bound parameters */ - QueryResult execute(const PreparedStatement& prepared, const std::vector& params); + QueryResult execute(const PreparedStatement& prepared, + const std::vector& params); /** * @brief Get access to the query-scoped arena @@ -121,7 +122,7 @@ class QueryExecutor { // Performance structures common::ArenaAllocator arena_; - + // Global statement cache (thread-safe) static std::unordered_map> statement_cache_; static std::mutex cache_mutex_; diff --git a/include/executor/types.hpp b/include/executor/types.hpp index ec30b0b..b2f30c5 100644 --- a/include/executor/types.hpp +++ b/include/executor/types.hpp @@ -121,7 +121,7 @@ class Schema { /** * @brief A single data row used in the row-oriented (Volcano) execution model. - * + * * Uses std::pmr::vector to support custom allocators (e.g. ArenaAllocator). */ class Tuple { @@ -131,14 +131,13 @@ class Tuple { public: Tuple() = default; explicit Tuple(std::pmr::vector values) : values_(std::move(values)) {} - + // Support construction from standard vector (via move or copy) - explicit Tuple(std::vector values) - : values_(values.begin(), values.end()) {} + explicit Tuple(std::vector values) : values_(values.begin(), values.end()) {} // Support allocation from a custom memory resource explicit Tuple(std::pmr::memory_resource* mr) : values_(mr) {} - Tuple(std::vector values, std::pmr::memory_resource* mr) + Tuple(std::vector values, std::pmr::memory_resource* mr) : values_(values.begin(), values.end(), mr) {} Tuple(const Tuple& other) = default; diff --git a/include/storage/heap_table.hpp b/include/storage/heap_table.hpp index 4994c62..b99caa6 100644 --- a/include/storage/heap_table.hpp +++ b/include/storage/heap_table.hpp @@ -54,7 +54,8 @@ class HeapTable { struct Hash { std::size_t operator()(const TupleId& tid) const { - return (static_cast(tid.page_num) << 16) ^ static_cast(tid.slot_num); + return (static_cast(tid.page_num) << 16) ^ + static_cast(tid.slot_num); } }; }; @@ -96,9 +97,9 @@ class HeapTable { 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 */ + 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 */ std::pmr::memory_resource* mr_; /**< Memory resource for tuple allocations */ public: @@ -214,7 +215,9 @@ class HeapTable { [[nodiscard]] uint64_t tuple_count() const; /** @return An iterator starting at the first page */ - [[nodiscard]] Iterator scan(std::pmr::memory_resource* mr = nullptr) { return Iterator(*this, mr); } + [[nodiscard]] Iterator scan(std::pmr::memory_resource* mr = nullptr) { + return Iterator(*this, mr); + } /** @brief Initializes the physical heap file */ bool create(); diff --git a/include/transaction/lock_manager.hpp b/include/transaction/lock_manager.hpp index 06ac6dc..698b8d6 100644 --- a/include/transaction/lock_manager.hpp +++ b/include/transaction/lock_manager.hpp @@ -33,9 +33,10 @@ class LockManager { }; std::mutex latch_; - std::unordered_map lock_table_; // RID -> LockQueue + std::unordered_map + lock_table_; // RID -> LockQueue - public: + public: LockManager() = default; ~LockManager() = default; @@ -59,8 +60,7 @@ class LockManager { * @brief Release a lock held by a transaction */ bool unlock(Transaction* txn, const storage::HeapTable::TupleId& rid); - }; - +}; } // namespace cloudsql::transaction diff --git a/include/transaction/transaction.hpp b/include/transaction/transaction.hpp index 7a138b6..34f1178 100644 --- a/include/transaction/transaction.hpp +++ b/include/transaction/transaction.hpp @@ -73,8 +73,10 @@ class Transaction { // Locks held by this transaction (for auto-release on commit/abort) std::mutex lock_set_mutex_; - std::unordered_set shared_locks_; - std::unordered_set exclusive_locks_; + std::unordered_set + shared_locks_; + std::unordered_set + exclusive_locks_; // Changes to undo on rollback std::vector undo_logs_; @@ -112,11 +114,13 @@ class Transaction { exclusive_locks_.insert(rid); } - [[nodiscard]] std::unordered_set get_shared_lock_set() { + [[nodiscard]] std::unordered_set + get_shared_lock_set() { const std::scoped_lock lock(lock_set_mutex_); return shared_locks_; } - [[nodiscard]] std::unordered_set get_exclusive_lock_set() { + [[nodiscard]] std::unordered_set + get_exclusive_lock_set() { const std::scoped_lock lock(lock_set_mutex_); return exclusive_locks_; } diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index ac96ae6..8521907 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -69,7 +69,6 @@ bool Catalog::save(const std::string& filename) const { * @brief Create a new table */ oid_t Catalog::create_table(const std::string& table_name, std::vector columns) { - // Compute shards from ClusterManager for serialization std::vector shards; if (cluster_manager_ != nullptr) { @@ -176,7 +175,6 @@ oid_t Catalog::create_table_local(const std::string& table_name, std::vectorshards.push_back(shard); } - const oid_t id = table->table_id; tables_[id] = std::move(table); version_++; diff --git a/src/executor/operator.cpp b/src/executor/operator.cpp index fda96de..6b8be50 100644 --- a/src/executor/operator.cpp +++ b/src/executor/operator.cpp @@ -645,7 +645,9 @@ bool HashJoinOperator::next(Tuple& out_tuple) { if (iter_state.current != iter_state.end) { auto& build_tuple = iter_state.current->second; const auto& right_tuple = build_tuple.tuple; - std::pmr::vector joined_values(left_tuple_->values().begin(), left_tuple_->values().end(), get_memory_resource()); + std::pmr::vector joined_values(left_tuple_->values().begin(), + left_tuple_->values().end(), + get_memory_resource()); joined_values.insert(joined_values.end(), right_tuple.values().begin(), right_tuple.values().end()); @@ -661,7 +663,9 @@ bool HashJoinOperator::next(Tuple& out_tuple) { match_iter_ = std::nullopt; if ((join_type_ == JoinType::Left || join_type_ == JoinType::Full) && !left_had_match_) { - std::pmr::vector joined_values(left_tuple_->values().begin(), left_tuple_->values().end(), get_memory_resource()); + std::pmr::vector joined_values(left_tuple_->values().begin(), + left_tuple_->values().end(), + get_memory_resource()); for (size_t i = 0; i < right_schema.column_count(); ++i) { joined_values.push_back(common::Value::make_null()); } @@ -685,7 +689,9 @@ bool HashJoinOperator::next(Tuple& out_tuple) { match_iter_ = {range.first, range.second}; } else if (join_type_ == JoinType::Left || join_type_ == JoinType::Full) { /* No match found immediately, emit NULLs if Left/Full join */ - std::pmr::vector joined_values(left_tuple_->values().begin(), left_tuple_->values().end(), get_memory_resource()); + std::pmr::vector joined_values(left_tuple_->values().begin(), + left_tuple_->values().end(), + get_memory_resource()); for (size_t i = 0; i < right_schema.column_count(); ++i) { joined_values.push_back(common::Value::make_null()); } diff --git a/src/executor/query_executor.cpp b/src/executor/query_executor.cpp index 445aa81..a3a9ca3 100644 --- a/src/executor/query_executor.cpp +++ b/src/executor/query_executor.cpp @@ -135,7 +135,7 @@ std::shared_ptr QueryExecutor::prepare(const std::string& sql parser::Parser parser(std::move(lexer)); auto stmt = parser.parse_statement(); if (!stmt) return nullptr; - + auto prepared = std::make_shared(); prepared->stmt = std::shared_ptr(stmt.release()); prepared->sql = sql; @@ -152,8 +152,8 @@ std::shared_ptr QueryExecutor::prepare(const std::string& sql for (const auto& col : prepared->table_meta->columns) { prepared->schema->add_column(col.name, col.type); } - prepared->table = std::make_unique( - table_name, bpm_, *prepared->schema); + prepared->table = + std::make_unique(table_name, bpm_, *prepared->schema); // Cache B-tree index objects for (const auto& idx_info : prepared->table_meta->indexes) { @@ -171,7 +171,8 @@ std::shared_ptr QueryExecutor::prepare(const std::string& sql return prepared; } -QueryResult QueryExecutor::execute(const PreparedStatement& prepared, const std::vector& params) { +QueryResult QueryExecutor::execute(const PreparedStatement& prepared, + const std::vector& params) { // Fast-path for INSERT if (prepared.stmt->type() == parser::StmtType::Insert && prepared.table) { const auto start = std::chrono::high_resolution_clock::now(); @@ -202,13 +203,15 @@ QueryResult QueryExecutor::execute(const PreparedStatement& prepared, const std: for (size_t i = 0; i < prepared.indexes.size(); ++i) { const auto& idx_info = prepared.table_meta->indexes[i]; uint16_t pos = idx_info.column_positions[0]; - if (!apply_index_write(*prepared.indexes[i], tuple.get(pos), tid, IndexOp::Insert, err)) { + if (!apply_index_write(*prepared.indexes[i], tuple.get(pos), tid, + IndexOp::Insert, err)) { throw std::runtime_error(err); } } if (txn != nullptr) { - txn->add_undo_log(transaction::UndoLog::Type::INSERT, prepared.table_meta->name, tid); + txn->add_undo_log(transaction::UndoLog::Type::INSERT, prepared.table_meta->name, + tid); if (!lock_manager_.acquire_exclusive(txn, tid)) { throw std::runtime_error("Failed to acquire exclusive lock"); } @@ -225,7 +228,8 @@ QueryResult QueryExecutor::execute(const PreparedStatement& prepared, const std: current_params_ = nullptr; const auto end = std::chrono::high_resolution_clock::now(); - result.set_execution_time(std::chrono::duration_cast(end - start).count()); + result.set_execution_time( + std::chrono::duration_cast(end - start).count()); arena_.reset(); return result; } @@ -931,11 +935,12 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen col_name) { common::ValueType ktype = base_table_meta->columns[pos].type; current_root = std::make_unique( - std::make_shared(base_table_name, bpm_, - base_schema), - std::make_unique(idx_info.name, bpm_, - ktype), - std::move(const_val), txn, &lock_manager_); index_used = true; + std::make_shared(base_table_name, bpm_, + base_schema), + std::make_unique(idx_info.name, bpm_, + ktype), + std::move(const_val), txn, &lock_manager_); + index_used = true; break; } } @@ -957,7 +962,6 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen current_root->set_memory_resource(&arena_); current_root->set_params(current_params_); - /* 2. Add JOINs */ for (const auto& join : stmt.joins()) { const std::string join_table_name = join.table->to_string(); @@ -1060,7 +1064,8 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen /* 3. Filter (WHERE) - Only if not already handled by IndexScan */ if (stmt.where()) { - auto filter_op = std::make_unique(std::move(current_root), stmt.where()->clone()); + auto filter_op = + std::make_unique(std::move(current_root), stmt.where()->clone()); filter_op->set_memory_resource(&arena_); filter_op->set_params(current_params_); current_root = std::move(filter_op); @@ -1117,14 +1122,15 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen group_by.push_back(gb->clone()); } auto agg_op = std::make_unique(std::move(current_root), - std::move(group_by), std::move(aggs)); + std::move(group_by), std::move(aggs)); agg_op->set_memory_resource(&arena_); agg_op->set_params(current_params_); current_root = std::move(agg_op); /* 3.5. Having */ if (stmt.having()) { - auto having_filter = std::make_unique(std::move(current_root), stmt.having()->clone()); + auto having_filter = + std::make_unique(std::move(current_root), stmt.having()->clone()); having_filter->set_memory_resource(&arena_); having_filter->set_params(current_params_); current_root = std::move(having_filter); @@ -1152,7 +1158,8 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen for (const auto& col : stmt.columns()) { projection.push_back(col->clone()); } - auto project_op = std::make_unique(std::move(current_root), std::move(projection)); + auto project_op = + std::make_unique(std::move(current_root), std::move(projection)); project_op->set_memory_resource(&arena_); project_op->set_params(current_params_); current_root = std::move(project_op); @@ -1160,7 +1167,8 @@ std::unique_ptr QueryExecutor::build_plan(const parser::SelectStatemen /* 6. Limit */ if (stmt.has_limit() || stmt.has_offset()) { - auto limit_op = std::make_unique(std::move(current_root), stmt.limit(), stmt.offset()); + auto limit_op = + std::make_unique(std::move(current_root), stmt.limit(), stmt.offset()); limit_op->set_memory_resource(&arena_); limit_op->set_params(current_params_); current_root = std::move(limit_op); diff --git a/src/parser/expression.cpp b/src/parser/expression.cpp index 96c3dbf..f878d58 100644 --- a/src/parser/expression.cpp +++ b/src/parser/expression.cpp @@ -342,7 +342,9 @@ void ParameterExpr::evaluate_vectorized(const executor::VectorBatch& batch, (void)result; } -std::string ParameterExpr::to_string() const { return "?"; } +std::string ParameterExpr::to_string() const { + return "?"; +} std::unique_ptr ParameterExpr::clone() const { return std::make_unique(index_); diff --git a/src/storage/buffer_pool_manager.cpp b/src/storage/buffer_pool_manager.cpp index d752b01..fcec24e 100644 --- a/src/storage/buffer_pool_manager.cpp +++ b/src/storage/buffer_pool_manager.cpp @@ -58,7 +58,7 @@ Page* BufferPoolManager::fetch_page(const std::string& file_name, uint32_t page_ const uint32_t file_id = get_file_id(file_name); const PageKey key{file_id, page_id}; - + if (page_table_.find(key) != page_table_.end()) { const uint32_t frame_id = page_table_[key]; Page* const page = &pages_[frame_id]; @@ -105,7 +105,7 @@ bool BufferPoolManager::unpin_page(const std::string& file_name, uint32_t page_i const uint32_t file_id = get_file_id(file_name); const PageKey key{file_id, page_id}; - + if (page_table_.find(key) == page_table_.end()) { return false; } @@ -134,7 +134,7 @@ bool BufferPoolManager::flush_page(const std::string& file_name, uint32_t page_i const uint32_t file_id = get_file_id(file_name); const PageKey key{file_id, page_id}; - + if (page_table_.find(key) == page_table_.end()) { return false; } @@ -155,7 +155,7 @@ Page* BufferPoolManager::new_page(const std::string& file_name, const uint32_t* // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) const_cast(*page_id) = target_page_id; } - + const uint32_t file_id = get_file_id(file_name); const PageKey key{file_id, target_page_id}; @@ -193,7 +193,7 @@ bool BufferPoolManager::delete_page(const std::string& file_name, uint32_t page_ const uint32_t file_id = get_file_id(file_name); const PageKey key{file_id, page_id}; - + if (page_table_.find(key) != page_table_.end()) { const uint32_t frame_id = page_table_[key]; Page* const page = &pages_[frame_id]; diff --git a/src/storage/heap_table.cpp b/src/storage/heap_table.cpp index 631e27d..43aa2e9 100644 --- a/src/storage/heap_table.cpp +++ b/src/storage/heap_table.cpp @@ -47,7 +47,7 @@ HeapTable::~HeapTable() { /* --- Iterator Implementation --- */ -HeapTable::Iterator::Iterator(HeapTable& table, std::pmr::memory_resource* mr) +HeapTable::Iterator::Iterator(HeapTable& table, std::pmr::memory_resource* mr) : table_(table), next_id_(0, 0), last_id_(0, 0), mr_(mr) {} bool HeapTable::Iterator::next(executor::Tuple& out_tuple) { @@ -289,7 +289,7 @@ bool HeapTable::remove(const TupleId& tuple_id, uint64_t xmax) { auto* buffer = cached_page_->get_data(); PageHeader header{}; std::memcpy(&header, buffer, sizeof(PageHeader)); - + uint16_t offset = 0; std::memcpy(&offset, buffer + sizeof(PageHeader) + (tuple_id.slot_num * sizeof(uint16_t)), sizeof(uint16_t)); @@ -404,15 +404,18 @@ bool HeapTable::get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const { type == common::ValueType::TYPE_INT64 || type == common::ValueType::TYPE_FLOAT32 || type == common::ValueType::TYPE_FLOAT64) { if (cursor + 8 > data_len) break; - if (type == common::ValueType::TYPE_FLOAT32 || type == common::ValueType::TYPE_FLOAT64) { + if (type == common::ValueType::TYPE_FLOAT32 || + type == common::ValueType::TYPE_FLOAT64) { double v; std::memcpy(&v, data + cursor, 8); values.push_back(common::Value::make_float64(v)); } else { int64_t v; std::memcpy(&v, data + cursor, 8); - if (type == common::ValueType::TYPE_BOOL) values.push_back(common::Value::make_bool(v != 0)); - else values.push_back(common::Value::make_int64(v)); + if (type == common::ValueType::TYPE_BOOL) + values.push_back(common::Value::make_bool(v != 0)); + else + values.push_back(common::Value::make_int64(v)); } cursor += 8; } else { From 48fcf462b819186a38dfc163c7804eaa9a48f889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 19:02:28 +0300 Subject: [PATCH 08/21] fix: resolve Tuple ambiguity and LockManager test compilation errors --- include/executor/types.hpp | 5 +---- tests/transaction_coverage_tests.cpp | 17 +++++++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/executor/types.hpp b/include/executor/types.hpp index b2f30c5..81e403e 100644 --- a/include/executor/types.hpp +++ b/include/executor/types.hpp @@ -131,10 +131,7 @@ class Tuple { public: Tuple() = default; explicit Tuple(std::pmr::vector values) : values_(std::move(values)) {} - - // Support construction from standard vector (via move or copy) - explicit Tuple(std::vector values) : values_(values.begin(), values.end()) {} - + // Support allocation from a custom memory resource explicit Tuple(std::pmr::memory_resource* mr) : values_(mr) {} Tuple(std::vector values, std::pmr::memory_resource* mr) diff --git a/tests/transaction_coverage_tests.cpp b/tests/transaction_coverage_tests.cpp index 0cfbad8..22f011a 100644 --- a/tests/transaction_coverage_tests.cpp +++ b/tests/transaction_coverage_tests.cpp @@ -91,19 +91,20 @@ TEST(TransactionCoverageTestsStandalone, LockManagerConcurrency) { std::atomic stop{false}; Transaction writer_txn(100); + storage::HeapTable::TupleId rid(1, 1); // Writers holds exclusive lock initially - ASSERT_TRUE(lm.acquire_exclusive(&writer_txn, "RESOURCE")); + ASSERT_TRUE(lm.acquire_exclusive(&writer_txn, rid)); for (int i = 0; i < num_readers; ++i) { - readers.emplace_back([&, i]() { + readers.emplace_back([&, i, rid]() { Transaction reader_txn(i); - if (lm.acquire_shared(&reader_txn, "RESOURCE")) { + if (lm.acquire_shared(&reader_txn, rid)) { shared_granted++; while (!stop) { std::this_thread::yield(); } - lm.unlock(&reader_txn, "RESOURCE"); + lm.unlock(&reader_txn, rid); } }); } @@ -113,7 +114,7 @@ TEST(TransactionCoverageTestsStandalone, LockManagerConcurrency) { EXPECT_EQ(shared_granted.load(), 0); // Release writer lock, readers should proceed - lm.unlock(&writer_txn, "RESOURCE"); + lm.unlock(&writer_txn, rid); // Wait for all readers to get the lock for (int i = 0; i < 50 && shared_granted.load() < num_readers; ++i) { @@ -140,19 +141,19 @@ TEST_F(TransactionCoverageTests, DeepRollback) { // 1. Insert some data auto rid1 = - table.insert(executor::Tuple({common::Value::make_int64(1), common::Value::make_text("A")}), + table.insert(executor::Tuple(std::pmr::vector({common::Value::make_int64(1), common::Value::make_text("A")})), txn->get_id()); txn->add_undo_log(UndoLog::Type::INSERT, "rollback_stress", rid1); auto rid2 = - table.insert(executor::Tuple({common::Value::make_int64(2), common::Value::make_text("B")}), + table.insert(executor::Tuple(std::pmr::vector({common::Value::make_int64(2), common::Value::make_text("B")})), txn->get_id()); txn->add_undo_log(UndoLog::Type::INSERT, "rollback_stress", rid2); // 2. Update data table.remove(rid1, txn->get_id()); // Mark old version deleted auto rid1_new = table.insert( - executor::Tuple({common::Value::make_int64(1), common::Value::make_text("A_NEW")}), + executor::Tuple(std::pmr::vector({common::Value::make_int64(1), common::Value::make_text("A_NEW")})), txn->get_id()); txn->add_undo_log(UndoLog::Type::UPDATE, "rollback_stress", rid1_new, rid1); From 1d09a7a5ea89f064ac7e679159d805f2093fe8e9 Mon Sep 17 00:00:00 2001 From: poyrazK <83272398+poyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:02:28 +0000 Subject: [PATCH 09/21] style: automated clang-format fixes --- include/executor/types.hpp | 2 +- tests/transaction_coverage_tests.cpp | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/executor/types.hpp b/include/executor/types.hpp index 81e403e..f76269d 100644 --- a/include/executor/types.hpp +++ b/include/executor/types.hpp @@ -131,7 +131,7 @@ class Tuple { public: Tuple() = default; explicit Tuple(std::pmr::vector values) : values_(std::move(values)) {} - + // Support allocation from a custom memory resource explicit Tuple(std::pmr::memory_resource* mr) : values_(mr) {} Tuple(std::vector values, std::pmr::memory_resource* mr) diff --git a/tests/transaction_coverage_tests.cpp b/tests/transaction_coverage_tests.cpp index 22f011a..8492d9c 100644 --- a/tests/transaction_coverage_tests.cpp +++ b/tests/transaction_coverage_tests.cpp @@ -140,21 +140,22 @@ TEST_F(TransactionCoverageTests, DeepRollback) { txn = tm.begin(); // 1. Insert some data - auto rid1 = - table.insert(executor::Tuple(std::pmr::vector({common::Value::make_int64(1), common::Value::make_text("A")})), - txn->get_id()); + auto rid1 = table.insert(executor::Tuple(std::pmr::vector( + {common::Value::make_int64(1), common::Value::make_text("A")})), + txn->get_id()); txn->add_undo_log(UndoLog::Type::INSERT, "rollback_stress", rid1); - auto rid2 = - table.insert(executor::Tuple(std::pmr::vector({common::Value::make_int64(2), common::Value::make_text("B")})), - txn->get_id()); + auto rid2 = table.insert(executor::Tuple(std::pmr::vector( + {common::Value::make_int64(2), common::Value::make_text("B")})), + txn->get_id()); txn->add_undo_log(UndoLog::Type::INSERT, "rollback_stress", rid2); // 2. Update data table.remove(rid1, txn->get_id()); // Mark old version deleted - auto rid1_new = table.insert( - executor::Tuple(std::pmr::vector({common::Value::make_int64(1), common::Value::make_text("A_NEW")})), - txn->get_id()); + auto rid1_new = + table.insert(executor::Tuple(std::pmr::vector( + {common::Value::make_int64(1), common::Value::make_text("A_NEW")})), + txn->get_id()); txn->add_undo_log(UndoLog::Type::UPDATE, "rollback_stress", rid1_new, rid1); // 3. Delete data From 71f912a94e81942b8b034898187d1866454366f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 21:07:00 +0300 Subject: [PATCH 10/21] fix: resolve Tuple constructor ambiguity for std::vector and initializer_list --- include/executor/types.hpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/include/executor/types.hpp b/include/executor/types.hpp index f76269d..e73014b 100644 --- a/include/executor/types.hpp +++ b/include/executor/types.hpp @@ -119,7 +119,7 @@ class Schema { [[nodiscard]] bool operator==(const Schema& other) const { return columns_ == other.columns_; } }; -/** + /** * @brief A single data row used in the row-oriented (Volcano) execution model. * * Uses std::pmr::vector to support custom allocators (e.g. ArenaAllocator). @@ -130,10 +130,21 @@ class Tuple { public: Tuple() = default; + + // Explicit PMR vector constructor explicit Tuple(std::pmr::vector values) : values_(std::move(values)) {} + + // Initializer list constructor to resolve ambiguity for {...} + Tuple(std::initializer_list list) : values_(list) {} // Support allocation from a custom memory resource explicit Tuple(std::pmr::memory_resource* mr) : values_(mr) {} + + // Support construction from standard vector + Tuple(const std::vector& values) : values_(values.begin(), values.end()) {} + Tuple(std::vector&& values) + : values_(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end())) {} + Tuple(std::vector values, std::pmr::memory_resource* mr) : values_(values.begin(), values.end(), mr) {} From 378b9c2053b87842d42c6f8512f5b00a965cf466 Mon Sep 17 00:00:00 2001 From: poyrazK <83272398+poyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:10:42 +0000 Subject: [PATCH 11/21] style: automated clang-format fixes --- include/executor/types.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/executor/types.hpp b/include/executor/types.hpp index e73014b..dae6771 100644 --- a/include/executor/types.hpp +++ b/include/executor/types.hpp @@ -119,7 +119,7 @@ class Schema { [[nodiscard]] bool operator==(const Schema& other) const { return columns_ == other.columns_; } }; - /** +/** * @brief A single data row used in the row-oriented (Volcano) execution model. * * Uses std::pmr::vector to support custom allocators (e.g. ArenaAllocator). @@ -130,19 +130,19 @@ class Tuple { public: Tuple() = default; - + // Explicit PMR vector constructor explicit Tuple(std::pmr::vector values) : values_(std::move(values)) {} - + // Initializer list constructor to resolve ambiguity for {...} Tuple(std::initializer_list list) : values_(list) {} // Support allocation from a custom memory resource explicit Tuple(std::pmr::memory_resource* mr) : values_(mr) {} - + // Support construction from standard vector Tuple(const std::vector& values) : values_(values.begin(), values.end()) {} - Tuple(std::vector&& values) + Tuple(std::vector&& values) : values_(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end())) {} Tuple(std::vector values, std::pmr::memory_resource* mr) From 3f4f4c5b964a1c5a2bfa2f6a4c2164ff4c202e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 21:22:40 +0300 Subject: [PATCH 12/21] fix: resolve Tuple constructor ambiguity and update LockManager tests to use TupleId --- include/executor/types.hpp | 3 +- tests/lock_manager_tests.cpp | 60 ++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/include/executor/types.hpp b/include/executor/types.hpp index dae6771..f16b579 100644 --- a/include/executor/types.hpp +++ b/include/executor/types.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "common/value.hpp" @@ -145,7 +146,7 @@ class Tuple { Tuple(std::vector&& values) : values_(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end())) {} - Tuple(std::vector values, std::pmr::memory_resource* mr) + Tuple(const std::vector& values, std::pmr::memory_resource* mr) : values_(values.begin(), values.end(), mr) {} Tuple(const Tuple& other) = default; diff --git a/tests/lock_manager_tests.cpp b/tests/lock_manager_tests.cpp index bf5db78..e59ed49 100644 --- a/tests/lock_manager_tests.cpp +++ b/tests/lock_manager_tests.cpp @@ -9,10 +9,12 @@ #include #include +#include "storage/heap_table.hpp" #include "transaction/lock_manager.hpp" #include "transaction/transaction.hpp" using namespace cloudsql::transaction; +using namespace cloudsql::storage; namespace { @@ -22,35 +24,38 @@ TEST(LockManagerTests, Shared) { LockManager lm; Transaction txn1(1); Transaction txn2(2); + HeapTable::TupleId rid1(1, 1); - EXPECT_TRUE(lm.acquire_shared(&txn1, "RID1")); - EXPECT_TRUE(lm.acquire_shared(&txn2, "RID1")); + EXPECT_TRUE(lm.acquire_shared(&txn1, rid1)); + EXPECT_TRUE(lm.acquire_shared(&txn2, rid1)); - static_cast(lm.unlock(&txn1, "RID1")); - static_cast(lm.unlock(&txn2, "RID1")); + static_cast(lm.unlock(&txn1, rid1)); + static_cast(lm.unlock(&txn2, rid1)); } TEST(LockManagerTests, Exclusive) { LockManager lm; Transaction txn1(1); Transaction txn2(2); + HeapTable::TupleId rid1(1, 1); - EXPECT_TRUE(lm.acquire_exclusive(&txn1, "RID1")); - EXPECT_FALSE(lm.acquire_shared(&txn2, "RID1")); + EXPECT_TRUE(lm.acquire_exclusive(&txn1, rid1)); + EXPECT_FALSE(lm.acquire_shared(&txn2, rid1)); - static_cast(lm.unlock(&txn1, "RID1")); - EXPECT_TRUE(lm.acquire_shared(&txn2, "RID1")); - static_cast(lm.unlock(&txn2, "RID1")); + static_cast(lm.unlock(&txn1, rid1)); + EXPECT_TRUE(lm.acquire_shared(&txn2, rid1)); + static_cast(lm.unlock(&txn2, rid1)); } TEST(LockManagerTests, Upgrade) { LockManager lm; Transaction txn1(1); + HeapTable::TupleId rid1(1, 1); - EXPECT_TRUE(lm.acquire_shared(&txn1, "RID1")); - EXPECT_TRUE(lm.acquire_exclusive(&txn1, "RID1")); + EXPECT_TRUE(lm.acquire_shared(&txn1, rid1)); + EXPECT_TRUE(lm.acquire_exclusive(&txn1, rid1)); - static_cast(lm.unlock(&txn1, "RID1")); + static_cast(lm.unlock(&txn1, rid1)); } TEST(LockManagerTests, Wait) { @@ -58,20 +63,21 @@ TEST(LockManagerTests, Wait) { Transaction txn1(1); Transaction txn2(2); Transaction txn3(3); + HeapTable::TupleId rid1(1, 1); std::atomic shared_granted{0}; // 1. Get Exclusive - EXPECT_TRUE(lm.acquire_exclusive(&txn1, "RID1")); + EXPECT_TRUE(lm.acquire_exclusive(&txn1, rid1)); // 2. Try to get Shared from two other txns (should block) std::thread t2([&]() { - if (lm.acquire_shared(&txn2, "RID1")) { + if (lm.acquire_shared(&txn2, rid1)) { shared_granted++; } }); std::thread t3([&]() { - if (lm.acquire_shared(&txn3, "RID1")) { + if (lm.acquire_shared(&txn3, rid1)) { shared_granted++; } }); @@ -81,41 +87,43 @@ TEST(LockManagerTests, Wait) { EXPECT_EQ(shared_granted.load(), 0); // 3. Release Exclusive (should grant both shared) - static_cast(lm.unlock(&txn1, "RID1")); + static_cast(lm.unlock(&txn1, rid1)); t2.join(); t3.join(); EXPECT_EQ(shared_granted.load(), 2); - static_cast(lm.unlock(&txn2, "RID1")); - static_cast(lm.unlock(&txn3, "RID1")); + static_cast(lm.unlock(&txn2, rid1)); + static_cast(lm.unlock(&txn3, rid1)); } TEST(LockManagerTests, Deadlock) { LockManager lm; Transaction txn1(1); Transaction txn2(2); + HeapTable::TupleId ridA(1, 1); + HeapTable::TupleId ridB(1, 2); // txn1 holds A, txn2 holds B - EXPECT_TRUE(lm.acquire_exclusive(&txn1, "A")); - EXPECT_TRUE(lm.acquire_exclusive(&txn2, "B")); + EXPECT_TRUE(lm.acquire_exclusive(&txn1, ridA)); + EXPECT_TRUE(lm.acquire_exclusive(&txn2, ridB)); // txn1 waits for B - std::thread t1([&]() { static_cast(lm.acquire_exclusive(&txn1, "B")); }); + std::thread t1([&]() { static_cast(lm.acquire_exclusive(&txn1, ridB)); }); // Small sleep to ensure t1 is waiting std::this_thread::sleep_for(TEST_SLEEP_MS); // txn2 waits for A -> Deadlock! - static_cast(lm.unlock(&txn1, "A")); - static_cast(lm.acquire_exclusive(&txn2, "A")); + static_cast(lm.unlock(&txn1, ridA)); + static_cast(lm.acquire_exclusive(&txn2, ridA)); - static_cast(lm.unlock(&txn2, "B")); + static_cast(lm.unlock(&txn2, ridB)); t1.join(); - static_cast(lm.unlock(&txn1, "B")); - static_cast(lm.unlock(&txn2, "A")); + static_cast(lm.unlock(&txn1, ridB)); + static_cast(lm.unlock(&txn2, ridA)); } } // namespace From c49bcb9e53f04d60273e03ed60b51a27b6379468 Mon Sep 17 00:00:00 2001 From: poyrazK <83272398+poyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 18:23:50 +0000 Subject: [PATCH 13/21] style: automated clang-format fixes --- include/executor/types.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/executor/types.hpp b/include/executor/types.hpp index f16b579..a0e3ee4 100644 --- a/include/executor/types.hpp +++ b/include/executor/types.hpp @@ -11,12 +11,12 @@ #define CLOUDSQL_EXECUTOR_TYPES_HPP #include +#include #include #include #include #include #include -#include #include "common/value.hpp" From 9d165e02d4565d6ef4241ef6b9c66ab7451379db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 21:41:08 +0300 Subject: [PATCH 14/21] fix: resolve new_page signature mismatch and update LockManager tests --- include/storage/buffer_pool_manager.hpp | 2 +- src/storage/buffer_pool_manager.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/storage/buffer_pool_manager.hpp b/include/storage/buffer_pool_manager.hpp index 96f2624..2386149 100644 --- a/include/storage/buffer_pool_manager.hpp +++ b/include/storage/buffer_pool_manager.hpp @@ -77,7 +77,7 @@ class BufferPoolManager { * @param[out] page_id Output param for the id of the created page * @return Pointer to the new Page, or nullptr if cannot be created */ - Page* new_page(const std::string& file_name, const uint32_t* page_id); + Page* new_page(const std::string& file_name, uint32_t* page_id); /** * @brief Delete a page diff --git a/src/storage/buffer_pool_manager.cpp b/src/storage/buffer_pool_manager.cpp index fcec24e..91e55f0 100644 --- a/src/storage/buffer_pool_manager.cpp +++ b/src/storage/buffer_pool_manager.cpp @@ -147,13 +147,12 @@ bool BufferPoolManager::flush_page(const std::string& file_name, uint32_t page_i return true; } -Page* BufferPoolManager::new_page(const std::string& file_name, const uint32_t* page_id) { +Page* BufferPoolManager::new_page(const std::string& file_name, uint32_t* page_id) { const std::scoped_lock lock(latch_); const uint32_t target_page_id = storage_manager_.allocate_page(file_name); if (page_id != nullptr) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) - const_cast(*page_id) = target_page_id; + *page_id = target_page_id; } const uint32_t file_id = get_file_id(file_name); From 14294cd8f08d63825024711076b566ccc6e4b712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 21:59:33 +0300 Subject: [PATCH 15/21] fix: prevent SegFault in HeapTable destructor during test cleanup --- src/storage/heap_table.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/storage/heap_table.cpp b/src/storage/heap_table.cpp index 43aa2e9..7abfcb2 100644 --- a/src/storage/heap_table.cpp +++ b/src/storage/heap_table.cpp @@ -39,8 +39,15 @@ HeapTable::HeapTable(std::string table_name, BufferPoolManager& bpm, executor::S last_page_id_(0) {} HeapTable::~HeapTable() { + // Note: In some tests, the BufferPoolManager might be destroyed before the HeapTable + // causing this to potentially access a dangling reference if we are not careful. + // However, the current issue is likely that cached_page_ needs to be unpinned properly. if (cached_page_ != nullptr) { - bpm_.unpin_page(filename_, cached_page_id_, true); + try { + bpm_.unpin_page(filename_, cached_page_id_, true); + } catch (...) { + // Ignore errors during destruction if BPM is already gone + } cached_page_ = nullptr; } } From 8ceaa93c2655e86aaad42122246e0b4549ce09a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 22:06:47 +0300 Subject: [PATCH 16/21] fix: ensure correct HeapTable destruction order in StoragePersistence test --- tests/cloudSQL_tests.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/cloudSQL_tests.cpp b/tests/cloudSQL_tests.cpp index 82a5b9e..0ab6092 100644 --- a/tests/cloudSQL_tests.cpp +++ b/tests/cloudSQL_tests.cpp @@ -192,19 +192,23 @@ TEST(CloudSQLTests, StoragePersistence) { { StorageManager disk_manager("./test_data"); BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - HeapTable table(filename, sm, schema); - static_cast(table.create()); - static_cast(table.insert(Tuple({Value::make_text("Persistent data")}))); + { + HeapTable table(filename, sm, schema); + static_cast(table.create()); + static_cast(table.insert(Tuple({Value::make_text("Persistent data")}))); + } sm.flush_all_pages(); } { StorageManager disk_manager("./test_data"); BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - HeapTable table(filename, sm, schema); - auto iter = table.scan(); - Tuple t; - EXPECT_TRUE(iter.next(t)); - EXPECT_STREQ(t.get(0).as_text().c_str(), "Persistent data"); + { + HeapTable table(filename, sm, schema); + auto iter = table.scan(); + Tuple t; + EXPECT_TRUE(iter.next(t)); + EXPECT_STREQ(t.get(0).as_text().c_str(), "Persistent data"); + } } static_cast(std::remove(filepath.c_str())); } From 54f6025d915b310525409a83d52cbc8966893870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 22:17:59 +0300 Subject: [PATCH 17/21] fix: resolve new_page signature mismatch and HeapTable destruction order --- tests/cloudSQL_tests.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/cloudSQL_tests.cpp b/tests/cloudSQL_tests.cpp index 0ab6092..f547650 100644 --- a/tests/cloudSQL_tests.cpp +++ b/tests/cloudSQL_tests.cpp @@ -190,20 +190,20 @@ TEST(CloudSQLTests, StoragePersistence) { Schema schema; schema.add_column("data", ValueType::TYPE_TEXT); { - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); + auto disk_manager = std::make_unique("./test_data"); + auto sm = std::make_unique(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, *disk_manager); { - HeapTable table(filename, sm, schema); + HeapTable table(filename, *sm, schema); static_cast(table.create()); static_cast(table.insert(Tuple({Value::make_text("Persistent data")}))); } - sm.flush_all_pages(); + sm->flush_all_pages(); } { - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); + auto disk_manager = std::make_unique("./test_data"); + auto sm = std::make_unique(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, *disk_manager); { - HeapTable table(filename, sm, schema); + HeapTable table(filename, *sm, schema); auto iter = table.scan(); Tuple t; EXPECT_TRUE(iter.next(t)); From 548839ca8cf4442ed743429d28fc3f8dd1d23e92 Mon Sep 17 00:00:00 2001 From: poyrazK <83272398+poyrazK@users.noreply.github.com> Date: Wed, 8 Apr 2026 19:18:51 +0000 Subject: [PATCH 18/21] style: automated clang-format fixes --- tests/cloudSQL_tests.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/cloudSQL_tests.cpp b/tests/cloudSQL_tests.cpp index f547650..aa8fad9 100644 --- a/tests/cloudSQL_tests.cpp +++ b/tests/cloudSQL_tests.cpp @@ -191,7 +191,8 @@ TEST(CloudSQLTests, StoragePersistence) { schema.add_column("data", ValueType::TYPE_TEXT); { auto disk_manager = std::make_unique("./test_data"); - auto sm = std::make_unique(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, *disk_manager); + auto sm = std::make_unique( + cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, *disk_manager); { HeapTable table(filename, *sm, schema); static_cast(table.create()); @@ -201,7 +202,8 @@ TEST(CloudSQLTests, StoragePersistence) { } { auto disk_manager = std::make_unique("./test_data"); - auto sm = std::make_unique(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, *disk_manager); + auto sm = std::make_unique( + cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, *disk_manager); { HeapTable table(filename, *sm, schema); auto iter = table.scan(); From 6cf093b8fb35f185f74662f2207678133dc21b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Thu, 9 Apr 2026 16:57:15 +0300 Subject: [PATCH 19/21] fix: resolve SegFaults via proper PMR propagation and record boundaries --- include/executor/operator.hpp | 22 +- include/executor/types.hpp | 29 +- include/storage/heap_table.hpp | 5 + profile.txt | 647 ++++++++++++++++++++++++++++++++ src/executor/operator.cpp | 83 +++- src/executor/query_executor.cpp | 19 +- src/storage/heap_table.cpp | 103 +++-- test_data/idx_id.idx | 0 8 files changed, 839 insertions(+), 69 deletions(-) create mode 100644 profile.txt delete mode 100644 test_data/idx_id.idx diff --git a/include/executor/operator.hpp b/include/executor/operator.hpp index 981ce33..253d500 100644 --- a/include/executor/operator.hpp +++ b/include/executor/operator.hpp @@ -74,12 +74,12 @@ class Operator { [[nodiscard]] Transaction* get_txn() const { return txn_; } [[nodiscard]] LockManager* get_lock_manager() const { return lock_manager_; } - void set_memory_resource(std::pmr::memory_resource* mr) { mr_ = mr; } + virtual void set_memory_resource(std::pmr::memory_resource* mr) { mr_ = mr; } [[nodiscard]] std::pmr::memory_resource* get_memory_resource() const { return mr_ ? mr_ : std::pmr::get_default_resource(); } - void set_params(const std::vector* params) { params_ = params; } + virtual void set_params(const std::vector* params) { params_ = params; } [[nodiscard]] const std::vector* get_params() const { return params_; } virtual bool init() { return true; } @@ -202,6 +202,9 @@ class FilterOperator : public Operator { void close() override; [[nodiscard]] Schema& output_schema() override; void add_child(std::unique_ptr child) override; + + void set_memory_resource(std::pmr::memory_resource* mr) override; + void set_params(const std::vector* params) override; }; /** @@ -223,6 +226,9 @@ class ProjectOperator : public Operator { void close() override; [[nodiscard]] Schema& output_schema() override; void add_child(std::unique_ptr child) override; + + void set_memory_resource(std::pmr::memory_resource* mr) override; + void set_params(const std::vector* params) override; }; /** @@ -247,6 +253,9 @@ class SortOperator : public Operator { bool next(Tuple& out_tuple) override; void close() override; [[nodiscard]] Schema& output_schema() override; + + void set_memory_resource(std::pmr::memory_resource* mr) override; + void set_params(const std::vector* params) override; }; /** @@ -281,6 +290,9 @@ class AggregateOperator : public Operator { bool next(Tuple& out_tuple) override; void close() override; [[nodiscard]] Schema& output_schema() override; + + void set_memory_resource(std::pmr::memory_resource* mr) override; + void set_params(const std::vector* params) override; }; /** @@ -330,6 +342,9 @@ class HashJoinOperator : public Operator { void close() override; [[nodiscard]] Schema& output_schema() override; void add_child(std::unique_ptr child) override; + + void set_memory_resource(std::pmr::memory_resource* mr) override; + void set_params(const std::vector* params) override; }; /** @@ -352,6 +367,9 @@ class LimitOperator : public Operator { void close() override; [[nodiscard]] Schema& output_schema() override; void add_child(std::unique_ptr child) override; + + void set_memory_resource(std::pmr::memory_resource* mr) override; + void set_params(const std::vector* params) override; }; } // namespace cloudsql::executor diff --git a/include/executor/types.hpp b/include/executor/types.hpp index a0e3ee4..6f7e30b 100644 --- a/include/executor/types.hpp +++ b/include/executor/types.hpp @@ -11,12 +11,12 @@ #define CLOUDSQL_EXECUTOR_TYPES_HPP #include -#include #include #include #include #include #include +#include #include "common/value.hpp" @@ -131,24 +131,29 @@ class Tuple { public: Tuple() = default; - + // Explicit PMR vector constructor explicit Tuple(std::pmr::vector values) : values_(std::move(values)) {} - - // Initializer list constructor to resolve ambiguity for {...} + + // Initializer list constructor Tuple(std::initializer_list list) : values_(list) {} // Support allocation from a custom memory resource - explicit Tuple(std::pmr::memory_resource* mr) : values_(mr) {} - - // Support construction from standard vector - Tuple(const std::vector& values) : values_(values.begin(), values.end()) {} - Tuple(std::vector&& values) + explicit Tuple(std::pmr::memory_resource* mr) + : values_(mr ? mr : std::pmr::get_default_resource()) {} + + // Support construction from standard vector or PMR vector with specific resource + template , Tuple>>, + typename std::enable_if_t, std::pmr::memory_resource*>>* = nullptr> + Tuple(const VectorType& values, std::pmr::memory_resource* mr = nullptr) + : values_(values.begin(), values.end(), mr ? mr : std::pmr::get_default_resource()) {} + + template , Tuple>>> + explicit Tuple(VectorType&& values) : values_(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end())) {} - Tuple(const std::vector& values, std::pmr::memory_resource* mr) - : values_(values.begin(), values.end(), mr) {} - Tuple(const Tuple& other) = default; Tuple(Tuple&& other) noexcept = default; Tuple& operator=(const Tuple& other) = default; diff --git a/include/storage/heap_table.hpp b/include/storage/heap_table.hpp index b99caa6..2922ae0 100644 --- a/include/storage/heap_table.hpp +++ b/include/storage/heap_table.hpp @@ -104,7 +104,12 @@ class HeapTable { public: explicit Iterator(HeapTable& table, std::pmr::memory_resource* mr = nullptr); + ~Iterator() = default; + Iterator(const Iterator&) = default; + Iterator& operator=(const Iterator&) = default; + Iterator(Iterator&&) noexcept = default; + Iterator& operator=(Iterator&&) noexcept = default; /** * @brief Fetches the next non-deleted record from the heap * @param[out] out_tuple Container for the retrieved record diff --git a/profile.txt b/profile.txt new file mode 100644 index 0000000..4fca312 --- /dev/null +++ b/profile.txt @@ -0,0 +1,647 @@ +Analysis of sampling storage_bench (pid 12352) every 1 millisecond +Process: storage_bench [12352] +Path: /Users/USER/*/storage_bench +Load Address: 0x1000f0000 +Identifier: storage_bench +Version: 0 +Code Type: ARM64 +Platform: macOS +Parent Process: bash [12350] +Target Type: live task + +Date/Time: 2026-04-04 13:01:29.909 +0300 +Launch Time: 2026-04-04 13:01:27.804 +0300 +OS Version: macOS 26.4 (25E246) +Report Version: 7 +Analysis Tool: /usr/bin/sample + +Physical footprint: 5776K +Physical footprint (peak): 5776K +Idle exit: untracked +---- + +Call graph: + 8282 Thread_8258606 DispatchQueue_1: com.apple.main-thread (serial) + 8282 start (in dyld) + 6992 [0x182d53da4] + 8282 main (in storage_bench) + 136 [0x1000f1d88] storage_bench.cpp:79 + 8282 benchmark::RunSpecifiedBenchmarks() (in storage_bench) + 92 [0x1000faaf4] benchmark.cc:535 + 8282 benchmark::RunSpecifiedBenchmarks(benchmark::BenchmarkReporter*, benchmark::BenchmarkReporter*, std::basic_string) (in storage_bench) + 2456 [0x1000fb4d4] benchmark.cc:611 + 8282 benchmark::internal::BenchmarkRunner::DoOneRepetition() (in storage_bench) + 144 [0x100110d64] benchmark_runner.cc:424 + 8282 benchmark::internal::BenchmarkRunner::DoNIterations() (in storage_bench) + 660 [0x100110290] benchmark_runner.cc:273 + 8282 benchmark::internal::(anonymous namespace)::RunInThread(benchmark::internal::BenchmarkInstance const*, long long, int, benchmark::internal::ThreadManager*, benchmark::internal::PerfCountersMeasurement*) (in storage_bench) + 72 [0x100110660] benchmark_runner.cc:132 + 8282 benchmark::internal::BenchmarkInstance::Run(long long, int, benchmark::internal::ThreadTimer*, benchmark::internal::ThreadManager*, benchmark::internal::PerfCountersMeasurement*) const (in storage_bench) + 172 [0x1001009ac] benchmark_api_internal.cc:98 + 8282 BM_HeapTableInsert(benchmark::State&) (in storage_bench) + 1076 [0x1000f18a8] storage_bench.cpp:71 + 1859 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 180 [0x1000f7b7c] heap_table.cpp:113 + + 789 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 176 [0x1000f5748] buffer_pool_manager.cpp:109 + + ! 334 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 300 [0x1000f68b0] lru_replacer.cpp:51 + + ! : 267 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 208 [0x1000f6ad8] __hash_table:1547 + + ! : | 239 operator new(unsigned long) (in libc++abi.dylib) + 52 [0x1830c67e8] + + ! : | + 106 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 420,88,... [0x182f32078,0x182f31f2c,...] + + ! : | + 63 (in libsystem_malloc.dylib) + 112,212,... [0x182f2c144,0x182f2c1a8,...] + + ! : | + 45 _xzm_xzone_malloc (in libsystem_malloc.dylib) + 8,180,... [0x182f2c8c8,0x182f2c974,...] + + ! : | + 23 malloc_type_malloc (in libsystem_malloc.dylib) + 28,72,... [0x182f20000,0x182f2002c,...] + + ! : | + 1 DYLD-STUB$$malloc_type_malloc (in libc++abi.dylib) + 8 [0x1830c6c18] + + ! : | + 1 _xzm_xzone_malloc_freelist_outlined (in libsystem_malloc.dylib) + 324 [0x182f3377c] + + ! : | + 1 _xzm_xzone_find_and_malloc_from_freelist_chunk (in libsystem_malloc.dylib) + 336 [0x182f34064] + + ! : | + 1 _xzm_xzone_malloc_from_freelist_chunk (in libsystem_malloc.dylib) + 556 [0x182f33d44] + + ! : | 14 DYLD-STUB$$operator new(unsigned long) (in storage_bench) + 4,0 [0x10011f274,0x10011f270] + + ! : | 14 operator new(unsigned long) (in libc++abi.dylib) + 36 [0x1830c67d8] + + ! : 13 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 32 [0x1000f6a28] __hash_table:1530 + + ! : 10 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 600 [0x1000f6c60] __hash_table:1563 + + ! : 9 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 80,88 [0x1000f6a58,0x1000f6a60] __hash_table:1535 + + ! : 9 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 552,548 [0x1000f6c30,0x1000f6c2c] __hash_table:1555 + + ! : 7 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 0 [0x1000f6a08] __hash_table:1528 + + ! : 5 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 244 [0x1000f6afc] __hash_table:1548 + + ! : 4 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 100,104 [0x1000f6a6c,0x1000f6a70] __hash_table:1536 + + ! : 3 operator new(unsigned long) (in libc++abi.dylib) + 76 [0x1830c6800] + + ! : 3 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 592 [0x1000f6c58] __hash_table:1562 + + ! : 2 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 200 [0x1000f6ad0] __hash_table:1547 + + ! : 1 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 28 [0x1000f6a24] __hash_table:1529 + + ! : 1 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 588 [0x1000f6c54] __hash_table:1561 + + ! 230 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 232 [0x1000f686c] lru_replacer.cpp:50 + + ! : 215 operator new(unsigned long) (in libc++abi.dylib) + 52 [0x1830c67e8] + + ! : | 95 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 420,88,... [0x182f32078,0x182f31f2c,...] + + ! : | 42 _xzm_xzone_malloc (in libsystem_malloc.dylib) + 8,180,... [0x182f2c8c8,0x182f2c974,...] + + ! : | 39 (in libsystem_malloc.dylib) + 112,220,... [0x182f2c144,0x182f2c1b0,...] + + ! : | 24 malloc_type_malloc (in libsystem_malloc.dylib) + 72,28,... [0x182f2002c,0x182f20000,...] + + ! : | 9 DYLD-STUB$$malloc_type_malloc (in libc++abi.dylib) + 8 [0x1830c6c18] + + ! : | 3 _xzm_xzone_malloc_freelist_outlined (in libsystem_malloc.dylib) + 324 [0x182f3377c] + + ! : | + 2 _xzm_xzone_find_and_malloc_from_freelist_chunk (in libsystem_malloc.dylib) + 116,620 [0x182f33f88,0x182f34180] + + ! : | + 1 _xzm_xzone_find_and_malloc_from_freelist_chunk (in libsystem_malloc.dylib) + 620 [0x182f34180] + + ! : | + 1 _xzm_xzone_malloc_from_empty_freelist_chunk (in libsystem_malloc.dylib) + 280 [0x182f34a80] + + ! : | 1 _xzm_xzone_malloc_freelist_outlined (in libsystem_malloc.dylib) + 248 [0x182f33730] + + ! : | + 1 _xzm_xzone_malloc_from_freelist_chunk (in libsystem_malloc.dylib) + 104 [0x182f33b80] + + ! : | 1 _xzm_xzone_malloc_freelist_outlined (in libsystem_malloc.dylib) + 28 [0x182f33654] + + ! : | 1 xzm_malloc_zone_malloc_type_malloc (in libsystem_malloc.dylib) + 0 [0x182f3811c] + + ! : 9 operator new(unsigned long) (in libc++abi.dylib) + 32,36,... [0x1830c67d4,0x1830c67d8,...] + + ! : 6 DYLD-STUB$$operator new(unsigned long) (in storage_bench) + 4 [0x10011f274] + + ! 120 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 40 [0x1000f67ac] lru_replacer.cpp:40 + + ! : 101 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] + + ! : | 88 pthread_mutex_lock (in libsystem_pthread.dylib) + 132,112,... [0x18310a480,0x18310a46c,...] + + ! : | 13 DYLD-STUB$$pthread_mutex_lock (in libc++.1.dylib) + 8 [0x183084900] + + ! : 12 std::mutex::lock() (in libc++.1.dylib) + 20,0,... [0x183022014,0x183022000,...] + + ! : 5 DYLD-STUB$$std::mutex::lock() (in storage_bench) + 4 [0x10011f130] + + ! : 2 pthread_mutex_lock (in libsystem_pthread.dylib) + 136 [0x18310a484] + + ! 46 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 312 [0x1000f68bc] lru_replacer.cpp:52 + + ! : 32 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] + + ! : | 26 pthread_mutex_unlock (in libsystem_pthread.dylib) + 104,12,... [0x18310a9ac,0x18310a950,...] + + ! : | 6 DYLD-STUB$$pthread_mutex_unlock (in libc++.1.dylib) + 8,0 [0x183084920,0x183084918] + + ! : 7 DYLD-STUB$$std::mutex::unlock() (in storage_bench) + 4,8 [0x10011f13c,0x10011f140] + + ! : 7 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] + + ! 25 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 64,100,... [0x1000f67c4,0x1000f67e8,...] lru_replacer.cpp:42 + + ! 18 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 684,680 [0x1000f6cb4,0x1000f6cb0] __hash_table:1575 + + ! 7 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 28,12 [0x1000f67a0,0x1000f6790] lru_replacer.cpp:39 + + ! 6 operator new(unsigned long) (in libc++abi.dylib) + 76 [0x1830c6800] + + ! 2 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 224 [0x1000f6864] lru_replacer.cpp:50 + + ! 1 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 300 [0x1000f68b0] lru_replacer.cpp:51 + + 375 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 60 [0x1000f56d4] buffer_pool_manager.cpp:91 + + ! 162 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 196 [0x1000f55c8] buffer_pool_manager.hpp:109 + + ! : 75 std::to_string(unsigned int) (in libc++.1.dylib) + 76 [0x183025a9c] + + ! : | 43 (in libc++.1.dylib) + 152 [0x18303a760] + + ! : | + 40 _platform_memmove (in libsystem_platform.dylib) + 452,428,... [0x183119584,0x18311956c,...] + + ! : | + 3 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] + + ! : | 32 (in libc++.1.dylib) + 16,128,... [0x18303a6d8,0x18303a748,...] + + ! : 58 std::to_string(unsigned int) (in libc++.1.dylib) + 56 [0x183025a88] + + ! : | 58 std::__itoa::__base_10_u32[abi:nqe210106](char*, unsigned int) (in libc++.1.dylib) + 0,936,... [0x183033a80,0x183033e28,...] + + ! : 14 DYLD-STUB$$std::to_string(unsigned int) (in storage_bench) + 4 [0x10011f214] + + ! : 13 (in libc++.1.dylib) + 168 [0x18303a770] + + ! : 2 std::to_string(unsigned int) (in libc++.1.dylib) + 12,56 [0x183025a5c,0x183025a88] + + ! 84 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 228 [0x1000f55e8] buffer_pool_manager.hpp:109 + + ! : 44 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] + + ! : | 31 _platform_memmove (in libsystem_platform.dylib) + 452,428,... [0x183119584,0x18311956c,...] + + ! : | 13 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] + + ! : 32 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 32,148,... [0x183021ecc,0x183021f40,...] + + ! : 8 DYLD-STUB$$std::basic_string::append(char const*, unsigned long) (in storage_bench) + 4 [0x10011eecc] + + ! 72 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 172 [0x1000f55b0] buffer_pool_manager.hpp:109 + + ! : 66 _platform_memmove (in libsystem_platform.dylib) + 428,460,... [0x18311956c,0x18311958c,...] + + ! : 6 DYLD-STUB$$memmove (in storage_bench) + 4,0 [0x10011f40c,0x10011f408] + + ! 36 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 40,32,... [0x1000f552c,0x1000f5524,...] buffer_pool_manager.hpp:109 + + ! 14 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 192,188 [0x183021f6c,0x183021f68] + + ! 7 std::to_string(unsigned int) (in libc++.1.dylib) + 104 [0x183025ab8] + + 329 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 72 [0x1000f56e0] buffer_pool_manager.cpp:92 + + ! 155 ??? (in storage_bench) load address 0x1000f0000 + 0x3db0 [0x1000f3db0] + + ! 61 ??? (in storage_bench) load address 0x1000f0000 + 0x3cd8 [0x1000f3cd8] + + ! : 25 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 380,332,... [0x1000f3f70,0x1000f3f40,...] hash.h:91 + + ! : 22 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 0 [0x1000f3df4] hash.h:87 + + ! : 14 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 452 [0x1000f3fb8] hash.h:0 + + ! 38 ??? (in storage_bench) load address 0x1000f0000 + 0x3d70 [0x1000f3d70] + + ! 37 ??? (in storage_bench) load address 0x1000f0000 + 0x3da8 [0x1000f3da8] + + ! : 26 _platform_memcmp (in libsystem_platform.dylib) + 96,8,... [0x183116f90,0x183116f38,...] + + ! : 11 DYLD-STUB$$memcmp (in storage_bench) + 4 [0x10011f3f4] + + ! 8 ??? (in storage_bench) load address 0x1000f0000 + 0x3d64 [0x1000f3d64] + + ! 6 ??? (in storage_bench) load address 0x1000f0000 + 0x3cd8 [0x1000f3cd8] + + ! 5 ??? (in storage_bench) load address 0x1000f0000 + 0x3d28 [0x1000f3d28] + + ! 5 ??? (in storage_bench) load address 0x1000f0000 + 0x3d54 [0x1000f3d54] + + ! 5 ??? (in storage_bench) load address 0x1000f0000 + 0x3d88 [0x1000f3d88] + + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x3d08 [0x1000f3d08] + + ! 2 ??? (in storage_bench) load address 0x1000f0000 + 0x3d78 [0x1000f3d78] + + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3d90 [0x1000f3d90] + + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3da8 [0x1000f3da8] + + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3dac [0x1000f3dac] + + 150 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 112 [0x1000f5708] buffer_pool_manager.cpp:96 + + ! 66 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 76 [0x1000f61a8] __hash_table:1529 + + ! : 28 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 432,352,... [0x1000f3fa4,0x1000f3f54,...] hash.h:91 + + ! : 16 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 456 [0x1000f3fbc] hash.h:123 + + ! : 16 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 0 [0x1000f3df4] hash.h:87 + + ! : 6 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 444 [0x1000f3fb0] hash.h:0 + + ! 33 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 288 [0x1000f627c] __hash_table:1541 + + ! : 21 _platform_memcmp (in libsystem_platform.dylib) + 8,56,... [0x183116f38,0x183116f68,...] + + ! : 12 DYLD-STUB$$memcmp (in storage_bench) + 4,0 [0x10011f3f4,0x10011f3f0] + + ! 14 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 220,304,... [0x1000f6238,0x1000f628c,...] __hash_table:1539 + + ! 11 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 44,52,... [0x1000f6188,0x1000f6190,...] __hash_table:1529 + + ! 7 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 16,24 [0x1000f616c,0x1000f6174] __hash_table:1528 + + ! 6 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 100,140 [0x1000f61c0,0x1000f61e8] __hash_table:1535 + + ! 4 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 240,260 [0x1000f624c,0x1000f6260] __hash_table:1541 + + ! 3 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 160,212,... [0x1000f61fc,0x1000f6230,...] __hash_table:0 + + ! 3 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 152 [0x1000f61f4] __hash_table:1536 + + ! 2 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 204 [0x1000f6228] __hash_table:1538 + + ! 1 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 80 [0x1000f61ac] __hash_table:1530 + + 70 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 44 [0x1000f56c4] buffer_pool_manager.cpp:89 + + ! 57 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] + + ! : 43 pthread_mutex_lock (in libsystem_pthread.dylib) + 112,132,... [0x18310a46c,0x18310a480,...] + + ! : 14 DYLD-STUB$$pthread_mutex_lock (in libc++.1.dylib) + 8,0 [0x183084900,0x1830848f8] + + ! 7 DYLD-STUB$$std::mutex::lock() (in storage_bench) + 4 [0x10011f130] + + ! 6 std::mutex::lock() (in libc++.1.dylib) + 20 [0x183022014] + + 65 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 220 [0x1000f5774] buffer_pool_manager.cpp:113 + + ! 55 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] + + ! : 43 pthread_mutex_unlock (in libsystem_pthread.dylib) + 104,72,... [0x18310a9ac,0x18310a98c,...] + + ! : 12 DYLD-STUB$$pthread_mutex_unlock (in libc++.1.dylib) + 8 [0x183084920] + + ! 6 std::mutex::unlock() (in libc++.1.dylib) + 16,0 [0x183022038,0x183022028] + + ! 4 DYLD-STUB$$std::mutex::unlock() (in storage_bench) + 4 [0x10011f13c] + + 15 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 12,0 [0x1000f56a4,0x1000f5698] buffer_pool_manager.cpp:88 + + 13 ??? (in storage_bench) load address 0x1000f0000 + 0x3c94 [0x1000f3c94] + + 11 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 864,868,... [0x1000f64bc,0x1000f64c0,...] __hash_table:1575 + + 10 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 284 [0x1000f5620] buffer_pool_manager.hpp:109 + + 8 ??? (in storage_bench) load address 0x1000f0000 + 0x3de4 [0x1000f3de4] + + 8 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 128 [0x1000f5718] buffer_pool_manager.cpp:99 + + 5 ??? (in storage_bench) load address 0x1000f0000 + 0x3ca8 [0x1000f3ca8] + + 3 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 160 [0x1000f5738] buffer_pool_manager.cpp:107 + + 3 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 168 [0x1000f5740] buffer_pool_manager.cpp:109 + + 3 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 320 [0x1000f68c4] lru_replacer.cpp:52 + + 1 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 224 [0x1000f5778] buffer_pool_manager.cpp:113 + + 1 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 212 [0x1000f576c] buffer_pool_manager.cpp:89 + 1778 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 136 [0x1000f7b50] heap_table.cpp:113 + + 857 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 152 [0x1000f52f0] buffer_pool_manager.cpp:54 + + ! 293 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 272 [0x1000f6768] lru_replacer.cpp:35 + + ! : 136 _xzm_free (in libsystem_malloc.dylib) + 996,684,... [0x182f2d450,0x182f2d318,...] + + ! : 68 _free (in libsystem_malloc.dylib) + 36,76,... [0x182f3cc70,0x182f3cc98,...] + + ! : 36 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] + + ! : | 24 _platform_memset (in libsystem_platform.dylib) + 180,188,... [0x1831191a4,0x1831191ac,...] + + ! : | 9 DYLD-STUB$$_platform_bzero (in libsystem_malloc.dylib) + 8 [0x182f447f4] + + ! : | 3 __bzero (in libsystem_platform.dylib) + 0,4 [0x183119090,0x183119094] + + ! : 25 DYLD-STUB$$free (in libc++abi.dylib) + 8,12 [0x1830c6bd8,0x1830c6bdc] + + ! : 24 DYLD-STUB$$operator delete(void*) (in storage_bench) + 4,8 [0x10011f25c,0x10011f260] + + ! : 1 _xzm_chunk_list_push (in libsystem_malloc.dylib) + 156 [0x182f34878] + + ! : 1 _xzm_chunk_list_slot_push (in libsystem_malloc.dylib) + 128 [0x182f35990] + + ! : | 1 _xzm_chunk_list_push (in libsystem_malloc.dylib) + 12 [0x182f347e8] + + ! : 1 free (in libsystem_malloc.dylib) + 0 [0x182f036b8] + + ! : 1 xzm_malloc_zone_try_free_default (in libsystem_malloc.dylib) + 0 [0x182f38108] + + ! 280 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 240 [0x1000f6748] lru_replacer.cpp:34 + + ! : 154 _xzm_free (in libsystem_malloc.dylib) + 996,684,... [0x182f2d450,0x182f2d318,...] + + ! : 58 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] + + ! : | 50 _platform_memset (in libsystem_platform.dylib) + 180,208,... [0x1831191a4,0x1831191c0,...] + + ! : | 6 DYLD-STUB$$_platform_bzero (in libsystem_malloc.dylib) + 8 [0x182f447f4] + + ! : | 2 __bzero (in libsystem_platform.dylib) + 0 [0x183119090] + + ! : 42 _free (in libsystem_malloc.dylib) + 0,96,... [0x182f3cc4c,0x182f3ccac,...] + + ! : 13 DYLD-STUB$$free (in libc++abi.dylib) + 8,0 [0x1830c6bd8,0x1830c6bd0] + + ! : 13 DYLD-STUB$$operator delete(void*) (in storage_bench) + 4 [0x10011f25c] + + ! 85 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 36 [0x1000f667c] lru_replacer.cpp:30 + + ! : 57 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] + + ! : | 41 pthread_mutex_lock (in libsystem_pthread.dylib) + 112,64,... [0x18310a46c,0x18310a43c,...] + + ! : | 16 DYLD-STUB$$pthread_mutex_lock (in libc++.1.dylib) + 8 [0x183084900] + + ! : 15 DYLD-STUB$$std::mutex::lock() (in storage_bench) + 4,0 [0x10011f130,0x10011f12c] + + ! : 12 std::mutex::lock() (in libc++.1.dylib) + 20 [0x183022014] + + ! : 1 pthread_mutex_lock (in libsystem_pthread.dylib) + 136 [0x18310a484] + + ! 56 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 280 [0x1000f6770] lru_replacer.cpp:37 + + ! : 44 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] + + ! : | 31 pthread_mutex_unlock (in libsystem_pthread.dylib) + 104,12,... [0x18310a9ac,0x18310a950,...] + + ! : | 13 DYLD-STUB$$pthread_mutex_unlock (in libc++.1.dylib) + 8,0 [0x183084920,0x183084918] + + ! : 6 DYLD-STUB$$std::mutex::unlock() (in storage_bench) + 4 [0x10011f13c] + + ! : 6 std::mutex::unlock() (in libc++.1.dylib) + 16,0 [0x183022038,0x183022028] + + ! 35 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 108,60,... [0x1000f66c4,0x1000f6694,...] lru_replacer.cpp:32 + + ! 29 _xzm_free (in libsystem_malloc.dylib) + 1560,1548 [0x182f2d684,0x182f2d678] + + ! 15 ??? (in storage_bench) load address 0x1000f0000 + 0x48ac [0x1000f48ac] + + ! 8 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 260 [0x1000f675c] lru_replacer.cpp:35 + + ! 7 ??? (in storage_bench) load address 0x1000f0000 + 0x47cc [0x1000f47cc] + + ! 7 ??? (in storage_bench) load address 0x1000f0000 + 0x4844 [0x1000f4844] + + ! 6 ??? (in storage_bench) load address 0x1000f0000 + 0x47a4 [0x1000f47a4] + + ! 5 ??? (in storage_bench) load address 0x1000f0000 + 0x478c [0x1000f478c] + + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x47c0 [0x1000f47c0] + + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x4800 [0x1000f4800] + + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x47b4 [0x1000f47b4] + + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x47c8 [0x1000f47c8] + + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x47d8 [0x1000f47d8] + + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x47f0 [0x1000f47f0] + + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x4808 [0x1000f4808] + + ! 3 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 12 [0x1000f6664] lru_replacer.cpp:29 + + ! 2 ??? (in storage_bench) load address 0x1000f0000 + 0x47f8 [0x1000f47f8] + + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x48a8 [0x1000f48a8] + + ! 1 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 272 [0x1000f6768] lru_replacer.cpp:30 + + ! 1 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 280 [0x1000f6770] lru_replacer.cpp:37 + + 370 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 76 [0x1000f52a4] buffer_pool_manager.cpp:50 + + ! 213 ??? (in storage_bench) load address 0x1000f0000 + 0x3db0 [0x1000f3db0] + + ! 60 ??? (in storage_bench) load address 0x1000f0000 + 0x3cd8 [0x1000f3cd8] + + ! : 32 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 380,436,... [0x1000f3f70,0x1000f3fa8,...] hash.h:91 + + ! : 20 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 0 [0x1000f3df4] hash.h:87 + + ! : 8 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 452,288 [0x1000f3fb8,0x1000f3f14] hash.h:0 + + ! 42 ??? (in storage_bench) load address 0x1000f0000 + 0x3d70 [0x1000f3d70] + + ! 29 ??? (in storage_bench) load address 0x1000f0000 + 0x3da8 [0x1000f3da8] + + ! : 20 _platform_memcmp (in libsystem_platform.dylib) + 8,48,... [0x183116f38,0x183116f60,...] + + ! : 9 DYLD-STUB$$memcmp (in storage_bench) + 4 [0x10011f3f4] + + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x3cd8 [0x1000f3cd8] + + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x3d28 [0x1000f3d28] + + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x3d64 [0x1000f3d64] + + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x3cc0 [0x1000f3cc0] + + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x3d08 [0x1000f3d08] + + ! 2 ??? (in storage_bench) load address 0x1000f0000 + 0x3d88 [0x1000f3d88] + + ! 2 ??? (in storage_bench) load address 0x1000f0000 + 0x3dd4 [0x1000f3dd4] + + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3cf0 [0x1000f3cf0] + + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3d20 [0x1000f3d20] + + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3d54 [0x1000f3d54] + + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3da8 [0x1000f3da8] + + 269 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 64 [0x1000f5298] buffer_pool_manager.cpp:49 + + ! 133 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 196 [0x1000f55c8] buffer_pool_manager.hpp:109 + + ! : 83 std::to_string(unsigned int) (in libc++.1.dylib) + 76 [0x183025a9c] + + ! : | 49 (in libc++.1.dylib) + 152 [0x18303a760] + + ! : | + 41 _platform_memmove (in libsystem_platform.dylib) + 452,0,... [0x183119584,0x1831193c0,...] + + ! : | + 8 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] + + ! : | 34 (in libc++.1.dylib) + 16,128,... [0x18303a6d8,0x18303a748,...] + + ! : 26 std::to_string(unsigned int) (in libc++.1.dylib) + 56 [0x183025a88] + + ! : | 26 std::__itoa::__base_10_u32[abi:nqe210106](char*, unsigned int) (in libc++.1.dylib) + 936,492,... [0x183033e28,0x183033c6c,...] + + ! : 13 std::to_string(unsigned int) (in libc++.1.dylib) + 36,76,... [0x183025a74,0x183025a9c,...] + + ! : 10 (in libc++.1.dylib) + 168 [0x18303a770] + + ! : 1 DYLD-STUB$$std::to_string(unsigned int) (in storage_bench) + 0 [0x10011f210] + + ! 94 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 228 [0x1000f55e8] buffer_pool_manager.hpp:109 + + ! : 50 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] + + ! : | 36 _platform_memmove (in libsystem_platform.dylib) + 452,0,... [0x183119584,0x1831193c0,...] + + ! : | 14 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] + + ! : 39 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 32,148,... [0x183021ecc,0x183021f40,...] + + ! : 5 DYLD-STUB$$std::basic_string::append(char const*, unsigned long) (in storage_bench) + 4 [0x10011eecc] + + ! 16 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 172 [0x1000f55b0] buffer_pool_manager.hpp:109 + + ! : 16 _platform_memmove (in libsystem_platform.dylib) + 12,460,... [0x1831193cc,0x18311958c,...] + + ! 10 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 188,192 [0x183021f68,0x183021f6c] + + ! 9 std::to_string(unsigned int) (in libc++.1.dylib) + 104 [0x183025ab8] + + ! 7 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 40,260,... [0x1000f552c,0x1000f5608,...] buffer_pool_manager.hpp:109 + + 128 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 116 [0x1000f52cc] buffer_pool_manager.cpp:51 + + ! 50 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 76 [0x1000f61a8] __hash_table:1529 + + ! : 23 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 400,352,... [0x1000f3f84,0x1000f3f54,...] hash.h:91 + + ! : 17 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 0,4 [0x1000f3df4,0x1000f3df8] hash.h:87 + + ! : 7 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 456 [0x1000f3fbc] hash.h:123 + + ! : 3 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 444,452 [0x1000f3fb0,0x1000f3fb8] hash.h:0 + + ! 28 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 288 [0x1000f627c] __hash_table:1541 + + ! : 22 _platform_memcmp (in libsystem_platform.dylib) + 0,48,... [0x183116f30,0x183116f60,...] + + ! : 6 DYLD-STUB$$memcmp (in storage_bench) + 4 [0x10011f3f4] + + ! 12 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 240,260,... [0x1000f624c,0x1000f6260,...] __hash_table:1541 + + ! 10 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 220,296,... [0x1000f6238,0x1000f6284,...] __hash_table:1539 + + ! 9 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 16,20 [0x1000f616c,0x1000f6170] __hash_table:1528 + + ! 6 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 100,128,... [0x1000f61c0,0x1000f61dc,...] __hash_table:1535 + + ! 4 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 152 [0x1000f61f4] __hash_table:1536 + + ! 3 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 212 [0x1000f6230] __hash_table:0 + + ! 3 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 68 [0x1000f61a0] __hash_table:1529 + + ! 2 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 204 [0x1000f6228] __hash_table:1538 + + ! 1 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 156 [0x1000f61f8] __hash_table:1537 + + 64 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 548 [0x1000f547c] buffer_pool_manager.cpp:86 + + ! 47 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] + + ! : 39 pthread_mutex_unlock (in libsystem_pthread.dylib) + 104,12,... [0x18310a9ac,0x18310a950,...] + + ! : 8 DYLD-STUB$$pthread_mutex_unlock (in libc++.1.dylib) + 8 [0x183084920] + + ! 9 std::mutex::unlock() (in libc++.1.dylib) + 16,0 [0x183022038,0x183022028] + + ! 8 DYLD-STUB$$std::mutex::unlock() (in storage_bench) + 4,8 [0x10011f13c,0x10011f140] + + 21 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 48 [0x1000f5288] buffer_pool_manager.cpp:47 + + ! 18 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] + + ! : 18 pthread_mutex_lock (in libsystem_pthread.dylib) + 4,108,... [0x18310a400,0x18310a468,...] + + ! 3 std::mutex::lock() (in libc++.1.dylib) + 20 [0x183022014] + + 15 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 524 [0x1000f5464] buffer_pool_manager.cpp:86 + + 14 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 864,868,... [0x1000f64bc,0x1000f64c0,...] __hash_table:1575 + + 11 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 16,20 [0x1000f5268,0x1000f526c] buffer_pool_manager.cpp:46 + + 6 ??? (in storage_bench) load address 0x1000f0000 + 0x3de4 [0x1000f3de4] + + 6 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 496 [0x1000f5448] buffer_pool_manager.cpp:79 + + ! 3 cloudsql::storage::StorageManager::read_page(std::basic_string const&, unsigned int, char*) (in storage_bench) + 140 [0x1000f3748] storage_manager.cpp:107 + + ! : 3 std::basic_istream::seekg(long long, std::ios_base::seekdir) (in libc++.1.dylib) + 196 [0x183025f14] + + ! : 2 std::basic_filebuf::seekoff(long long, std::ios_base::seekdir, unsigned int) (in libc++.1.dylib) + 132 [0x183055e14] + + ! : | 2 std::basic_filebuf::sync() (in libc++.1.dylib) + 500 [0x18305618c] + + ! : | 1 DYLD-STUB$$fseeko (in libc++.1.dylib) + 0 [0x183084648] + + ! : | 1 fseeko (in libsystem_c.dylib) + 92 [0x182fb2594] + + ! : | 1 _fseeko (in libsystem_c.dylib) + 16 [0x182fcee9c] + + ! : 1 std::basic_filebuf::seekoff(long long, std::ios_base::seekdir, unsigned int) (in libc++.1.dylib) + 232 [0x183055e78] + + ! : 1 ftello (in libsystem_c.dylib) + 44 [0x182fb2a70] + + ! : 1 _ftello (in libsystem_c.dylib) + 188 [0x182fcd138] + + ! : 1 _sseek (in libsystem_c.dylib) + 72 [0x182fb2af8] + + ! : 1 __lseek (in libsystem_kernel.dylib) + 8 [0x1830cd624] + + ! 3 cloudsql::storage::StorageManager::read_page(std::basic_string const&, unsigned int, char*) (in storage_bench) + 192 [0x1000f377c] storage_manager.cpp:114 + + ! 3 std::basic_istream::read(char*, long) (in libc++.1.dylib) + 136 [0x183024e80] + + ! 3 std::basic_streambuf::xsgetn(char*, long) (in libc++.1.dylib) + 156 [0x183024ff0] + + ! 3 std::basic_streambuf::uflow() (in libc++.1.dylib) + 48 [0x18302505c] + + ! 3 std::basic_filebuf::underflow() (in libc++.1.dylib) + 264 [0x183055778] + + ! 3 fread (in libsystem_c.dylib) + 136 [0x182fb2c5c] + + ! 3 __fread (in libsystem_c.dylib) + 336 [0x182faa308] + + ! 3 __srefill1 (in libsystem_c.dylib) + 36 [0x182faa0f0] + + ! 2 _sread (in libsystem_c.dylib) + 0 [0x182faa13c] + + ! 1 _sread (in libsystem_c.dylib) + 32 [0x182faa15c] + + ! 1 __sread (in libsystem_c.dylib) + 24 [0x182fcd074] + + ! 1 __read_nocancel (in libsystem_kernel.dylib) + 8 [0x1830cdcac] + + 6 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 284 [0x1000f5620] buffer_pool_manager.hpp:109 + + 5 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 288 [0x1000f6778] lru_replacer.cpp:37 + + 3 ??? (in storage_bench) load address 0x1000f0000 + 0x3c94 [0x1000f3c94] + + 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3dd8 [0x1000f3dd8] + + 1 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 64 [0x1000f5298] buffer_pool_manager.cpp:50 + + 1 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 92 [0x1000f52b4] buffer_pool_manager.cpp:51 + 1756 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 160 [0x1000f7b68] heap_table.cpp:113 + + 1752 _platform_memmove (in libsystem_platform.dylib) + 180,204,... [0x183119474,0x18311948c,...] + + 4 DYLD-STUB$$memcpy (in storage_bench) + 4 [0x10011f400] + 673 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 528 [0x1000f7cd8] heap_table.cpp:134 + + 543 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 108 [0x183021f18] + + ! 255 std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) + 180 [0x183023064] + + ! : 211 $_0::operator()() const::'lambda0'(unsigned long, std::__type_descriptor_t)::__invoke(unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 16 [0x1830c54a8] + + ! : | 202 operator_new_impl[abi:nqe210106](unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 36 [0x1830c54dc] + + ! : | + 113 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 88,104,... [0x182f31f2c,0x182f31f3c,...] + + ! : | + 39 _xzm_xzone_malloc (in libsystem_malloc.dylib) + 8,0,... [0x182f2c8c8,0x182f2c8c0,...] + + ! : | + 21 (in libsystem_malloc.dylib) + 96,112,... [0x182f2c134,0x182f2c144,...] + + ! : | + 18 malloc_type_malloc (in libsystem_malloc.dylib) + 72,16,... [0x182f2002c,0x182f1fff4,...] + + ! : | + 10 DYLD-STUB$$malloc_type_malloc (in libc++abi.dylib) + 8 [0x1830c6c18] + + ! : | + 1 xzm_malloc_zone_malloc_type_malloc (in libsystem_malloc.dylib) + 0 [0x182f3811c] + + ! : | 9 operator_new_impl[abi:nqe210106](unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 8 [0x1830c54c0] + + ! : 18 new(unsigned long, std::__type_descriptor_t) (in libc++.1.dylib) + 8,0 [0x1830842a0,0x183084298] + + ! : 13 operator new(unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 4,0 [0x1830c5370,0x1830c536c] + + ! : 9 operator_new_impl[abi:nqe210106](unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 68 [0x1830c54fc] + + ! : 4 $_0::operator()() const::'lambda0'(unsigned long, std::__type_descriptor_t)::__invoke(unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 20,0,... [0x1830c54ac,0x1830c5498,...] + + ! 118 std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) + 224 [0x183023090] + + ! : 107 _platform_memmove (in libsystem_platform.dylib) + 428,452,... [0x18311956c,0x183119584,...] + + ! : 11 DYLD-STUB$$memcpy (in libc++.1.dylib) + 8 [0x1830847b0] + + ! 91 std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) + 204 [0x18302307c] + + ! : 84 _platform_memmove (in libsystem_platform.dylib) + 452,444,... [0x183119584,0x18311957c,...] + + ! : 7 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] + + ! 79 std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) + 24,224,... [0x183022fc8,0x183023090,...] + + 62 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 108,32,... [0x183021f18,0x183021ecc,...] + + 42 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] + + ! 30 _platform_memmove (in libsystem_platform.dylib) + 452,428,... [0x183119584,0x18311956c,...] + + ! 12 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] + + 20 DYLD-STUB$$std::basic_string::append(char const*, unsigned long) (in storage_bench) + 4,0 [0x10011eecc,0x10011eec8] + + 6 std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) + 320,308 [0x1830230f0,0x1830230e4] + 605 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 460 [0x1000f7c94] heap_table.cpp:134 + + 241 std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) + 80 [0x1000ff870] string:2393 + + ! 222 operator new(unsigned long) (in libc++abi.dylib) + 52 [0x1830c67e8] + + ! : 102 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 88,52,... [0x182f31f2c,0x182f31f08,...] + + ! : 48 _xzm_xzone_malloc (in libsystem_malloc.dylib) + 180,324,... [0x182f2c974,0x182f2ca04,...] + + ! : 43 (in libsystem_malloc.dylib) + 0,112,... [0x182f2c0d4,0x182f2c144,...] + + ! : 24 malloc_type_malloc (in libsystem_malloc.dylib) + 28,72,... [0x182f20000,0x182f2002c,...] + + ! : 4 DYLD-STUB$$malloc_type_malloc (in libc++abi.dylib) + 8 [0x1830c6c18] + + ! : 1 xzm_malloc_zone_malloc_type_malloc (in libsystem_malloc.dylib) + 0 [0x182f3811c] + + ! 10 operator new(unsigned long) (in libc++abi.dylib) + 24,36,... [0x1830c67cc,0x1830c67d8,...] + + ! 9 DYLD-STUB$$operator new(unsigned long) (in storage_bench) + 4 [0x10011f274] + + 95 _platform_memmove (in libsystem_platform.dylib) + 428,452,... [0x18311956c,0x183119584,...] + + 78 std::to_string(long long) (in libc++.1.dylib) + 432 [0x183027acc] + + ! 39 (in libc++.1.dylib) + 152 [0x18303a760] + + ! : 32 _platform_memmove (in libsystem_platform.dylib) + 452,460,... [0x183119584,0x18311958c,...] + + ! : 7 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] + + ! 39 (in libc++.1.dylib) + 0,16,... [0x18303a6c8,0x18303a6d8,...] + + 40 cloudsql::common::Value::to_string() const (in storage_bench) + 36,64,... [0x1000f7f7c,0x1000f7f98,...] value.hpp:273 + + 39 std::to_string(long long) (in libc++.1.dylib) + 172 [0x1830279c8] + + ! 39 std::__itoa::__base_10_u32[abi:nqe210106](char*, unsigned int) (in libc++.1.dylib) + 936,0,... [0x183033e28,0x183033a80,...] + + 35 std::to_string(long long) (in libc++.1.dylib) + 56,156,... [0x183027954,0x1830279b8,...] + + 14 std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) + 8 [0x1000ff828] string:2382 + + 13 (in libc++.1.dylib) + 168,164 [0x18303a770,0x18303a76c] + + 8 DYLD-STUB$$memmove (in storage_bench) + 4 [0x10011f40c] + + 8 DYLD-STUB$$std::to_string(long long) (in storage_bench) + 4 [0x10011f220] + + 8 cloudsql::common::Value::to_string() const (in storage_bench) + 192,196 [0x1000f8018,0x1000f801c] value.hpp:0 + + 8 cloudsql::common::Value::to_string() const (in storage_bench) + 500 [0x1000f814c] value.hpp:289 + + 8 std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) + 76 [0x1000ff86c] string:2393 + + 3 cloudsql::common::Value::to_string() const (in storage_bench) + 32,0 [0x1000f7f78,0x1000f7f58] value.hpp:272 + + 3 operator new(unsigned long) (in libc++abi.dylib) + 76 [0x1830c6800] + + 3 std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) + 36 [0x1000ff844] string:0 + + 1 std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) + 80 [0x1000ff870] string:2397 + 495 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 116 [0x1000f7b3c] heap_table.cpp:163 + + 209 _xzm_free (in libsystem_malloc.dylib) + 1048 [0x182f2d484] + + ! 201 mach_absolute_time (in libsystem_kernel.dylib) + 108,112,... [0x1830cc10c,0x1830cc110,...] + + ! 8 DYLD-STUB$$mach_absolute_time (in libsystem_malloc.dylib) + 8 [0x182f44b14] + + 126 _xzm_free (in libsystem_malloc.dylib) + 684,164,... [0x182f2d318,0x182f2d110,...] + + 89 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] + + ! 74 _platform_memset (in libsystem_platform.dylib) + 180,208,... [0x1831191a4,0x1831191c0,...] + + ! 14 DYLD-STUB$$_platform_bzero (in libsystem_malloc.dylib) + 8 [0x182f447f4] + + ! 1 __bzero (in libsystem_platform.dylib) + 0 [0x183119090] + + 40 _free (in libsystem_malloc.dylib) + 0,44,... [0x182f3cc4c,0x182f3cc78,...] + + 23 DYLD-STUB$$operator delete(void*) (in storage_bench) + 4,0 [0x10011f25c,0x10011f258] + + 8 DYLD-STUB$$free (in libc++abi.dylib) + 8 [0x1830c6bd8] + 299 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 472 [0x1000f7ca0] heap_table.cpp:134 + + 109 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] + + ! 65 _platform_memmove (in libsystem_platform.dylib) + 428,0,... [0x18311956c,0x1831193c0,...] + + ! 44 DYLD-STUB$$memmove (in libc++.1.dylib) + 8,0 [0x1830847c0,0x1830847b8] + + 99 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 32,148,... [0x183021ecc,0x183021f40,...] + + 66 std::basic_string::append(char const*) (in libc++.1.dylib) + 32 [0x1830245c8] + + ! 42 _platform_strlen (in libsystem_platform.dylib) + 56,80,... [0x183116b18,0x183116b30,...] + + ! 24 DYLD-STUB$$strlen (in libc++.1.dylib) + 8 [0x183084a90] + + 25 DYLD-STUB$$std::basic_string::append(char const*) (in storage_bench) + 4,0 [0x10011eec0,0x10011eebc] + 279 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 428 [0x1000f7c74] heap_table.cpp:134 + + 141 _xzm_free (in libsystem_malloc.dylib) + 672,996,... [0x182f2d30c,0x182f2d450,...] + + 54 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] + + ! 50 _platform_memset (in libsystem_platform.dylib) + 180,208,... [0x1831191a4,0x1831191c0,...] + + ! 2 DYLD-STUB$$_platform_bzero (in libsystem_malloc.dylib) + 8 [0x182f447f4] + + ! 2 __bzero (in libsystem_platform.dylib) + 0 [0x183119090] + + 48 _free (in libsystem_malloc.dylib) + 0,44,... [0x182f3cc4c,0x182f3cc78,...] + + 20 DYLD-STUB$$operator delete(void*) (in storage_bench) + 4,0 [0x10011f25c,0x10011f258] + + 14 DYLD-STUB$$free (in libc++abi.dylib) + 8 [0x1830c6bd8] + + 1 free (in libsystem_malloc.dylib) + 0 [0x182f036b8] + + 1 xzm_malloc_zone_try_free_default (in libsystem_malloc.dylib) + 0 [0x182f38108] + 151 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 368 [0x1000f7c38] heap_table.cpp:132 + + 65 std::basic_string::append(char const*) (in libc++.1.dylib) + 32 [0x1830245c8] + + ! 52 _platform_strlen (in libsystem_platform.dylib) + 56,80,... [0x183116b18,0x183116b30,...] + + ! 13 DYLD-STUB$$strlen (in libc++.1.dylib) + 8 [0x183084a90] + + 52 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] + + ! 40 _platform_memmove (in libsystem_platform.dylib) + 452,428,... [0x183119584,0x18311956c,...] + + ! 12 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] + + 31 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 32,112,... [0x183021ecc,0x183021f1c,...] + + 2 DYLD-STUB$$std::basic_string::append(char const*) (in storage_bench) + 4 [0x10011eec0] + + 1 std::basic_string::append(char const*) (in libc++.1.dylib) + 8 [0x1830245b0] + 127 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 352 [0x1000f7c28] heap_table.cpp:132 + + 65 std::to_string(unsigned long long) (in libc++.1.dylib) + 348 [0x183043540] + + ! 36 (in libc++.1.dylib) + 16,128,... [0x18303a6d8,0x18303a748,...] + + ! 29 (in libc++.1.dylib) + 152 [0x18303a760] + + ! 21 _platform_memmove (in libsystem_platform.dylib) + 0,428,... [0x1831193c0,0x18311956c,...] + + ! 8 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] + + 30 std::to_string(unsigned long long) (in libc++.1.dylib) + 72 [0x18304342c] + + ! 30 std::__itoa::__base_10_u32[abi:nqe210106](char*, unsigned int) (in libc++.1.dylib) + 28,0,... [0x183033a9c,0x183033a80,...] + + 14 (in libc++.1.dylib) + 168 [0x18303a770] + + 10 std::to_string(unsigned long long) (in libc++.1.dylib) + 48,328,... [0x183043414,0x18304352c,...] + + 8 DYLD-STUB$$std::to_string(unsigned long long) (in storage_bench) + 4 [0x10011f22c] + 59 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 188,192,... [0x183021f68,0x183021f6c,...] + 36 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 420,536,... [0x1000f7c6c,0x1000f7ce0,...] heap_table.cpp:134 + 33 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 436,412,... [0x1000f7c7c,0x1000f7c64,...] heap_table.cpp:133 + 26 std::basic_string::append(char const*) (in libc++.1.dylib) + 56,48 [0x1830245e0,0x1830245d8] + 25 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 160,136 [0x1000f7b68,0x1000f7b50] heap_table.cpp:113 + 23 _xzm_free (in libsystem_malloc.dylib) + 1560,1552,... [0x182f2d684,0x182f2d67c,...] + 15 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 344,352,... [0x1000f7c20,0x1000f7c28,...] heap_table.cpp:132 + 9 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 592 [0x1000f7d18] heap_table.cpp:140 + 7 std::to_string(long long) (in libc++.1.dylib) + 468 [0x183027af0] + 5 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 748 [0x1000f7db4] heap_table.cpp:157 + + 5 _platform_memmove (in libsystem_platform.dylib) + 180,192 [0x183119474,0x183119480] + 5 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 768 [0x1000f7dc8] heap_table.cpp:157 + + 3 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 176 [0x1000f5748] buffer_pool_manager.cpp:109 + + ! 2 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 232 [0x1000f686c] lru_replacer.cpp:50 + + ! : 2 operator new(unsigned long) (in libc++abi.dylib) + 52 [0x1830c67e8] + + ! : 1 (in libsystem_malloc.dylib) + 112 [0x182f2c144] + + ! : 1 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 12 [0x182f31ee0] + + ! 1 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 312 [0x1000f68bc] lru_replacer.cpp:52 + + ! 1 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] + + ! 1 pthread_mutex_unlock (in libsystem_pthread.dylib) + 32 [0x18310a964] + + 1 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 60 [0x1000f56d4] buffer_pool_manager.cpp:91 + + ! 1 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 228 [0x1000f55e8] buffer_pool_manager.hpp:109 + + ! 1 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] + + ! 1 _platform_memmove (in libsystem_platform.dylib) + 452 [0x183119584] + + 1 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 72 [0x1000f56e0] buffer_pool_manager.cpp:92 + + 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3d20 [0x1000f3d20] + 4 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 568 [0x1000f5490] buffer_pool_manager.cpp:86 + 4 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 556 [0x1000f7cf4] heap_table.cpp:137 + 3 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 232 [0x1000f5780] buffer_pool_manager.cpp:113 + 3 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 700 [0x1000f7d84] heap_table.cpp:157 + + 1 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 48 [0x1000f5288] buffer_pool_manager.cpp:47 + + ! 1 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] + + ! 1 pthread_mutex_lock (in libsystem_pthread.dylib) + 64 [0x18310a43c] + + 1 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 76 [0x1000f52a4] buffer_pool_manager.cpp:50 + + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3cc0 [0x1000f3cc0] + + 1 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 152 [0x1000f52f0] buffer_pool_manager.cpp:54 + + 1 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 240 [0x1000f6748] lru_replacer.cpp:34 + + 1 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] + + 1 _platform_memset (in libsystem_platform.dylib) + 208 [0x1831191c0] + 2 std::to_string(unsigned long long) (in libc++.1.dylib) + 384 [0x183043564] + 1 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 324 [0x1000f7c0c] heap_table.cpp:125 + +Total number in stack (recursive counted multiple, when >=5): + 17 _platform_memmove (in libsystem_platform.dylib) + 0 [0x1831193c0] + 10 DYLD-STUB$$memmove (in libc++.1.dylib) + 0 [0x1830847b8] + 8 (in libc++.1.dylib) + 0 [0x18303a6c8] + 8 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 0 [0x183021eac] + 7 pthread_mutex_lock (in libsystem_pthread.dylib) + 0 [0x18310a3fc] + 6 _xzm_free (in libsystem_malloc.dylib) + 0 [0x182f2d06c] + 6 operator new(unsigned long) (in libc++abi.dylib) + 0 [0x1830c67b4] + 6 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] + 5 (in libsystem_malloc.dylib) + 0 [0x182f2c0d4] + 5 _platform_memset (in libsystem_platform.dylib) + 0 [0x1831190f0] + 5 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] + 5 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 0 [0x182f31ed4] + 5 pthread_mutex_unlock (in libsystem_pthread.dylib) + 0 [0x18310a944] + 5 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] + 5 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] + +Sort by top of stack, same collapsed (when >= 5): + _platform_memmove (in libsystem_platform.dylib) 2462 + _xzm_free (in libsystem_malloc.dylib) 609 + _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) 417 + ??? (in storage_bench) load address 0x1000f0000 + 0x3db0 [0x1000f3db0] 368 + std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) 346 + std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) 237 + mach_absolute_time (in libsystem_kernel.dylib) 201 + _platform_memset (in libsystem_platform.dylib) 199 + _free (in libsystem_malloc.dylib) 198 + pthread_mutex_lock (in libsystem_pthread.dylib) 194 + (in libc++.1.dylib) 191 + _xzm_xzone_malloc (in libsystem_malloc.dylib) 174 + (in libsystem_malloc.dylib) 167 + std::__itoa::__base_10_u32[abi:nqe210106](char*, unsigned int) (in libc++.1.dylib) 153 + pthread_mutex_unlock (in libsystem_pthread.dylib) 140 + DYLD-STUB$$memmove (in libc++.1.dylib) 128 + std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) 126 + cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) 123 + _platform_strlen (in libsystem_platform.dylib) 94 + _platform_memcmp (in libsystem_platform.dylib) 89 + malloc_type_malloc (in libsystem_malloc.dylib) 89 + std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) 85 + std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) 82 + ??? (in storage_bench) load address 0x1000f0000 + 0x3d70 [0x1000f3d70] 80 + DYLD-STUB$$operator delete(void*) (in storage_bench) 80 + DYLD-STUB$$free (in libc++abi.dylib) 60 + cloudsql::common::Value::to_string() const (in storage_bench) 59 + cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) 59 + cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) 53 + operator new(unsigned long) (in libc++abi.dylib) 45 + DYLD-STUB$$pthread_mutex_lock (in libc++.1.dylib) 43 + std::to_string(long long) (in libc++.1.dylib) 42 + DYLD-STUB$$pthread_mutex_unlock (in libc++.1.dylib) 39 + DYLD-STUB$$memcmp (in storage_bench) 38 + cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) 38 + DYLD-STUB$$strlen (in libc++.1.dylib) 37 + cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) 34 + DYLD-STUB$$std::basic_string::append(char const*, unsigned long) (in storage_bench) 33 + std::mutex::lock() (in libc++.1.dylib) 33 + cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) 32 + DYLD-STUB$$_platform_bzero (in libsystem_malloc.dylib) 31 + std::to_string(unsigned int) (in libc++.1.dylib) 31 + DYLD-STUB$$operator new(unsigned long) (in storage_bench) 29 + std::mutex::unlock() (in libc++.1.dylib) 28 + DYLD-STUB$$std::basic_string::append(char const*) (in storage_bench) 27 + DYLD-STUB$$std::mutex::lock() (in storage_bench) 27 + std::basic_string::append(char const*) (in libc++.1.dylib) 27 + std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) 26 + DYLD-STUB$$std::mutex::unlock() (in storage_bench) 25 + DYLD-STUB$$malloc_type_malloc (in libc++abi.dylib) 24 + new(unsigned long, std::__type_descriptor_t) (in libc++.1.dylib) 18 + operator_new_impl[abi:nqe210106](unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) 18 + ??? (in storage_bench) load address 0x1000f0000 + 0x3c94 [0x1000f3c94] 16 + ??? (in storage_bench) load address 0x1000f0000 + 0x48ac [0x1000f48ac] 15 + DYLD-STUB$$std::to_string(unsigned int) (in storage_bench) 15 + ??? (in storage_bench) load address 0x1000f0000 + 0x3de4 [0x1000f3de4] 14 + DYLD-STUB$$memmove (in storage_bench) 14 + operator new(unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) 13 + ??? (in storage_bench) load address 0x1000f0000 + 0x3d64 [0x1000f3d64] 12 + std::to_string(unsigned long long) (in libc++.1.dylib) 12 + DYLD-STUB$$memcpy (in libc++.1.dylib) 11 + ??? (in storage_bench) load address 0x1000f0000 + 0x3cd8 [0x1000f3cd8] 10 + ??? (in storage_bench) load address 0x1000f0000 + 0x3d28 [0x1000f3d28] 9 + DYLD-STUB$$mach_absolute_time (in libsystem_malloc.dylib) 8 + DYLD-STUB$$std::to_string(long long) (in storage_bench) 8 + DYLD-STUB$$std::to_string(unsigned long long) (in storage_bench) 8 + __bzero (in libsystem_platform.dylib) 8 + ??? (in storage_bench) load address 0x1000f0000 + 0x3d08 [0x1000f3d08] 7 + ??? (in storage_bench) load address 0x1000f0000 + 0x3d88 [0x1000f3d88] 7 + ??? (in storage_bench) load address 0x1000f0000 + 0x47cc [0x1000f47cc] 7 + ??? (in storage_bench) load address 0x1000f0000 + 0x4844 [0x1000f4844] 7 + ??? (in storage_bench) load address 0x1000f0000 + 0x3d54 [0x1000f3d54] 6 + ??? (in storage_bench) load address 0x1000f0000 + 0x47a4 [0x1000f47a4] 6 + ??? (in storage_bench) load address 0x1000f0000 + 0x3ca8 [0x1000f3ca8] 5 + ??? (in storage_bench) load address 0x1000f0000 + 0x478c [0x1000f478c] 5 + +Binary Images: + 0x1000f0000 - 0x100124cef +storage_bench (0) <36C28C6B-B05F-3511-B235-E2888FE43F53> /Users/*/storage_bench + 0x182cac000 - 0x182cfeb4b libobjc.A.dylib (951.7) <2E858E25-1FF6-3DA6-84F6-911630620512> /usr/lib/libobjc.A.dylib + 0x182cff000 - 0x182d33b34 libdyld.dylib (1376.6) <2C3C5F75-3686-39A1-9202-BD4D2133379D> /usr/lib/system/libdyld.dylib + 0x182d34000 - 0x182dd9ec7 dyld (1.0.0 - 1376.6) <9F682DCF-340C-3BFA-BCDD-DD702F30313E> /usr/lib/dyld + 0x182dda000 - 0x182ddd228 libsystem_blocks.dylib (96) <2EA73169-CF76-3DD1-9869-F23C8B338022> /usr/lib/system/libsystem_blocks.dylib + 0x182dde000 - 0x182e3251f libxpc.dylib (3102.100.102) <618039C8-9965-3782-A7D2-90FD4C3DD66F> /usr/lib/system/libxpc.dylib + 0x182e33000 - 0x182e539bf libsystem_trace.dylib (1861.100.19) <08629650-54FC-3AA6-910E-EACA563804D0> /usr/lib/system/libsystem_trace.dylib + 0x182e54000 - 0x182f01daf libcorecrypto.dylib (1922.101.2) /usr/lib/system/libcorecrypto.dylib + 0x182f02000 - 0x182f521d7 libsystem_malloc.dylib (812.100.31) <2AD21BE3-FFDB-31D5-A3D7-2F7F672D6E92> /usr/lib/system/libsystem_malloc.dylib + 0x182f53000 - 0x182f9a23f libdispatch.dylib (1542.100.32) /usr/lib/system/libdispatch.dylib + 0x182f9b000 - 0x182f9dffb libsystem_featureflags.dylib (103) <0DE01F76-4B36-35A2-98F9-43DD147EDD95> /usr/lib/system/libsystem_featureflags.dylib + 0x182f9e000 - 0x18301eef7 libsystem_c.dylib (1752.100.10) <66EBD321-6899-3863-BA24-5CFC3076A0CB> /usr/lib/system/libsystem_c.dylib + 0x18301f000 - 0x1830afae7 libc++.1.dylib (2100.43) <1E9541EC-C564-38CB-BED6-46F708E8D863> /usr/lib/libc++.1.dylib + 0x1830b0000 - 0x1830ca75f libc++abi.dylib (2100.43) /usr/lib/libc++abi.dylib + 0x1830cb000 - 0x18310828f libsystem_kernel.dylib (12377.101.15) <51565B39-F595-3E96-A217-FEF29815057A> /usr/lib/system/libsystem_kernel.dylib + 0x183109000 - 0x183115b3b libsystem_pthread.dylib (539.100.4) /usr/lib/system/libsystem_pthread.dylib + 0x183116000 - 0x18311e8f3 libsystem_platform.dylib (375.100.10) /usr/lib/system/libsystem_platform.dylib + 0x18311f000 - 0x18314e6eb libsystem_info.dylib (600) <201FD67C-3DF6-3788-B132-A69CAA2AA3D7> /usr/lib/system/libsystem_info.dylib + 0x1870e4000 - 0x1870ede5f libsystem_darwin.dylib (1752.100.10) /usr/lib/system/libsystem_darwin.dylib + 0x18754f000 - 0x187560f5b libsystem_notify.dylib (348.100.7) <9F46F30B-B7C0-3DD7-AC38-57B78C7971FF> /usr/lib/system/libsystem_notify.dylib + 0x189819000 - 0x189833f5b libsystem_networkextension.dylib (2226.101.1) <85169C7B-48DD-3542-AD38-F1B88EA2A95A> /usr/lib/system/libsystem_networkextension.dylib + 0x1898b6000 - 0x1898cdfdf libsystem_asl.dylib (406) <6427D987-7938-3278-8C14-10FB9C06BBD5> /usr/lib/system/libsystem_asl.dylib + 0x18b471000 - 0x18b479387 libsystem_symptoms.dylib (2169.100.30) <28B6E34E-9C7D-3437-A3F1-A3C979DE579A> /usr/lib/system/libsystem_symptoms.dylib + 0x18f70c000 - 0x18f74425f libsystem_containermanager.dylib (725.100.37) <14750F95-BB3A-3654-8610-A05A454643A8> /usr/lib/system/libsystem_containermanager.dylib + 0x190b1c000 - 0x190b205d7 libsystem_configuration.dylib (1405.100.8) <634F597D-F8BD-3C00-B967-86047FC15D14> /usr/lib/system/libsystem_configuration.dylib + 0x190b21000 - 0x190b278cf libsystem_sandbox.dylib (2680.100.174) /usr/lib/system/libsystem_sandbox.dylib + 0x192167000 - 0x19216a1fb libquarantine.dylib (196.100.8) <268FEB6E-A237-3050-BFFF-AE3A66B7EAD4> /usr/lib/system/libquarantine.dylib + 0x192906000 - 0x19290cd03 libsystem_coreservices.dylib (191.4.5) <7129349D-04F9-3C3C-BF37-3082C1468654> /usr/lib/system/libsystem_coreservices.dylib + 0x192e8b000 - 0x192ec8a77 libsystem_m.dylib (3312.100.1) <83B173CD-7F32-3901-8E67-C0B2676BE015> /usr/lib/system/libsystem_m.dylib + 0x192eca000 - 0x192ecd527 libmacho.dylib (1376.6) <9729ECEA-0A08-32E3-8BDB-B42FC15FF258> /usr/lib/system/libmacho.dylib + 0x192ee7000 - 0x192ef43a7 libcommonCrypto.dylib (600035) <710EC5FA-F77C-3646-A9E3-C037C42E1539> /usr/lib/system/libcommonCrypto.dylib + 0x192ef5000 - 0x192efeca3 libunwind.dylib (2100.2) /usr/lib/system/libunwind.dylib + 0x192f07000 - 0x192f117ff libcopyfile.dylib (240) <0B7FF027-5579-3CBF-A12B-68A4FD36641C> /usr/lib/system/libcopyfile.dylib + 0x192f12000 - 0x192f15987 libcompiler_rt.dylib (103.3) <65E29E6E-7042-3F73-A1D2-F2C4EBCD7524> /usr/lib/system/libcompiler_rt.dylib + 0x192f16000 - 0x192f1a78b libsystem_collections.dylib (1752.100.10) /usr/lib/system/libsystem_collections.dylib + 0x192f1b000 - 0x192f1e4cf libsystem_secinit.dylib (168.100.7) /usr/lib/system/libsystem_secinit.dylib + 0x192f1f000 - 0x192f21bf7 libremovefile.dylib (85.100.6) /usr/lib/system/libremovefile.dylib + 0x192f22000 - 0x192f22f27 libkeymgr.dylib (31) /usr/lib/system/libkeymgr.dylib + 0x192f23000 - 0x192f2be3f libsystem_dnssd.dylib (2881.100.56.0.1) /usr/lib/system/libsystem_dnssd.dylib + 0x192f2c000 - 0x192f3109b libcache.dylib (95) <4D6833A3-C910-3A76-AA8A-303F698B36BF> /usr/lib/system/libcache.dylib + 0x192f32000 - 0x192f33ce3 libSystem.B.dylib (1356) /usr/lib/libSystem.B.dylib + 0x285815000 - 0x28581c349 libRosetta.dylib (367.5) <2FC1EF06-04C4-35FC-8DC3-BEA1E9FBD63F> /usr/lib/libRosetta.dylib + 0x2874f2000 - 0x2874f5a4b libsystem_darwindirectory.dylib (122) /usr/lib/system/libsystem_darwindirectory.dylib + 0x2874f6000 - 0x2874ff5a7 libsystem_eligibility.dylib (319.101.1) <2D19994A-87BB-34B8-A343-CB8DD47FF110> /usr/lib/system/libsystem_eligibility.dylib + 0x287500000 - 0x2875078db libsystem_sanitizers.dylib (26) /usr/lib/system/libsystem_sanitizers.dylib + 0x287508000 - 0x287508bb7 libsystem_trial.dylib (474.2.18) <5BB81430-4E33-3160-94D2-1FFB2B614DB2> /usr/lib/system/libsystem_trial.dylib diff --git a/src/executor/operator.cpp b/src/executor/operator.cpp index 6b8be50..9e751a2 100644 --- a/src/executor/operator.cpp +++ b/src/executor/operator.cpp @@ -237,7 +237,7 @@ bool FilterOperator::next(Tuple& out_tuple) { Tuple tuple; while (child_->next(tuple)) { /* Evaluate condition against the current tuple context */ - const common::Value result = condition_->evaluate(&tuple, &schema_); + const common::Value result = condition_->evaluate(&tuple, &schema_, get_params()); if (result.as_bool()) { out_tuple = std::move(tuple); return true; @@ -260,6 +260,16 @@ void FilterOperator::add_child(std::unique_ptr child) { child_ = std::move(child); } +void FilterOperator::set_memory_resource(std::pmr::memory_resource* mr) { + Operator::set_memory_resource(mr); + if (child_) child_->set_memory_resource(mr); +} + +void FilterOperator::set_params(const std::vector* params) { + Operator::set_params(params); + if (child_) child_->set_params(params); +} + /* --- ProjectOperator --- */ ProjectOperator::ProjectOperator(std::unique_ptr child, @@ -311,7 +321,7 @@ bool ProjectOperator::next(Tuple& out_tuple) { auto input_schema = child_->output_schema(); for (const auto& col : columns_) { /* Evaluate projection expression with input tuple context */ - common::Value v = col->evaluate(&input, &input_schema); + common::Value v = col->evaluate(&input, &input_schema, get_params()); output_values.push_back(std::move(v)); } out_tuple = Tuple(std::move(output_values)); @@ -331,6 +341,17 @@ void ProjectOperator::add_child(std::unique_ptr child) { child_ = std::move(child); } +/* Override propagation for ProjectOperator */ +void ProjectOperator::set_memory_resource(std::pmr::memory_resource* mr) { + Operator::set_memory_resource(mr); + if (child_) child_->set_memory_resource(mr); +} + +void ProjectOperator::set_params(const std::vector* params) { + Operator::set_params(params); + if (child_) child_->set_params(params); +} + /* --- SortOperator --- */ SortOperator::SortOperator(std::unique_ptr child, @@ -364,8 +385,8 @@ bool SortOperator::open() { std::stable_sort(sorted_tuples_.begin(), sorted_tuples_.end(), [this](const Tuple& a, const Tuple& b) { for (size_t i = 0; i < sort_keys_.size(); ++i) { - const common::Value val_a = sort_keys_[i]->evaluate(&a, &schema_); - const common::Value val_b = sort_keys_[i]->evaluate(&b, &schema_); + const common::Value val_a = sort_keys_[i]->evaluate(&a, &schema_, get_params()); + const common::Value val_b = sort_keys_[i]->evaluate(&b, &schema_, get_params()); const bool asc = ascending_[i]; if (val_a < val_b) { return asc; @@ -401,6 +422,17 @@ Schema& SortOperator::output_schema() { return schema_; } +/* Override propagation for SortOperator */ +void SortOperator::set_memory_resource(std::pmr::memory_resource* mr) { + Operator::set_memory_resource(mr); + if (child_) child_->set_memory_resource(mr); +} + +void SortOperator::set_params(const std::vector* params) { + Operator::set_params(params); + if (child_) child_->set_params(params); +} + /* --- AggregateOperator --- */ AggregateOperator::AggregateOperator(std::unique_ptr child, @@ -470,7 +502,7 @@ bool AggregateOperator::open() { if (!is_global) { key = ""; for (const auto& gb : group_by_) { - auto val = gb ? gb->evaluate(&tuple, &child_schema) : common::Value::make_null(); + auto val = gb ? gb->evaluate(&tuple, &child_schema, get_params()) : common::Value::make_null(); key += val.to_string() + "|"; gb_vals.push_back(std::move(val)); } @@ -486,7 +518,7 @@ bool AggregateOperator::open() { for (size_t i = 0; i < aggregates_.size(); ++i) { common::Value val; if (aggregates_[i].expr) { - val = aggregates_[i].expr->evaluate(&tuple, &child_schema); + val = aggregates_[i].expr->evaluate(&tuple, &child_schema, get_params()); } else { val = common::Value::make_int64(static_cast(1)); } @@ -578,6 +610,17 @@ Schema& AggregateOperator::output_schema() { return schema_; } +/* Override propagation for AggregateOperator */ +void AggregateOperator::set_memory_resource(std::pmr::memory_resource* mr) { + Operator::set_memory_resource(mr); + if (child_) child_->set_memory_resource(mr); +} + +void AggregateOperator::set_params(const std::vector* params) { + Operator::set_params(params); + if (child_) child_->set_params(params); +} + /* --- HashJoinOperator --- */ HashJoinOperator::HashJoinOperator(std::unique_ptr left, std::unique_ptr right, @@ -623,7 +666,7 @@ bool HashJoinOperator::open() { Tuple right_tuple; auto right_schema = right_->output_schema(); while (right_->next(right_tuple)) { - const common::Value key = right_key_->evaluate(&right_tuple, &right_schema); + const common::Value key = right_key_->evaluate(&right_tuple, &right_schema, get_params()); hash_table_.emplace(key.to_string(), BuildTuple{std::move(right_tuple), false}); } @@ -681,7 +724,7 @@ bool HashJoinOperator::next(Tuple& out_tuple) { if (left_->next(next_left)) { left_tuple_ = std::move(next_left); left_had_match_ = false; - const common::Value key = left_key_->evaluate(&(left_tuple_.value()), &left_schema); + const common::Value key = left_key_->evaluate(&(left_tuple_.value()), &left_schema, get_params()); /* Look up in hash table */ auto range = hash_table_.equal_range(key.to_string()); @@ -755,6 +798,19 @@ void HashJoinOperator::add_child(std::unique_ptr child) { } } +/* Override propagation for HashJoinOperator */ +void HashJoinOperator::set_memory_resource(std::pmr::memory_resource* mr) { + Operator::set_memory_resource(mr); + if (left_) left_->set_memory_resource(mr); + if (right_) right_->set_memory_resource(mr); +} + +void HashJoinOperator::set_params(const std::vector* params) { + Operator::set_params(params); + if (left_) left_->set_params(params); + if (right_) right_->set_params(params); +} + /* --- LimitOperator --- */ LimitOperator::LimitOperator(std::unique_ptr child, int64_t limit, int64_t offset) @@ -814,4 +870,15 @@ void LimitOperator::add_child(std::unique_ptr child) { child_ = std::move(child); } +/* Override propagation for LimitOperator */ +void LimitOperator::set_memory_resource(std::pmr::memory_resource* mr) { + Operator::set_memory_resource(mr); + if (child_) child_->set_memory_resource(mr); +} + +void LimitOperator::set_params(const std::vector* params) { + Operator::set_params(params); + if (child_) child_->set_params(params); +} + } // namespace cloudsql::executor diff --git a/src/executor/query_executor.cpp b/src/executor/query_executor.cpp index a3a9ca3..fd3549e 100644 --- a/src/executor/query_executor.cpp +++ b/src/executor/query_executor.cpp @@ -200,12 +200,14 @@ QueryResult QueryExecutor::execute(const PreparedStatement& prepared, // Index updates using cached index objects std::string err; - for (size_t i = 0; i < prepared.indexes.size(); ++i) { - const auto& idx_info = prepared.table_meta->indexes[i]; - uint16_t pos = idx_info.column_positions[0]; - if (!apply_index_write(*prepared.indexes[i], tuple.get(pos), tid, - IndexOp::Insert, err)) { - throw std::runtime_error(err); + size_t cached_idx_ptr = 0; + for (const auto& idx_info : prepared.table_meta->indexes) { + if (!idx_info.column_positions.empty()) { + uint16_t pos = idx_info.column_positions[0]; + if (!apply_index_write(*prepared.indexes[cached_idx_ptr++], tuple.get(pos), tid, + IndexOp::Insert, err)) { + throw std::runtime_error(err); + } } } @@ -388,6 +390,8 @@ QueryResult QueryExecutor::execute_select(const parser::SelectStatement& stmt, } /* Initialize and open operators */ + root->set_memory_resource(&arena_); + root->set_params(current_params_); if (!root->init() || !root->open()) { result.set_error(root->error().empty() ? "Failed to open execution plan" : root->error()); return result; @@ -399,7 +403,8 @@ QueryResult QueryExecutor::execute_select(const parser::SelectStatement& stmt, /* Pull tuples (Volcano model) */ Tuple tuple; while (root->next(tuple)) { - result.add_row(std::move(tuple)); + // MUST deep-copy tuple to default allocator (heap) so it outlives the arena reset + result.add_row(Tuple(tuple.values(), nullptr)); } root->close(); diff --git a/src/storage/heap_table.cpp b/src/storage/heap_table.cpp index 7abfcb2..4654989 100644 --- a/src/storage/heap_table.cpp +++ b/src/storage/heap_table.cpp @@ -41,7 +41,6 @@ HeapTable::HeapTable(std::string table_name, BufferPoolManager& bpm, executor::S HeapTable::~HeapTable() { // Note: In some tests, the BufferPoolManager might be destroyed before the HeapTable // causing this to potentially access a dangling reference if we are not careful. - // However, the current issue is likely that cached_page_ needs to be unpinned properly. if (cached_page_ != nullptr) { try { bpm_.unpin_page(filename_, cached_page_id_, true); @@ -55,7 +54,11 @@ HeapTable::~HeapTable() { /* --- Iterator Implementation --- */ HeapTable::Iterator::Iterator(HeapTable& table, std::pmr::memory_resource* mr) - : table_(table), next_id_(0, 0), last_id_(0, 0), mr_(mr) {} + : table_(table), + next_id_(0, 0), + last_id_(0, 0), + eof_(false), + mr_(mr ? mr : std::pmr::new_delete_resource()) {} bool HeapTable::Iterator::next(executor::Tuple& out_tuple) { TupleMeta meta; @@ -103,24 +106,29 @@ bool HeapTable::Iterator::next_meta(TupleMeta& out_meta) { if (offset != 0) { /* Found a record: Deserialize it in-place from the pinned buffer */ const uint8_t* const data = reinterpret_cast(buffer + offset); - const size_t data_len = Page::PAGE_SIZE - offset; - - if (data_len < 16) { + + // Read Tuple Length (first 2 bytes) + uint16_t tuple_data_len; + std::memcpy(&tuple_data_len, data, 2); + + const size_t record_len = static_cast(tuple_data_len); + if (record_len < 18) { // 2 len + 8 xmin + 8 xmax table_.bpm_.unpin_page(table_.filename_, next_id_.page_num, false); return false; } // Read MVCC Header - std::memcpy(&out_meta.xmin, data, 8); - std::memcpy(&out_meta.xmax, data + 8, 8); + std::memcpy(&out_meta.xmin, data + 2, 8); + std::memcpy(&out_meta.xmax, data + 10, 8); - size_t cursor = 16; - // Zero-allocation vector construction via Arena (mr_) + size_t cursor = 18; std::pmr::vector values(mr_); + + std::cerr << "DEBUG: Iterator::next_meta values.reserve(" << table_.schema_.column_count() << ") iter=" << this << " table=" << &table_ << " mr=" << mr_ << std::endl; values.reserve(table_.schema_.column_count()); for (size_t i = 0; i < table_.schema_.column_count(); ++i) { - if (cursor >= data_len) break; + if (cursor >= record_len) break; auto type = static_cast(data[cursor++]); if (type == common::ValueType::TYPE_NULL) { values.push_back(common::Value::make_null()); @@ -134,7 +142,7 @@ bool HeapTable::Iterator::next_meta(TupleMeta& out_meta) { type == common::ValueType::TYPE_INT64 || type == common::ValueType::TYPE_FLOAT32 || type == common::ValueType::TYPE_FLOAT64) { - if (cursor + 8 > data_len) break; + if (cursor + 8 > record_len) break; if (type == common::ValueType::TYPE_FLOAT32 || type == common::ValueType::TYPE_FLOAT64) { @@ -151,11 +159,11 @@ bool HeapTable::Iterator::next_meta(TupleMeta& out_meta) { } cursor += 8; } else { - if (cursor + 4 > data_len) break; + if (cursor + 4 > record_len) break; uint32_t len; std::memcpy(&len, data + cursor, 4); cursor += 4; - if (cursor + len > data_len) break; + if (cursor + len > record_len) break; std::string s(reinterpret_cast(data + cursor), len); cursor += len; values.push_back(common::Value::make_text(s)); @@ -201,9 +209,11 @@ HeapTable::TupleId HeapTable::insert(const executor::Tuple& tuple, uint64_t xmin }; uint64_t xmax = 0; - payload_size = 16; - std::memcpy(payload_ptr, &xmin, 8); - std::memcpy(payload_ptr + 8, &xmax, 8); + payload_size = 18; // 2 len + 8 xmin + 8 xmax + // placeholder for length + std::memset(payload_ptr, 0, 2); + std::memcpy(payload_ptr + 2, &xmin, 8); + std::memcpy(payload_ptr + 10, &xmax, 8); for (const auto& val : tuple.values()) { ensure_capacity(1); @@ -221,6 +231,11 @@ HeapTable::TupleId HeapTable::insert(const executor::Tuple& tuple, uint64_t xmin std::memcpy(payload_ptr + payload_size, &v, 8); } payload_size += 8; + } else if (val.type() == common::ValueType::TYPE_BOOL) { + ensure_capacity(8); + int64_t v = val.as_bool() ? 1 : 0; + std::memcpy(payload_ptr + payload_size, &v, 8); + payload_size += 8; } else { const std::string& s = val.as_text(); uint32_t len = static_cast(s.size()); @@ -232,6 +247,7 @@ HeapTable::TupleId HeapTable::insert(const executor::Tuple& tuple, uint64_t xmin } const auto required = static_cast(payload_size); + std::memcpy(payload_ptr, &required, 2); // set final length while (true) { // Use cached page if available @@ -243,7 +259,9 @@ HeapTable::TupleId HeapTable::insert(const executor::Tuple& tuple, uint64_t xmin cached_page_ = bpm_.fetch_page(filename_, cached_page_id_); if (!cached_page_) { cached_page_ = bpm_.new_page(filename_, &cached_page_id_); - if (!cached_page_) return {0, 0}; + if (!cached_page_) { + return {0, 0}; // Buffer pool full or allocation failed + } last_page_id_ = cached_page_id_; } } @@ -301,7 +319,7 @@ bool HeapTable::remove(const TupleId& tuple_id, uint64_t xmax) { std::memcpy(&offset, buffer + sizeof(PageHeader) + (tuple_id.slot_num * sizeof(uint16_t)), sizeof(uint16_t)); if (offset != 0) { - std::memcpy(buffer + offset + 8, &xmax, 8); + std::memcpy(buffer + offset + 10, &xmax, 8); return true; } return false; @@ -326,8 +344,8 @@ bool HeapTable::remove(const TupleId& tuple_id, uint64_t xmax) { return false; } - /* In binary format, xmax is at offset + 8 */ - std::memcpy(buffer + offset + 8, &xmax, 8); + /* In binary format, xmax is at offset + 10 (2 len + 8 xmin) */ + std::memcpy(buffer + offset + 10, &xmax, 8); bpm_.unpin_page(filename_, tuple_id.page_num, true); return true; @@ -388,18 +406,21 @@ bool HeapTable::get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const { if (offset == 0) return false; const uint8_t* const data = reinterpret_cast(buffer + offset); - const size_t data_len = Page::PAGE_SIZE - offset; - if (data_len < 16) return false; + + uint16_t tuple_data_len; + std::memcpy(&tuple_data_len, data, 2); + const size_t record_len = static_cast(tuple_data_len); + if (record_len < 18) return false; - std::memcpy(&out_meta.xmin, data, 8); - std::memcpy(&out_meta.xmax, data + 8, 8); + std::memcpy(&out_meta.xmin, data + 2, 8); + std::memcpy(&out_meta.xmax, data + 10, 8); - size_t cursor = 16; + size_t cursor = 18; std::vector values; values.reserve(schema_.column_count()); for (size_t i = 0; i < schema_.column_count(); ++i) { - if (cursor >= data_len) break; + if (cursor >= record_len) break; auto type = static_cast(data[cursor++]); if (type == common::ValueType::TYPE_NULL) { values.push_back(common::Value::make_null()); @@ -410,7 +431,7 @@ bool HeapTable::get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const { type == common::ValueType::TYPE_INT16 || type == common::ValueType::TYPE_INT32 || type == common::ValueType::TYPE_INT64 || type == common::ValueType::TYPE_FLOAT32 || type == common::ValueType::TYPE_FLOAT64) { - if (cursor + 8 > data_len) break; + if (cursor + 8 > record_len) break; if (type == common::ValueType::TYPE_FLOAT32 || type == common::ValueType::TYPE_FLOAT64) { double v; @@ -426,11 +447,11 @@ bool HeapTable::get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const { } cursor += 8; } else { - if (cursor + 4 > data_len) break; + if (cursor + 4 > record_len) break; uint32_t len; std::memcpy(&len, data + cursor, 4); cursor += 4; - if (cursor + len > data_len) break; + if (cursor + len > record_len) break; std::string s(reinterpret_cast(data + cursor), len); cursor += len; values.push_back(common::Value::make_text(s)); @@ -460,23 +481,25 @@ bool HeapTable::get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const { } const uint8_t* const data = reinterpret_cast(buffer + offset); - const size_t data_len = Page::PAGE_SIZE - offset; - - if (data_len < 16) { + + uint16_t tuple_data_len; + std::memcpy(&tuple_data_len, data, 2); + const size_t record_len = static_cast(tuple_data_len); + if (record_len < 18) { bpm_.unpin_page(filename_, tuple_id.page_num, false); return false; } // Read MVCC Header - std::memcpy(&out_meta.xmin, data, 8); - std::memcpy(&out_meta.xmax, data + 8, 8); + std::memcpy(&out_meta.xmin, data + 2, 8); + std::memcpy(&out_meta.xmax, data + 10, 8); - size_t cursor = 16; + size_t cursor = 18; std::vector values; values.reserve(schema_.column_count()); for (size_t i = 0; i < schema_.column_count(); ++i) { - if (cursor >= data_len) break; + if (cursor >= record_len) break; auto type = static_cast(data[cursor++]); if (type == common::ValueType::TYPE_NULL) { values.push_back(common::Value::make_null()); @@ -487,7 +510,7 @@ bool HeapTable::get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const { type == common::ValueType::TYPE_INT16 || type == common::ValueType::TYPE_INT32 || type == common::ValueType::TYPE_INT64 || type == common::ValueType::TYPE_FLOAT32 || type == common::ValueType::TYPE_FLOAT64) { - if (cursor + 8 > data_len) break; + if (cursor + 8 > record_len) break; if (type == common::ValueType::TYPE_FLOAT32 || type == common::ValueType::TYPE_FLOAT64) { @@ -504,11 +527,11 @@ bool HeapTable::get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const { } cursor += 8; } else { - if (cursor + 4 > data_len) break; + if (cursor + 4 > record_len) break; uint32_t len; std::memcpy(&len, data + cursor, 4); cursor += 4; - if (cursor + len > data_len) break; + if (cursor + len > record_len) break; std::string s(reinterpret_cast(data + cursor), len); cursor += len; values.push_back(common::Value::make_text(s)); @@ -550,7 +573,7 @@ uint64_t HeapTable::tuple_count() const { sizeof(uint16_t)); if (offset != 0) { uint64_t xmax = 0; - std::memcpy(&xmax, buffer + offset + 8, 8); + std::memcpy(&xmax, buffer + offset + 10, 8); // 2 len + 8 xmin if (xmax == 0) count++; } } diff --git a/test_data/idx_id.idx b/test_data/idx_id.idx deleted file mode 100644 index e69de29..0000000 From 0dc042bf2eeb0f92c79a5400ed85df608868ee3e Mon Sep 17 00:00:00 2001 From: poyrazK <83272398+poyrazK@users.noreply.github.com> Date: Thu, 9 Apr 2026 13:58:41 +0000 Subject: [PATCH 20/21] style: automated clang-format fixes --- include/executor/types.hpp | 11 +++++----- src/executor/operator.cpp | 36 +++++++++++++++++---------------- src/executor/query_executor.cpp | 4 ++-- src/storage/heap_table.cpp | 24 ++++++++++++---------- 4 files changed, 40 insertions(+), 35 deletions(-) diff --git a/include/executor/types.hpp b/include/executor/types.hpp index 6f7e30b..416e1d0 100644 --- a/include/executor/types.hpp +++ b/include/executor/types.hpp @@ -11,12 +11,12 @@ #define CLOUDSQL_EXECUTOR_TYPES_HPP #include +#include #include #include #include #include #include -#include #include "common/value.hpp" @@ -131,21 +131,22 @@ class Tuple { public: Tuple() = default; - + // Explicit PMR vector constructor explicit Tuple(std::pmr::vector values) : values_(std::move(values)) {} - + // Initializer list constructor Tuple(std::initializer_list list) : values_(list) {} // Support allocation from a custom memory resource explicit Tuple(std::pmr::memory_resource* mr) : values_(mr ? mr : std::pmr::get_default_resource()) {} - + // Support construction from standard vector or PMR vector with specific resource template , Tuple>>, - typename std::enable_if_t, std::pmr::memory_resource*>>* = nullptr> + typename std::enable_if_t< + !std::is_same_v, std::pmr::memory_resource*>>* = nullptr> Tuple(const VectorType& values, std::pmr::memory_resource* mr = nullptr) : values_(values.begin(), values.end(), mr ? mr : std::pmr::get_default_resource()) {} diff --git a/src/executor/operator.cpp b/src/executor/operator.cpp index 9e751a2..2f67b09 100644 --- a/src/executor/operator.cpp +++ b/src/executor/operator.cpp @@ -382,21 +382,21 @@ bool SortOperator::open() { } /* Perform sort using child schema for evaluation */ - std::stable_sort(sorted_tuples_.begin(), sorted_tuples_.end(), - [this](const Tuple& a, const Tuple& b) { - for (size_t i = 0; i < sort_keys_.size(); ++i) { - const common::Value val_a = sort_keys_[i]->evaluate(&a, &schema_, get_params()); - const common::Value val_b = sort_keys_[i]->evaluate(&b, &schema_, get_params()); - const bool asc = ascending_[i]; - if (val_a < val_b) { - return asc; - } - if (val_b < val_a) { - return !asc; - } - } - return false; - }); + std::stable_sort( + sorted_tuples_.begin(), sorted_tuples_.end(), [this](const Tuple& a, const Tuple& b) { + for (size_t i = 0; i < sort_keys_.size(); ++i) { + const common::Value val_a = sort_keys_[i]->evaluate(&a, &schema_, get_params()); + const common::Value val_b = sort_keys_[i]->evaluate(&b, &schema_, get_params()); + const bool asc = ascending_[i]; + if (val_a < val_b) { + return asc; + } + if (val_b < val_a) { + return !asc; + } + } + return false; + }); current_index_ = 0; set_state(ExecState::Open); @@ -502,7 +502,8 @@ bool AggregateOperator::open() { if (!is_global) { key = ""; for (const auto& gb : group_by_) { - auto val = gb ? gb->evaluate(&tuple, &child_schema, get_params()) : common::Value::make_null(); + auto val = gb ? gb->evaluate(&tuple, &child_schema, get_params()) + : common::Value::make_null(); key += val.to_string() + "|"; gb_vals.push_back(std::move(val)); } @@ -724,7 +725,8 @@ bool HashJoinOperator::next(Tuple& out_tuple) { if (left_->next(next_left)) { left_tuple_ = std::move(next_left); left_had_match_ = false; - const common::Value key = left_key_->evaluate(&(left_tuple_.value()), &left_schema, get_params()); + const common::Value key = + left_key_->evaluate(&(left_tuple_.value()), &left_schema, get_params()); /* Look up in hash table */ auto range = hash_table_.equal_range(key.to_string()); diff --git a/src/executor/query_executor.cpp b/src/executor/query_executor.cpp index fd3549e..af17fb3 100644 --- a/src/executor/query_executor.cpp +++ b/src/executor/query_executor.cpp @@ -204,8 +204,8 @@ QueryResult QueryExecutor::execute(const PreparedStatement& prepared, for (const auto& idx_info : prepared.table_meta->indexes) { if (!idx_info.column_positions.empty()) { uint16_t pos = idx_info.column_positions[0]; - if (!apply_index_write(*prepared.indexes[cached_idx_ptr++], tuple.get(pos), tid, - IndexOp::Insert, err)) { + if (!apply_index_write(*prepared.indexes[cached_idx_ptr++], tuple.get(pos), + tid, IndexOp::Insert, err)) { throw std::runtime_error(err); } } diff --git a/src/storage/heap_table.cpp b/src/storage/heap_table.cpp index 4654989..5f69733 100644 --- a/src/storage/heap_table.cpp +++ b/src/storage/heap_table.cpp @@ -106,13 +106,13 @@ bool HeapTable::Iterator::next_meta(TupleMeta& out_meta) { if (offset != 0) { /* Found a record: Deserialize it in-place from the pinned buffer */ const uint8_t* const data = reinterpret_cast(buffer + offset); - + // Read Tuple Length (first 2 bytes) uint16_t tuple_data_len; std::memcpy(&tuple_data_len, data, 2); - + const size_t record_len = static_cast(tuple_data_len); - if (record_len < 18) { // 2 len + 8 xmin + 8 xmax + if (record_len < 18) { // 2 len + 8 xmin + 8 xmax table_.bpm_.unpin_page(table_.filename_, next_id_.page_num, false); return false; } @@ -123,8 +123,10 @@ bool HeapTable::Iterator::next_meta(TupleMeta& out_meta) { size_t cursor = 18; std::pmr::vector values(mr_); - - std::cerr << "DEBUG: Iterator::next_meta values.reserve(" << table_.schema_.column_count() << ") iter=" << this << " table=" << &table_ << " mr=" << mr_ << std::endl; + + std::cerr << "DEBUG: Iterator::next_meta values.reserve(" + << table_.schema_.column_count() << ") iter=" << this + << " table=" << &table_ << " mr=" << mr_ << std::endl; values.reserve(table_.schema_.column_count()); for (size_t i = 0; i < table_.schema_.column_count(); ++i) { @@ -209,7 +211,7 @@ HeapTable::TupleId HeapTable::insert(const executor::Tuple& tuple, uint64_t xmin }; uint64_t xmax = 0; - payload_size = 18; // 2 len + 8 xmin + 8 xmax + payload_size = 18; // 2 len + 8 xmin + 8 xmax // placeholder for length std::memset(payload_ptr, 0, 2); std::memcpy(payload_ptr + 2, &xmin, 8); @@ -247,7 +249,7 @@ HeapTable::TupleId HeapTable::insert(const executor::Tuple& tuple, uint64_t xmin } const auto required = static_cast(payload_size); - std::memcpy(payload_ptr, &required, 2); // set final length + std::memcpy(payload_ptr, &required, 2); // set final length while (true) { // Use cached page if available @@ -260,7 +262,7 @@ HeapTable::TupleId HeapTable::insert(const executor::Tuple& tuple, uint64_t xmin if (!cached_page_) { cached_page_ = bpm_.new_page(filename_, &cached_page_id_); if (!cached_page_) { - return {0, 0}; // Buffer pool full or allocation failed + return {0, 0}; // Buffer pool full or allocation failed } last_page_id_ = cached_page_id_; } @@ -406,7 +408,7 @@ bool HeapTable::get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const { if (offset == 0) return false; const uint8_t* const data = reinterpret_cast(buffer + offset); - + uint16_t tuple_data_len; std::memcpy(&tuple_data_len, data, 2); const size_t record_len = static_cast(tuple_data_len); @@ -481,7 +483,7 @@ bool HeapTable::get_meta(const TupleId& tuple_id, TupleMeta& out_meta) const { } const uint8_t* const data = reinterpret_cast(buffer + offset); - + uint16_t tuple_data_len; std::memcpy(&tuple_data_len, data, 2); const size_t record_len = static_cast(tuple_data_len); @@ -573,7 +575,7 @@ uint64_t HeapTable::tuple_count() const { sizeof(uint16_t)); if (offset != 0) { uint64_t xmax = 0; - std::memcpy(&xmax, buffer + offset + 10, 8); // 2 len + 8 xmin + std::memcpy(&xmax, buffer + offset + 10, 8); // 2 len + 8 xmin if (xmax == 0) count++; } } From e9a845e01faf604b9b36c27b5e72c9f4376d02a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Thu, 9 Apr 2026 21:45:29 +0300 Subject: [PATCH 21/21] chore: cleanup debug artifacts and accidental files --- profile.txt | 647 ------------------------------------- src/storage/heap_table.cpp | 4 - 2 files changed, 651 deletions(-) delete mode 100644 profile.txt diff --git a/profile.txt b/profile.txt deleted file mode 100644 index 4fca312..0000000 --- a/profile.txt +++ /dev/null @@ -1,647 +0,0 @@ -Analysis of sampling storage_bench (pid 12352) every 1 millisecond -Process: storage_bench [12352] -Path: /Users/USER/*/storage_bench -Load Address: 0x1000f0000 -Identifier: storage_bench -Version: 0 -Code Type: ARM64 -Platform: macOS -Parent Process: bash [12350] -Target Type: live task - -Date/Time: 2026-04-04 13:01:29.909 +0300 -Launch Time: 2026-04-04 13:01:27.804 +0300 -OS Version: macOS 26.4 (25E246) -Report Version: 7 -Analysis Tool: /usr/bin/sample - -Physical footprint: 5776K -Physical footprint (peak): 5776K -Idle exit: untracked ----- - -Call graph: - 8282 Thread_8258606 DispatchQueue_1: com.apple.main-thread (serial) - 8282 start (in dyld) + 6992 [0x182d53da4] - 8282 main (in storage_bench) + 136 [0x1000f1d88] storage_bench.cpp:79 - 8282 benchmark::RunSpecifiedBenchmarks() (in storage_bench) + 92 [0x1000faaf4] benchmark.cc:535 - 8282 benchmark::RunSpecifiedBenchmarks(benchmark::BenchmarkReporter*, benchmark::BenchmarkReporter*, std::basic_string) (in storage_bench) + 2456 [0x1000fb4d4] benchmark.cc:611 - 8282 benchmark::internal::BenchmarkRunner::DoOneRepetition() (in storage_bench) + 144 [0x100110d64] benchmark_runner.cc:424 - 8282 benchmark::internal::BenchmarkRunner::DoNIterations() (in storage_bench) + 660 [0x100110290] benchmark_runner.cc:273 - 8282 benchmark::internal::(anonymous namespace)::RunInThread(benchmark::internal::BenchmarkInstance const*, long long, int, benchmark::internal::ThreadManager*, benchmark::internal::PerfCountersMeasurement*) (in storage_bench) + 72 [0x100110660] benchmark_runner.cc:132 - 8282 benchmark::internal::BenchmarkInstance::Run(long long, int, benchmark::internal::ThreadTimer*, benchmark::internal::ThreadManager*, benchmark::internal::PerfCountersMeasurement*) const (in storage_bench) + 172 [0x1001009ac] benchmark_api_internal.cc:98 - 8282 BM_HeapTableInsert(benchmark::State&) (in storage_bench) + 1076 [0x1000f18a8] storage_bench.cpp:71 - 1859 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 180 [0x1000f7b7c] heap_table.cpp:113 - + 789 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 176 [0x1000f5748] buffer_pool_manager.cpp:109 - + ! 334 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 300 [0x1000f68b0] lru_replacer.cpp:51 - + ! : 267 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 208 [0x1000f6ad8] __hash_table:1547 - + ! : | 239 operator new(unsigned long) (in libc++abi.dylib) + 52 [0x1830c67e8] - + ! : | + 106 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 420,88,... [0x182f32078,0x182f31f2c,...] - + ! : | + 63 (in libsystem_malloc.dylib) + 112,212,... [0x182f2c144,0x182f2c1a8,...] - + ! : | + 45 _xzm_xzone_malloc (in libsystem_malloc.dylib) + 8,180,... [0x182f2c8c8,0x182f2c974,...] - + ! : | + 23 malloc_type_malloc (in libsystem_malloc.dylib) + 28,72,... [0x182f20000,0x182f2002c,...] - + ! : | + 1 DYLD-STUB$$malloc_type_malloc (in libc++abi.dylib) + 8 [0x1830c6c18] - + ! : | + 1 _xzm_xzone_malloc_freelist_outlined (in libsystem_malloc.dylib) + 324 [0x182f3377c] - + ! : | + 1 _xzm_xzone_find_and_malloc_from_freelist_chunk (in libsystem_malloc.dylib) + 336 [0x182f34064] - + ! : | + 1 _xzm_xzone_malloc_from_freelist_chunk (in libsystem_malloc.dylib) + 556 [0x182f33d44] - + ! : | 14 DYLD-STUB$$operator new(unsigned long) (in storage_bench) + 4,0 [0x10011f274,0x10011f270] - + ! : | 14 operator new(unsigned long) (in libc++abi.dylib) + 36 [0x1830c67d8] - + ! : 13 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 32 [0x1000f6a28] __hash_table:1530 - + ! : 10 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 600 [0x1000f6c60] __hash_table:1563 - + ! : 9 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 80,88 [0x1000f6a58,0x1000f6a60] __hash_table:1535 - + ! : 9 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 552,548 [0x1000f6c30,0x1000f6c2c] __hash_table:1555 - + ! : 7 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 0 [0x1000f6a08] __hash_table:1528 - + ! : 5 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 244 [0x1000f6afc] __hash_table:1548 - + ! : 4 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 100,104 [0x1000f6a6c,0x1000f6a70] __hash_table:1536 - + ! : 3 operator new(unsigned long) (in libc++abi.dylib) + 76 [0x1830c6800] - + ! : 3 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 592 [0x1000f6c58] __hash_table:1562 - + ! : 2 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 200 [0x1000f6ad0] __hash_table:1547 - + ! : 1 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 28 [0x1000f6a24] __hash_table:1529 - + ! : 1 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 588 [0x1000f6c54] __hash_table:1561 - + ! 230 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 232 [0x1000f686c] lru_replacer.cpp:50 - + ! : 215 operator new(unsigned long) (in libc++abi.dylib) + 52 [0x1830c67e8] - + ! : | 95 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 420,88,... [0x182f32078,0x182f31f2c,...] - + ! : | 42 _xzm_xzone_malloc (in libsystem_malloc.dylib) + 8,180,... [0x182f2c8c8,0x182f2c974,...] - + ! : | 39 (in libsystem_malloc.dylib) + 112,220,... [0x182f2c144,0x182f2c1b0,...] - + ! : | 24 malloc_type_malloc (in libsystem_malloc.dylib) + 72,28,... [0x182f2002c,0x182f20000,...] - + ! : | 9 DYLD-STUB$$malloc_type_malloc (in libc++abi.dylib) + 8 [0x1830c6c18] - + ! : | 3 _xzm_xzone_malloc_freelist_outlined (in libsystem_malloc.dylib) + 324 [0x182f3377c] - + ! : | + 2 _xzm_xzone_find_and_malloc_from_freelist_chunk (in libsystem_malloc.dylib) + 116,620 [0x182f33f88,0x182f34180] - + ! : | + 1 _xzm_xzone_find_and_malloc_from_freelist_chunk (in libsystem_malloc.dylib) + 620 [0x182f34180] - + ! : | + 1 _xzm_xzone_malloc_from_empty_freelist_chunk (in libsystem_malloc.dylib) + 280 [0x182f34a80] - + ! : | 1 _xzm_xzone_malloc_freelist_outlined (in libsystem_malloc.dylib) + 248 [0x182f33730] - + ! : | + 1 _xzm_xzone_malloc_from_freelist_chunk (in libsystem_malloc.dylib) + 104 [0x182f33b80] - + ! : | 1 _xzm_xzone_malloc_freelist_outlined (in libsystem_malloc.dylib) + 28 [0x182f33654] - + ! : | 1 xzm_malloc_zone_malloc_type_malloc (in libsystem_malloc.dylib) + 0 [0x182f3811c] - + ! : 9 operator new(unsigned long) (in libc++abi.dylib) + 32,36,... [0x1830c67d4,0x1830c67d8,...] - + ! : 6 DYLD-STUB$$operator new(unsigned long) (in storage_bench) + 4 [0x10011f274] - + ! 120 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 40 [0x1000f67ac] lru_replacer.cpp:40 - + ! : 101 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] - + ! : | 88 pthread_mutex_lock (in libsystem_pthread.dylib) + 132,112,... [0x18310a480,0x18310a46c,...] - + ! : | 13 DYLD-STUB$$pthread_mutex_lock (in libc++.1.dylib) + 8 [0x183084900] - + ! : 12 std::mutex::lock() (in libc++.1.dylib) + 20,0,... [0x183022014,0x183022000,...] - + ! : 5 DYLD-STUB$$std::mutex::lock() (in storage_bench) + 4 [0x10011f130] - + ! : 2 pthread_mutex_lock (in libsystem_pthread.dylib) + 136 [0x18310a484] - + ! 46 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 312 [0x1000f68bc] lru_replacer.cpp:52 - + ! : 32 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] - + ! : | 26 pthread_mutex_unlock (in libsystem_pthread.dylib) + 104,12,... [0x18310a9ac,0x18310a950,...] - + ! : | 6 DYLD-STUB$$pthread_mutex_unlock (in libc++.1.dylib) + 8,0 [0x183084920,0x183084918] - + ! : 7 DYLD-STUB$$std::mutex::unlock() (in storage_bench) + 4,8 [0x10011f13c,0x10011f140] - + ! : 7 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] - + ! 25 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 64,100,... [0x1000f67c4,0x1000f67e8,...] lru_replacer.cpp:42 - + ! 18 std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) + 684,680 [0x1000f6cb4,0x1000f6cb0] __hash_table:1575 - + ! 7 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 28,12 [0x1000f67a0,0x1000f6790] lru_replacer.cpp:39 - + ! 6 operator new(unsigned long) (in libc++abi.dylib) + 76 [0x1830c6800] - + ! 2 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 224 [0x1000f6864] lru_replacer.cpp:50 - + ! 1 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 300 [0x1000f68b0] lru_replacer.cpp:51 - + 375 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 60 [0x1000f56d4] buffer_pool_manager.cpp:91 - + ! 162 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 196 [0x1000f55c8] buffer_pool_manager.hpp:109 - + ! : 75 std::to_string(unsigned int) (in libc++.1.dylib) + 76 [0x183025a9c] - + ! : | 43 (in libc++.1.dylib) + 152 [0x18303a760] - + ! : | + 40 _platform_memmove (in libsystem_platform.dylib) + 452,428,... [0x183119584,0x18311956c,...] - + ! : | + 3 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] - + ! : | 32 (in libc++.1.dylib) + 16,128,... [0x18303a6d8,0x18303a748,...] - + ! : 58 std::to_string(unsigned int) (in libc++.1.dylib) + 56 [0x183025a88] - + ! : | 58 std::__itoa::__base_10_u32[abi:nqe210106](char*, unsigned int) (in libc++.1.dylib) + 0,936,... [0x183033a80,0x183033e28,...] - + ! : 14 DYLD-STUB$$std::to_string(unsigned int) (in storage_bench) + 4 [0x10011f214] - + ! : 13 (in libc++.1.dylib) + 168 [0x18303a770] - + ! : 2 std::to_string(unsigned int) (in libc++.1.dylib) + 12,56 [0x183025a5c,0x183025a88] - + ! 84 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 228 [0x1000f55e8] buffer_pool_manager.hpp:109 - + ! : 44 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] - + ! : | 31 _platform_memmove (in libsystem_platform.dylib) + 452,428,... [0x183119584,0x18311956c,...] - + ! : | 13 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] - + ! : 32 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 32,148,... [0x183021ecc,0x183021f40,...] - + ! : 8 DYLD-STUB$$std::basic_string::append(char const*, unsigned long) (in storage_bench) + 4 [0x10011eecc] - + ! 72 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 172 [0x1000f55b0] buffer_pool_manager.hpp:109 - + ! : 66 _platform_memmove (in libsystem_platform.dylib) + 428,460,... [0x18311956c,0x18311958c,...] - + ! : 6 DYLD-STUB$$memmove (in storage_bench) + 4,0 [0x10011f40c,0x10011f408] - + ! 36 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 40,32,... [0x1000f552c,0x1000f5524,...] buffer_pool_manager.hpp:109 - + ! 14 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 192,188 [0x183021f6c,0x183021f68] - + ! 7 std::to_string(unsigned int) (in libc++.1.dylib) + 104 [0x183025ab8] - + 329 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 72 [0x1000f56e0] buffer_pool_manager.cpp:92 - + ! 155 ??? (in storage_bench) load address 0x1000f0000 + 0x3db0 [0x1000f3db0] - + ! 61 ??? (in storage_bench) load address 0x1000f0000 + 0x3cd8 [0x1000f3cd8] - + ! : 25 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 380,332,... [0x1000f3f70,0x1000f3f40,...] hash.h:91 - + ! : 22 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 0 [0x1000f3df4] hash.h:87 - + ! : 14 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 452 [0x1000f3fb8] hash.h:0 - + ! 38 ??? (in storage_bench) load address 0x1000f0000 + 0x3d70 [0x1000f3d70] - + ! 37 ??? (in storage_bench) load address 0x1000f0000 + 0x3da8 [0x1000f3da8] - + ! : 26 _platform_memcmp (in libsystem_platform.dylib) + 96,8,... [0x183116f90,0x183116f38,...] - + ! : 11 DYLD-STUB$$memcmp (in storage_bench) + 4 [0x10011f3f4] - + ! 8 ??? (in storage_bench) load address 0x1000f0000 + 0x3d64 [0x1000f3d64] - + ! 6 ??? (in storage_bench) load address 0x1000f0000 + 0x3cd8 [0x1000f3cd8] - + ! 5 ??? (in storage_bench) load address 0x1000f0000 + 0x3d28 [0x1000f3d28] - + ! 5 ??? (in storage_bench) load address 0x1000f0000 + 0x3d54 [0x1000f3d54] - + ! 5 ??? (in storage_bench) load address 0x1000f0000 + 0x3d88 [0x1000f3d88] - + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x3d08 [0x1000f3d08] - + ! 2 ??? (in storage_bench) load address 0x1000f0000 + 0x3d78 [0x1000f3d78] - + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3d90 [0x1000f3d90] - + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3da8 [0x1000f3da8] - + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3dac [0x1000f3dac] - + 150 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 112 [0x1000f5708] buffer_pool_manager.cpp:96 - + ! 66 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 76 [0x1000f61a8] __hash_table:1529 - + ! : 28 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 432,352,... [0x1000f3fa4,0x1000f3f54,...] hash.h:91 - + ! : 16 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 456 [0x1000f3fbc] hash.h:123 - + ! : 16 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 0 [0x1000f3df4] hash.h:87 - + ! : 6 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 444 [0x1000f3fb0] hash.h:0 - + ! 33 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 288 [0x1000f627c] __hash_table:1541 - + ! : 21 _platform_memcmp (in libsystem_platform.dylib) + 8,56,... [0x183116f38,0x183116f68,...] - + ! : 12 DYLD-STUB$$memcmp (in storage_bench) + 4,0 [0x10011f3f4,0x10011f3f0] - + ! 14 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 220,304,... [0x1000f6238,0x1000f628c,...] __hash_table:1539 - + ! 11 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 44,52,... [0x1000f6188,0x1000f6190,...] __hash_table:1529 - + ! 7 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 16,24 [0x1000f616c,0x1000f6174] __hash_table:1528 - + ! 6 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 100,140 [0x1000f61c0,0x1000f61e8] __hash_table:1535 - + ! 4 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 240,260 [0x1000f624c,0x1000f6260] __hash_table:1541 - + ! 3 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 160,212,... [0x1000f61fc,0x1000f6230,...] __hash_table:0 - + ! 3 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 152 [0x1000f61f4] __hash_table:1536 - + ! 2 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 204 [0x1000f6228] __hash_table:1538 - + ! 1 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 80 [0x1000f61ac] __hash_table:1530 - + 70 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 44 [0x1000f56c4] buffer_pool_manager.cpp:89 - + ! 57 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] - + ! : 43 pthread_mutex_lock (in libsystem_pthread.dylib) + 112,132,... [0x18310a46c,0x18310a480,...] - + ! : 14 DYLD-STUB$$pthread_mutex_lock (in libc++.1.dylib) + 8,0 [0x183084900,0x1830848f8] - + ! 7 DYLD-STUB$$std::mutex::lock() (in storage_bench) + 4 [0x10011f130] - + ! 6 std::mutex::lock() (in libc++.1.dylib) + 20 [0x183022014] - + 65 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 220 [0x1000f5774] buffer_pool_manager.cpp:113 - + ! 55 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] - + ! : 43 pthread_mutex_unlock (in libsystem_pthread.dylib) + 104,72,... [0x18310a9ac,0x18310a98c,...] - + ! : 12 DYLD-STUB$$pthread_mutex_unlock (in libc++.1.dylib) + 8 [0x183084920] - + ! 6 std::mutex::unlock() (in libc++.1.dylib) + 16,0 [0x183022038,0x183022028] - + ! 4 DYLD-STUB$$std::mutex::unlock() (in storage_bench) + 4 [0x10011f13c] - + 15 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 12,0 [0x1000f56a4,0x1000f5698] buffer_pool_manager.cpp:88 - + 13 ??? (in storage_bench) load address 0x1000f0000 + 0x3c94 [0x1000f3c94] - + 11 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 864,868,... [0x1000f64bc,0x1000f64c0,...] __hash_table:1575 - + 10 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 284 [0x1000f5620] buffer_pool_manager.hpp:109 - + 8 ??? (in storage_bench) load address 0x1000f0000 + 0x3de4 [0x1000f3de4] - + 8 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 128 [0x1000f5718] buffer_pool_manager.cpp:99 - + 5 ??? (in storage_bench) load address 0x1000f0000 + 0x3ca8 [0x1000f3ca8] - + 3 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 160 [0x1000f5738] buffer_pool_manager.cpp:107 - + 3 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 168 [0x1000f5740] buffer_pool_manager.cpp:109 - + 3 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 320 [0x1000f68c4] lru_replacer.cpp:52 - + 1 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 224 [0x1000f5778] buffer_pool_manager.cpp:113 - + 1 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 212 [0x1000f576c] buffer_pool_manager.cpp:89 - 1778 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 136 [0x1000f7b50] heap_table.cpp:113 - + 857 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 152 [0x1000f52f0] buffer_pool_manager.cpp:54 - + ! 293 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 272 [0x1000f6768] lru_replacer.cpp:35 - + ! : 136 _xzm_free (in libsystem_malloc.dylib) + 996,684,... [0x182f2d450,0x182f2d318,...] - + ! : 68 _free (in libsystem_malloc.dylib) + 36,76,... [0x182f3cc70,0x182f3cc98,...] - + ! : 36 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] - + ! : | 24 _platform_memset (in libsystem_platform.dylib) + 180,188,... [0x1831191a4,0x1831191ac,...] - + ! : | 9 DYLD-STUB$$_platform_bzero (in libsystem_malloc.dylib) + 8 [0x182f447f4] - + ! : | 3 __bzero (in libsystem_platform.dylib) + 0,4 [0x183119090,0x183119094] - + ! : 25 DYLD-STUB$$free (in libc++abi.dylib) + 8,12 [0x1830c6bd8,0x1830c6bdc] - + ! : 24 DYLD-STUB$$operator delete(void*) (in storage_bench) + 4,8 [0x10011f25c,0x10011f260] - + ! : 1 _xzm_chunk_list_push (in libsystem_malloc.dylib) + 156 [0x182f34878] - + ! : 1 _xzm_chunk_list_slot_push (in libsystem_malloc.dylib) + 128 [0x182f35990] - + ! : | 1 _xzm_chunk_list_push (in libsystem_malloc.dylib) + 12 [0x182f347e8] - + ! : 1 free (in libsystem_malloc.dylib) + 0 [0x182f036b8] - + ! : 1 xzm_malloc_zone_try_free_default (in libsystem_malloc.dylib) + 0 [0x182f38108] - + ! 280 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 240 [0x1000f6748] lru_replacer.cpp:34 - + ! : 154 _xzm_free (in libsystem_malloc.dylib) + 996,684,... [0x182f2d450,0x182f2d318,...] - + ! : 58 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] - + ! : | 50 _platform_memset (in libsystem_platform.dylib) + 180,208,... [0x1831191a4,0x1831191c0,...] - + ! : | 6 DYLD-STUB$$_platform_bzero (in libsystem_malloc.dylib) + 8 [0x182f447f4] - + ! : | 2 __bzero (in libsystem_platform.dylib) + 0 [0x183119090] - + ! : 42 _free (in libsystem_malloc.dylib) + 0,96,... [0x182f3cc4c,0x182f3ccac,...] - + ! : 13 DYLD-STUB$$free (in libc++abi.dylib) + 8,0 [0x1830c6bd8,0x1830c6bd0] - + ! : 13 DYLD-STUB$$operator delete(void*) (in storage_bench) + 4 [0x10011f25c] - + ! 85 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 36 [0x1000f667c] lru_replacer.cpp:30 - + ! : 57 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] - + ! : | 41 pthread_mutex_lock (in libsystem_pthread.dylib) + 112,64,... [0x18310a46c,0x18310a43c,...] - + ! : | 16 DYLD-STUB$$pthread_mutex_lock (in libc++.1.dylib) + 8 [0x183084900] - + ! : 15 DYLD-STUB$$std::mutex::lock() (in storage_bench) + 4,0 [0x10011f130,0x10011f12c] - + ! : 12 std::mutex::lock() (in libc++.1.dylib) + 20 [0x183022014] - + ! : 1 pthread_mutex_lock (in libsystem_pthread.dylib) + 136 [0x18310a484] - + ! 56 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 280 [0x1000f6770] lru_replacer.cpp:37 - + ! : 44 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] - + ! : | 31 pthread_mutex_unlock (in libsystem_pthread.dylib) + 104,12,... [0x18310a9ac,0x18310a950,...] - + ! : | 13 DYLD-STUB$$pthread_mutex_unlock (in libc++.1.dylib) + 8,0 [0x183084920,0x183084918] - + ! : 6 DYLD-STUB$$std::mutex::unlock() (in storage_bench) + 4 [0x10011f13c] - + ! : 6 std::mutex::unlock() (in libc++.1.dylib) + 16,0 [0x183022038,0x183022028] - + ! 35 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 108,60,... [0x1000f66c4,0x1000f6694,...] lru_replacer.cpp:32 - + ! 29 _xzm_free (in libsystem_malloc.dylib) + 1560,1548 [0x182f2d684,0x182f2d678] - + ! 15 ??? (in storage_bench) load address 0x1000f0000 + 0x48ac [0x1000f48ac] - + ! 8 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 260 [0x1000f675c] lru_replacer.cpp:35 - + ! 7 ??? (in storage_bench) load address 0x1000f0000 + 0x47cc [0x1000f47cc] - + ! 7 ??? (in storage_bench) load address 0x1000f0000 + 0x4844 [0x1000f4844] - + ! 6 ??? (in storage_bench) load address 0x1000f0000 + 0x47a4 [0x1000f47a4] - + ! 5 ??? (in storage_bench) load address 0x1000f0000 + 0x478c [0x1000f478c] - + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x47c0 [0x1000f47c0] - + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x4800 [0x1000f4800] - + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x47b4 [0x1000f47b4] - + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x47c8 [0x1000f47c8] - + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x47d8 [0x1000f47d8] - + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x47f0 [0x1000f47f0] - + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x4808 [0x1000f4808] - + ! 3 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 12 [0x1000f6664] lru_replacer.cpp:29 - + ! 2 ??? (in storage_bench) load address 0x1000f0000 + 0x47f8 [0x1000f47f8] - + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x48a8 [0x1000f48a8] - + ! 1 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 272 [0x1000f6768] lru_replacer.cpp:30 - + ! 1 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 280 [0x1000f6770] lru_replacer.cpp:37 - + 370 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 76 [0x1000f52a4] buffer_pool_manager.cpp:50 - + ! 213 ??? (in storage_bench) load address 0x1000f0000 + 0x3db0 [0x1000f3db0] - + ! 60 ??? (in storage_bench) load address 0x1000f0000 + 0x3cd8 [0x1000f3cd8] - + ! : 32 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 380,436,... [0x1000f3f70,0x1000f3fa8,...] hash.h:91 - + ! : 20 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 0 [0x1000f3df4] hash.h:87 - + ! : 8 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 452,288 [0x1000f3fb8,0x1000f3f14] hash.h:0 - + ! 42 ??? (in storage_bench) load address 0x1000f0000 + 0x3d70 [0x1000f3d70] - + ! 29 ??? (in storage_bench) load address 0x1000f0000 + 0x3da8 [0x1000f3da8] - + ! : 20 _platform_memcmp (in libsystem_platform.dylib) + 8,48,... [0x183116f38,0x183116f60,...] - + ! : 9 DYLD-STUB$$memcmp (in storage_bench) + 4 [0x10011f3f4] - + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x3cd8 [0x1000f3cd8] - + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x3d28 [0x1000f3d28] - + ! 4 ??? (in storage_bench) load address 0x1000f0000 + 0x3d64 [0x1000f3d64] - + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x3cc0 [0x1000f3cc0] - + ! 3 ??? (in storage_bench) load address 0x1000f0000 + 0x3d08 [0x1000f3d08] - + ! 2 ??? (in storage_bench) load address 0x1000f0000 + 0x3d88 [0x1000f3d88] - + ! 2 ??? (in storage_bench) load address 0x1000f0000 + 0x3dd4 [0x1000f3dd4] - + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3cf0 [0x1000f3cf0] - + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3d20 [0x1000f3d20] - + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3d54 [0x1000f3d54] - + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3da8 [0x1000f3da8] - + 269 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 64 [0x1000f5298] buffer_pool_manager.cpp:49 - + ! 133 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 196 [0x1000f55c8] buffer_pool_manager.hpp:109 - + ! : 83 std::to_string(unsigned int) (in libc++.1.dylib) + 76 [0x183025a9c] - + ! : | 49 (in libc++.1.dylib) + 152 [0x18303a760] - + ! : | + 41 _platform_memmove (in libsystem_platform.dylib) + 452,0,... [0x183119584,0x1831193c0,...] - + ! : | + 8 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] - + ! : | 34 (in libc++.1.dylib) + 16,128,... [0x18303a6d8,0x18303a748,...] - + ! : 26 std::to_string(unsigned int) (in libc++.1.dylib) + 56 [0x183025a88] - + ! : | 26 std::__itoa::__base_10_u32[abi:nqe210106](char*, unsigned int) (in libc++.1.dylib) + 936,492,... [0x183033e28,0x183033c6c,...] - + ! : 13 std::to_string(unsigned int) (in libc++.1.dylib) + 36,76,... [0x183025a74,0x183025a9c,...] - + ! : 10 (in libc++.1.dylib) + 168 [0x18303a770] - + ! : 1 DYLD-STUB$$std::to_string(unsigned int) (in storage_bench) + 0 [0x10011f210] - + ! 94 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 228 [0x1000f55e8] buffer_pool_manager.hpp:109 - + ! : 50 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] - + ! : | 36 _platform_memmove (in libsystem_platform.dylib) + 452,0,... [0x183119584,0x1831193c0,...] - + ! : | 14 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] - + ! : 39 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 32,148,... [0x183021ecc,0x183021f40,...] - + ! : 5 DYLD-STUB$$std::basic_string::append(char const*, unsigned long) (in storage_bench) + 4 [0x10011eecc] - + ! 16 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 172 [0x1000f55b0] buffer_pool_manager.hpp:109 - + ! : 16 _platform_memmove (in libsystem_platform.dylib) + 12,460,... [0x1831193cc,0x18311958c,...] - + ! 10 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 188,192 [0x183021f68,0x183021f6c] - + ! 9 std::to_string(unsigned int) (in libc++.1.dylib) + 104 [0x183025ab8] - + ! 7 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 40,260,... [0x1000f552c,0x1000f5608,...] buffer_pool_manager.hpp:109 - + 128 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 116 [0x1000f52cc] buffer_pool_manager.cpp:51 - + ! 50 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 76 [0x1000f61a8] __hash_table:1529 - + ! : 23 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 400,352,... [0x1000f3f84,0x1000f3f54,...] hash.h:91 - + ! : 17 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 0,4 [0x1000f3df4,0x1000f3df8] hash.h:87 - + ! : 7 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 456 [0x1000f3fbc] hash.h:123 - + ! : 3 std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) + 444,452 [0x1000f3fb0,0x1000f3fb8] hash.h:0 - + ! 28 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 288 [0x1000f627c] __hash_table:1541 - + ! : 22 _platform_memcmp (in libsystem_platform.dylib) + 0,48,... [0x183116f30,0x183116f60,...] - + ! : 6 DYLD-STUB$$memcmp (in storage_bench) + 4 [0x10011f3f4] - + ! 12 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 240,260,... [0x1000f624c,0x1000f6260,...] __hash_table:1541 - + ! 10 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 220,296,... [0x1000f6238,0x1000f6284,...] __hash_table:1539 - + ! 9 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 16,20 [0x1000f616c,0x1000f6170] __hash_table:1528 - + ! 6 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 100,128,... [0x1000f61c0,0x1000f61dc,...] __hash_table:1535 - + ! 4 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 152 [0x1000f61f4] __hash_table:1536 - + ! 3 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 212 [0x1000f6230] __hash_table:0 - + ! 3 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 68 [0x1000f61a0] __hash_table:1529 - + ! 2 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 204 [0x1000f6228] __hash_table:1538 - + ! 1 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 156 [0x1000f61f8] __hash_table:1537 - + 64 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 548 [0x1000f547c] buffer_pool_manager.cpp:86 - + ! 47 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] - + ! : 39 pthread_mutex_unlock (in libsystem_pthread.dylib) + 104,12,... [0x18310a9ac,0x18310a950,...] - + ! : 8 DYLD-STUB$$pthread_mutex_unlock (in libc++.1.dylib) + 8 [0x183084920] - + ! 9 std::mutex::unlock() (in libc++.1.dylib) + 16,0 [0x183022038,0x183022028] - + ! 8 DYLD-STUB$$std::mutex::unlock() (in storage_bench) + 4,8 [0x10011f13c,0x10011f140] - + 21 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 48 [0x1000f5288] buffer_pool_manager.cpp:47 - + ! 18 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] - + ! : 18 pthread_mutex_lock (in libsystem_pthread.dylib) + 4,108,... [0x18310a400,0x18310a468,...] - + ! 3 std::mutex::lock() (in libc++.1.dylib) + 20 [0x183022014] - + 15 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 524 [0x1000f5464] buffer_pool_manager.cpp:86 - + 14 std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) + 864,868,... [0x1000f64bc,0x1000f64c0,...] __hash_table:1575 - + 11 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 16,20 [0x1000f5268,0x1000f526c] buffer_pool_manager.cpp:46 - + 6 ??? (in storage_bench) load address 0x1000f0000 + 0x3de4 [0x1000f3de4] - + 6 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 496 [0x1000f5448] buffer_pool_manager.cpp:79 - + ! 3 cloudsql::storage::StorageManager::read_page(std::basic_string const&, unsigned int, char*) (in storage_bench) + 140 [0x1000f3748] storage_manager.cpp:107 - + ! : 3 std::basic_istream::seekg(long long, std::ios_base::seekdir) (in libc++.1.dylib) + 196 [0x183025f14] - + ! : 2 std::basic_filebuf::seekoff(long long, std::ios_base::seekdir, unsigned int) (in libc++.1.dylib) + 132 [0x183055e14] - + ! : | 2 std::basic_filebuf::sync() (in libc++.1.dylib) + 500 [0x18305618c] - + ! : | 1 DYLD-STUB$$fseeko (in libc++.1.dylib) + 0 [0x183084648] - + ! : | 1 fseeko (in libsystem_c.dylib) + 92 [0x182fb2594] - + ! : | 1 _fseeko (in libsystem_c.dylib) + 16 [0x182fcee9c] - + ! : 1 std::basic_filebuf::seekoff(long long, std::ios_base::seekdir, unsigned int) (in libc++.1.dylib) + 232 [0x183055e78] - + ! : 1 ftello (in libsystem_c.dylib) + 44 [0x182fb2a70] - + ! : 1 _ftello (in libsystem_c.dylib) + 188 [0x182fcd138] - + ! : 1 _sseek (in libsystem_c.dylib) + 72 [0x182fb2af8] - + ! : 1 __lseek (in libsystem_kernel.dylib) + 8 [0x1830cd624] - + ! 3 cloudsql::storage::StorageManager::read_page(std::basic_string const&, unsigned int, char*) (in storage_bench) + 192 [0x1000f377c] storage_manager.cpp:114 - + ! 3 std::basic_istream::read(char*, long) (in libc++.1.dylib) + 136 [0x183024e80] - + ! 3 std::basic_streambuf::xsgetn(char*, long) (in libc++.1.dylib) + 156 [0x183024ff0] - + ! 3 std::basic_streambuf::uflow() (in libc++.1.dylib) + 48 [0x18302505c] - + ! 3 std::basic_filebuf::underflow() (in libc++.1.dylib) + 264 [0x183055778] - + ! 3 fread (in libsystem_c.dylib) + 136 [0x182fb2c5c] - + ! 3 __fread (in libsystem_c.dylib) + 336 [0x182faa308] - + ! 3 __srefill1 (in libsystem_c.dylib) + 36 [0x182faa0f0] - + ! 2 _sread (in libsystem_c.dylib) + 0 [0x182faa13c] - + ! 1 _sread (in libsystem_c.dylib) + 32 [0x182faa15c] - + ! 1 __sread (in libsystem_c.dylib) + 24 [0x182fcd074] - + ! 1 __read_nocancel (in libsystem_kernel.dylib) + 8 [0x1830cdcac] - + 6 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 284 [0x1000f5620] buffer_pool_manager.hpp:109 - + 5 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 288 [0x1000f6778] lru_replacer.cpp:37 - + 3 ??? (in storage_bench) load address 0x1000f0000 + 0x3c94 [0x1000f3c94] - + 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3dd8 [0x1000f3dd8] - + 1 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 64 [0x1000f5298] buffer_pool_manager.cpp:50 - + 1 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 92 [0x1000f52b4] buffer_pool_manager.cpp:51 - 1756 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 160 [0x1000f7b68] heap_table.cpp:113 - + 1752 _platform_memmove (in libsystem_platform.dylib) + 180,204,... [0x183119474,0x18311948c,...] - + 4 DYLD-STUB$$memcpy (in storage_bench) + 4 [0x10011f400] - 673 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 528 [0x1000f7cd8] heap_table.cpp:134 - + 543 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 108 [0x183021f18] - + ! 255 std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) + 180 [0x183023064] - + ! : 211 $_0::operator()() const::'lambda0'(unsigned long, std::__type_descriptor_t)::__invoke(unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 16 [0x1830c54a8] - + ! : | 202 operator_new_impl[abi:nqe210106](unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 36 [0x1830c54dc] - + ! : | + 113 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 88,104,... [0x182f31f2c,0x182f31f3c,...] - + ! : | + 39 _xzm_xzone_malloc (in libsystem_malloc.dylib) + 8,0,... [0x182f2c8c8,0x182f2c8c0,...] - + ! : | + 21 (in libsystem_malloc.dylib) + 96,112,... [0x182f2c134,0x182f2c144,...] - + ! : | + 18 malloc_type_malloc (in libsystem_malloc.dylib) + 72,16,... [0x182f2002c,0x182f1fff4,...] - + ! : | + 10 DYLD-STUB$$malloc_type_malloc (in libc++abi.dylib) + 8 [0x1830c6c18] - + ! : | + 1 xzm_malloc_zone_malloc_type_malloc (in libsystem_malloc.dylib) + 0 [0x182f3811c] - + ! : | 9 operator_new_impl[abi:nqe210106](unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 8 [0x1830c54c0] - + ! : 18 new(unsigned long, std::__type_descriptor_t) (in libc++.1.dylib) + 8,0 [0x1830842a0,0x183084298] - + ! : 13 operator new(unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 4,0 [0x1830c5370,0x1830c536c] - + ! : 9 operator_new_impl[abi:nqe210106](unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 68 [0x1830c54fc] - + ! : 4 $_0::operator()() const::'lambda0'(unsigned long, std::__type_descriptor_t)::__invoke(unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) + 20,0,... [0x1830c54ac,0x1830c5498,...] - + ! 118 std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) + 224 [0x183023090] - + ! : 107 _platform_memmove (in libsystem_platform.dylib) + 428,452,... [0x18311956c,0x183119584,...] - + ! : 11 DYLD-STUB$$memcpy (in libc++.1.dylib) + 8 [0x1830847b0] - + ! 91 std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) + 204 [0x18302307c] - + ! : 84 _platform_memmove (in libsystem_platform.dylib) + 452,444,... [0x183119584,0x18311957c,...] - + ! : 7 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] - + ! 79 std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) + 24,224,... [0x183022fc8,0x183023090,...] - + 62 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 108,32,... [0x183021f18,0x183021ecc,...] - + 42 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] - + ! 30 _platform_memmove (in libsystem_platform.dylib) + 452,428,... [0x183119584,0x18311956c,...] - + ! 12 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] - + 20 DYLD-STUB$$std::basic_string::append(char const*, unsigned long) (in storage_bench) + 4,0 [0x10011eecc,0x10011eec8] - + 6 std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) + 320,308 [0x1830230f0,0x1830230e4] - 605 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 460 [0x1000f7c94] heap_table.cpp:134 - + 241 std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) + 80 [0x1000ff870] string:2393 - + ! 222 operator new(unsigned long) (in libc++abi.dylib) + 52 [0x1830c67e8] - + ! : 102 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 88,52,... [0x182f31f2c,0x182f31f08,...] - + ! : 48 _xzm_xzone_malloc (in libsystem_malloc.dylib) + 180,324,... [0x182f2c974,0x182f2ca04,...] - + ! : 43 (in libsystem_malloc.dylib) + 0,112,... [0x182f2c0d4,0x182f2c144,...] - + ! : 24 malloc_type_malloc (in libsystem_malloc.dylib) + 28,72,... [0x182f20000,0x182f2002c,...] - + ! : 4 DYLD-STUB$$malloc_type_malloc (in libc++abi.dylib) + 8 [0x1830c6c18] - + ! : 1 xzm_malloc_zone_malloc_type_malloc (in libsystem_malloc.dylib) + 0 [0x182f3811c] - + ! 10 operator new(unsigned long) (in libc++abi.dylib) + 24,36,... [0x1830c67cc,0x1830c67d8,...] - + ! 9 DYLD-STUB$$operator new(unsigned long) (in storage_bench) + 4 [0x10011f274] - + 95 _platform_memmove (in libsystem_platform.dylib) + 428,452,... [0x18311956c,0x183119584,...] - + 78 std::to_string(long long) (in libc++.1.dylib) + 432 [0x183027acc] - + ! 39 (in libc++.1.dylib) + 152 [0x18303a760] - + ! : 32 _platform_memmove (in libsystem_platform.dylib) + 452,460,... [0x183119584,0x18311958c,...] - + ! : 7 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] - + ! 39 (in libc++.1.dylib) + 0,16,... [0x18303a6c8,0x18303a6d8,...] - + 40 cloudsql::common::Value::to_string() const (in storage_bench) + 36,64,... [0x1000f7f7c,0x1000f7f98,...] value.hpp:273 - + 39 std::to_string(long long) (in libc++.1.dylib) + 172 [0x1830279c8] - + ! 39 std::__itoa::__base_10_u32[abi:nqe210106](char*, unsigned int) (in libc++.1.dylib) + 936,0,... [0x183033e28,0x183033a80,...] - + 35 std::to_string(long long) (in libc++.1.dylib) + 56,156,... [0x183027954,0x1830279b8,...] - + 14 std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) + 8 [0x1000ff828] string:2382 - + 13 (in libc++.1.dylib) + 168,164 [0x18303a770,0x18303a76c] - + 8 DYLD-STUB$$memmove (in storage_bench) + 4 [0x10011f40c] - + 8 DYLD-STUB$$std::to_string(long long) (in storage_bench) + 4 [0x10011f220] - + 8 cloudsql::common::Value::to_string() const (in storage_bench) + 192,196 [0x1000f8018,0x1000f801c] value.hpp:0 - + 8 cloudsql::common::Value::to_string() const (in storage_bench) + 500 [0x1000f814c] value.hpp:289 - + 8 std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) + 76 [0x1000ff86c] string:2393 - + 3 cloudsql::common::Value::to_string() const (in storage_bench) + 32,0 [0x1000f7f78,0x1000f7f58] value.hpp:272 - + 3 operator new(unsigned long) (in libc++abi.dylib) + 76 [0x1830c6800] - + 3 std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) + 36 [0x1000ff844] string:0 - + 1 std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) + 80 [0x1000ff870] string:2397 - 495 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 116 [0x1000f7b3c] heap_table.cpp:163 - + 209 _xzm_free (in libsystem_malloc.dylib) + 1048 [0x182f2d484] - + ! 201 mach_absolute_time (in libsystem_kernel.dylib) + 108,112,... [0x1830cc10c,0x1830cc110,...] - + ! 8 DYLD-STUB$$mach_absolute_time (in libsystem_malloc.dylib) + 8 [0x182f44b14] - + 126 _xzm_free (in libsystem_malloc.dylib) + 684,164,... [0x182f2d318,0x182f2d110,...] - + 89 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] - + ! 74 _platform_memset (in libsystem_platform.dylib) + 180,208,... [0x1831191a4,0x1831191c0,...] - + ! 14 DYLD-STUB$$_platform_bzero (in libsystem_malloc.dylib) + 8 [0x182f447f4] - + ! 1 __bzero (in libsystem_platform.dylib) + 0 [0x183119090] - + 40 _free (in libsystem_malloc.dylib) + 0,44,... [0x182f3cc4c,0x182f3cc78,...] - + 23 DYLD-STUB$$operator delete(void*) (in storage_bench) + 4,0 [0x10011f25c,0x10011f258] - + 8 DYLD-STUB$$free (in libc++abi.dylib) + 8 [0x1830c6bd8] - 299 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 472 [0x1000f7ca0] heap_table.cpp:134 - + 109 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] - + ! 65 _platform_memmove (in libsystem_platform.dylib) + 428,0,... [0x18311956c,0x1831193c0,...] - + ! 44 DYLD-STUB$$memmove (in libc++.1.dylib) + 8,0 [0x1830847c0,0x1830847b8] - + 99 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 32,148,... [0x183021ecc,0x183021f40,...] - + 66 std::basic_string::append(char const*) (in libc++.1.dylib) + 32 [0x1830245c8] - + ! 42 _platform_strlen (in libsystem_platform.dylib) + 56,80,... [0x183116b18,0x183116b30,...] - + ! 24 DYLD-STUB$$strlen (in libc++.1.dylib) + 8 [0x183084a90] - + 25 DYLD-STUB$$std::basic_string::append(char const*) (in storage_bench) + 4,0 [0x10011eec0,0x10011eebc] - 279 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 428 [0x1000f7c74] heap_table.cpp:134 - + 141 _xzm_free (in libsystem_malloc.dylib) + 672,996,... [0x182f2d30c,0x182f2d450,...] - + 54 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] - + ! 50 _platform_memset (in libsystem_platform.dylib) + 180,208,... [0x1831191a4,0x1831191c0,...] - + ! 2 DYLD-STUB$$_platform_bzero (in libsystem_malloc.dylib) + 8 [0x182f447f4] - + ! 2 __bzero (in libsystem_platform.dylib) + 0 [0x183119090] - + 48 _free (in libsystem_malloc.dylib) + 0,44,... [0x182f3cc4c,0x182f3cc78,...] - + 20 DYLD-STUB$$operator delete(void*) (in storage_bench) + 4,0 [0x10011f25c,0x10011f258] - + 14 DYLD-STUB$$free (in libc++abi.dylib) + 8 [0x1830c6bd8] - + 1 free (in libsystem_malloc.dylib) + 0 [0x182f036b8] - + 1 xzm_malloc_zone_try_free_default (in libsystem_malloc.dylib) + 0 [0x182f38108] - 151 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 368 [0x1000f7c38] heap_table.cpp:132 - + 65 std::basic_string::append(char const*) (in libc++.1.dylib) + 32 [0x1830245c8] - + ! 52 _platform_strlen (in libsystem_platform.dylib) + 56,80,... [0x183116b18,0x183116b30,...] - + ! 13 DYLD-STUB$$strlen (in libc++.1.dylib) + 8 [0x183084a90] - + 52 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] - + ! 40 _platform_memmove (in libsystem_platform.dylib) + 452,428,... [0x183119584,0x18311956c,...] - + ! 12 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] - + 31 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 32,112,... [0x183021ecc,0x183021f1c,...] - + 2 DYLD-STUB$$std::basic_string::append(char const*) (in storage_bench) + 4 [0x10011eec0] - + 1 std::basic_string::append(char const*) (in libc++.1.dylib) + 8 [0x1830245b0] - 127 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 352 [0x1000f7c28] heap_table.cpp:132 - + 65 std::to_string(unsigned long long) (in libc++.1.dylib) + 348 [0x183043540] - + ! 36 (in libc++.1.dylib) + 16,128,... [0x18303a6d8,0x18303a748,...] - + ! 29 (in libc++.1.dylib) + 152 [0x18303a760] - + ! 21 _platform_memmove (in libsystem_platform.dylib) + 0,428,... [0x1831193c0,0x18311956c,...] - + ! 8 DYLD-STUB$$memmove (in libc++.1.dylib) + 8 [0x1830847c0] - + 30 std::to_string(unsigned long long) (in libc++.1.dylib) + 72 [0x18304342c] - + ! 30 std::__itoa::__base_10_u32[abi:nqe210106](char*, unsigned int) (in libc++.1.dylib) + 28,0,... [0x183033a9c,0x183033a80,...] - + 14 (in libc++.1.dylib) + 168 [0x18303a770] - + 10 std::to_string(unsigned long long) (in libc++.1.dylib) + 48,328,... [0x183043414,0x18304352c,...] - + 8 DYLD-STUB$$std::to_string(unsigned long long) (in storage_bench) + 4 [0x10011f22c] - 59 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 188,192,... [0x183021f68,0x183021f6c,...] - 36 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 420,536,... [0x1000f7c6c,0x1000f7ce0,...] heap_table.cpp:134 - 33 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 436,412,... [0x1000f7c7c,0x1000f7c64,...] heap_table.cpp:133 - 26 std::basic_string::append(char const*) (in libc++.1.dylib) + 56,48 [0x1830245e0,0x1830245d8] - 25 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 160,136 [0x1000f7b68,0x1000f7b50] heap_table.cpp:113 - 23 _xzm_free (in libsystem_malloc.dylib) + 1560,1552,... [0x182f2d684,0x182f2d67c,...] - 15 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 344,352,... [0x1000f7c20,0x1000f7c28,...] heap_table.cpp:132 - 9 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 592 [0x1000f7d18] heap_table.cpp:140 - 7 std::to_string(long long) (in libc++.1.dylib) + 468 [0x183027af0] - 5 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 748 [0x1000f7db4] heap_table.cpp:157 - + 5 _platform_memmove (in libsystem_platform.dylib) + 180,192 [0x183119474,0x183119480] - 5 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 768 [0x1000f7dc8] heap_table.cpp:157 - + 3 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 176 [0x1000f5748] buffer_pool_manager.cpp:109 - + ! 2 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 232 [0x1000f686c] lru_replacer.cpp:50 - + ! : 2 operator new(unsigned long) (in libc++abi.dylib) + 52 [0x1830c67e8] - + ! : 1 (in libsystem_malloc.dylib) + 112 [0x182f2c144] - + ! : 1 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 12 [0x182f31ee0] - + ! 1 cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) + 312 [0x1000f68bc] lru_replacer.cpp:52 - + ! 1 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] - + ! 1 pthread_mutex_unlock (in libsystem_pthread.dylib) + 32 [0x18310a964] - + 1 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 60 [0x1000f56d4] buffer_pool_manager.cpp:91 - + ! 1 cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) + 228 [0x1000f55e8] buffer_pool_manager.hpp:109 - + ! 1 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] - + ! 1 _platform_memmove (in libsystem_platform.dylib) + 452 [0x183119584] - + 1 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 72 [0x1000f56e0] buffer_pool_manager.cpp:92 - + 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3d20 [0x1000f3d20] - 4 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 568 [0x1000f5490] buffer_pool_manager.cpp:86 - 4 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 556 [0x1000f7cf4] heap_table.cpp:137 - 3 cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) + 232 [0x1000f5780] buffer_pool_manager.cpp:113 - 3 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 700 [0x1000f7d84] heap_table.cpp:157 - + 1 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 48 [0x1000f5288] buffer_pool_manager.cpp:47 - + ! 1 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] - + ! 1 pthread_mutex_lock (in libsystem_pthread.dylib) + 64 [0x18310a43c] - + 1 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 76 [0x1000f52a4] buffer_pool_manager.cpp:50 - + ! 1 ??? (in storage_bench) load address 0x1000f0000 + 0x3cc0 [0x1000f3cc0] - + 1 cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) + 152 [0x1000f52f0] buffer_pool_manager.cpp:54 - + 1 cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) + 240 [0x1000f6748] lru_replacer.cpp:34 - + 1 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] - + 1 _platform_memset (in libsystem_platform.dylib) + 208 [0x1831191c0] - 2 std::to_string(unsigned long long) (in libc++.1.dylib) + 384 [0x183043564] - 1 cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) + 324 [0x1000f7c0c] heap_table.cpp:125 - -Total number in stack (recursive counted multiple, when >=5): - 17 _platform_memmove (in libsystem_platform.dylib) + 0 [0x1831193c0] - 10 DYLD-STUB$$memmove (in libc++.1.dylib) + 0 [0x1830847b8] - 8 (in libc++.1.dylib) + 0 [0x18303a6c8] - 8 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 0 [0x183021eac] - 7 pthread_mutex_lock (in libsystem_pthread.dylib) + 0 [0x18310a3fc] - 6 _xzm_free (in libsystem_malloc.dylib) + 0 [0x182f2d06c] - 6 operator new(unsigned long) (in libc++abi.dylib) + 0 [0x1830c67b4] - 6 std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) + 144 [0x183021f3c] - 5 (in libsystem_malloc.dylib) + 0 [0x182f2c0d4] - 5 _platform_memset (in libsystem_platform.dylib) + 0 [0x1831190f0] - 5 _xzm_free (in libsystem_malloc.dylib) + 352 [0x182f2d1cc] - 5 _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) + 0 [0x182f31ed4] - 5 pthread_mutex_unlock (in libsystem_pthread.dylib) + 0 [0x18310a944] - 5 std::mutex::lock() (in libc++.1.dylib) + 16 [0x183022010] - 5 std::mutex::unlock() (in libc++.1.dylib) + 16 [0x183022038] - -Sort by top of stack, same collapsed (when >= 5): - _platform_memmove (in libsystem_platform.dylib) 2462 - _xzm_free (in libsystem_malloc.dylib) 609 - _xzm_xzone_malloc_tiny (in libsystem_malloc.dylib) 417 - ??? (in storage_bench) load address 0x1000f0000 + 0x3db0 [0x1000f3db0] 368 - std::basic_string::append(char const*, unsigned long) (in libc++.1.dylib) 346 - std::__murmur2_or_cityhash::operator()[abi:ne200100](void const*, unsigned long) const (in storage_bench) 237 - mach_absolute_time (in libsystem_kernel.dylib) 201 - _platform_memset (in libsystem_platform.dylib) 199 - _free (in libsystem_malloc.dylib) 198 - pthread_mutex_lock (in libsystem_pthread.dylib) 194 - (in libc++.1.dylib) 191 - _xzm_xzone_malloc (in libsystem_malloc.dylib) 174 - (in libsystem_malloc.dylib) 167 - std::__itoa::__base_10_u32[abi:nqe210106](char*, unsigned int) (in libc++.1.dylib) 153 - pthread_mutex_unlock (in libsystem_pthread.dylib) 140 - DYLD-STUB$$memmove (in libc++.1.dylib) 128 - std::__hash_table, unsigned int>>::__emplace_unique_key_args, std::piecewise_construct_t const&, std::tuple const&>, std::tuple<>>(std::basic_string const&, std::piecewise_construct_t const&, std::tuple const&>&&, std::tuple<>&&) (in storage_bench) 126 - cloudsql::storage::HeapTable::insert(cloudsql::executor::Tuple const&, unsigned long long) (in storage_bench) 123 - _platform_strlen (in libsystem_platform.dylib) 94 - _platform_memcmp (in libsystem_platform.dylib) 89 - malloc_type_malloc (in libsystem_malloc.dylib) 89 - std::basic_string::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) (in libc++.1.dylib) 85 - std::__hash_table>>::__emplace_unique_key_args, std::tuple<>>(unsigned int const&, std::piecewise_construct_t const&, std::tuple&&, std::tuple<>&&) (in storage_bench) 82 - ??? (in storage_bench) load address 0x1000f0000 + 0x3d70 [0x1000f3d70] 80 - DYLD-STUB$$operator delete(void*) (in storage_bench) 80 - DYLD-STUB$$free (in libc++abi.dylib) 60 - cloudsql::common::Value::to_string() const (in storage_bench) 59 - cloudsql::storage::BufferPoolManager::make_page_key(std::basic_string const&, unsigned int) (in storage_bench) 59 - cloudsql::storage::LRUReplacer::pin(unsigned int) (in storage_bench) 53 - operator new(unsigned long) (in libc++abi.dylib) 45 - DYLD-STUB$$pthread_mutex_lock (in libc++.1.dylib) 43 - std::to_string(long long) (in libc++.1.dylib) 42 - DYLD-STUB$$pthread_mutex_unlock (in libc++.1.dylib) 39 - DYLD-STUB$$memcmp (in storage_bench) 38 - cloudsql::storage::LRUReplacer::unpin(unsigned int) (in storage_bench) 38 - DYLD-STUB$$strlen (in libc++.1.dylib) 37 - cloudsql::storage::BufferPoolManager::unpin_page(std::basic_string const&, unsigned int, bool) (in storage_bench) 34 - DYLD-STUB$$std::basic_string::append(char const*, unsigned long) (in storage_bench) 33 - std::mutex::lock() (in libc++.1.dylib) 33 - cloudsql::storage::BufferPoolManager::fetch_page(std::basic_string const&, unsigned int) (in storage_bench) 32 - DYLD-STUB$$_platform_bzero (in libsystem_malloc.dylib) 31 - std::to_string(unsigned int) (in libc++.1.dylib) 31 - DYLD-STUB$$operator new(unsigned long) (in storage_bench) 29 - std::mutex::unlock() (in libc++.1.dylib) 28 - DYLD-STUB$$std::basic_string::append(char const*) (in storage_bench) 27 - DYLD-STUB$$std::mutex::lock() (in storage_bench) 27 - std::basic_string::append(char const*) (in libc++.1.dylib) 27 - std::basic_string::__init_copy_ctor_external(char const*, unsigned long) (in storage_bench) 26 - DYLD-STUB$$std::mutex::unlock() (in storage_bench) 25 - DYLD-STUB$$malloc_type_malloc (in libc++abi.dylib) 24 - new(unsigned long, std::__type_descriptor_t) (in libc++.1.dylib) 18 - operator_new_impl[abi:nqe210106](unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) 18 - ??? (in storage_bench) load address 0x1000f0000 + 0x3c94 [0x1000f3c94] 16 - ??? (in storage_bench) load address 0x1000f0000 + 0x48ac [0x1000f48ac] 15 - DYLD-STUB$$std::to_string(unsigned int) (in storage_bench) 15 - ??? (in storage_bench) load address 0x1000f0000 + 0x3de4 [0x1000f3de4] 14 - DYLD-STUB$$memmove (in storage_bench) 14 - operator new(unsigned long, std::__type_descriptor_t) (in libc++abi.dylib) 13 - ??? (in storage_bench) load address 0x1000f0000 + 0x3d64 [0x1000f3d64] 12 - std::to_string(unsigned long long) (in libc++.1.dylib) 12 - DYLD-STUB$$memcpy (in libc++.1.dylib) 11 - ??? (in storage_bench) load address 0x1000f0000 + 0x3cd8 [0x1000f3cd8] 10 - ??? (in storage_bench) load address 0x1000f0000 + 0x3d28 [0x1000f3d28] 9 - DYLD-STUB$$mach_absolute_time (in libsystem_malloc.dylib) 8 - DYLD-STUB$$std::to_string(long long) (in storage_bench) 8 - DYLD-STUB$$std::to_string(unsigned long long) (in storage_bench) 8 - __bzero (in libsystem_platform.dylib) 8 - ??? (in storage_bench) load address 0x1000f0000 + 0x3d08 [0x1000f3d08] 7 - ??? (in storage_bench) load address 0x1000f0000 + 0x3d88 [0x1000f3d88] 7 - ??? (in storage_bench) load address 0x1000f0000 + 0x47cc [0x1000f47cc] 7 - ??? (in storage_bench) load address 0x1000f0000 + 0x4844 [0x1000f4844] 7 - ??? (in storage_bench) load address 0x1000f0000 + 0x3d54 [0x1000f3d54] 6 - ??? (in storage_bench) load address 0x1000f0000 + 0x47a4 [0x1000f47a4] 6 - ??? (in storage_bench) load address 0x1000f0000 + 0x3ca8 [0x1000f3ca8] 5 - ??? (in storage_bench) load address 0x1000f0000 + 0x478c [0x1000f478c] 5 - -Binary Images: - 0x1000f0000 - 0x100124cef +storage_bench (0) <36C28C6B-B05F-3511-B235-E2888FE43F53> /Users/*/storage_bench - 0x182cac000 - 0x182cfeb4b libobjc.A.dylib (951.7) <2E858E25-1FF6-3DA6-84F6-911630620512> /usr/lib/libobjc.A.dylib - 0x182cff000 - 0x182d33b34 libdyld.dylib (1376.6) <2C3C5F75-3686-39A1-9202-BD4D2133379D> /usr/lib/system/libdyld.dylib - 0x182d34000 - 0x182dd9ec7 dyld (1.0.0 - 1376.6) <9F682DCF-340C-3BFA-BCDD-DD702F30313E> /usr/lib/dyld - 0x182dda000 - 0x182ddd228 libsystem_blocks.dylib (96) <2EA73169-CF76-3DD1-9869-F23C8B338022> /usr/lib/system/libsystem_blocks.dylib - 0x182dde000 - 0x182e3251f libxpc.dylib (3102.100.102) <618039C8-9965-3782-A7D2-90FD4C3DD66F> /usr/lib/system/libxpc.dylib - 0x182e33000 - 0x182e539bf libsystem_trace.dylib (1861.100.19) <08629650-54FC-3AA6-910E-EACA563804D0> /usr/lib/system/libsystem_trace.dylib - 0x182e54000 - 0x182f01daf libcorecrypto.dylib (1922.101.2) /usr/lib/system/libcorecrypto.dylib - 0x182f02000 - 0x182f521d7 libsystem_malloc.dylib (812.100.31) <2AD21BE3-FFDB-31D5-A3D7-2F7F672D6E92> /usr/lib/system/libsystem_malloc.dylib - 0x182f53000 - 0x182f9a23f libdispatch.dylib (1542.100.32) /usr/lib/system/libdispatch.dylib - 0x182f9b000 - 0x182f9dffb libsystem_featureflags.dylib (103) <0DE01F76-4B36-35A2-98F9-43DD147EDD95> /usr/lib/system/libsystem_featureflags.dylib - 0x182f9e000 - 0x18301eef7 libsystem_c.dylib (1752.100.10) <66EBD321-6899-3863-BA24-5CFC3076A0CB> /usr/lib/system/libsystem_c.dylib - 0x18301f000 - 0x1830afae7 libc++.1.dylib (2100.43) <1E9541EC-C564-38CB-BED6-46F708E8D863> /usr/lib/libc++.1.dylib - 0x1830b0000 - 0x1830ca75f libc++abi.dylib (2100.43) /usr/lib/libc++abi.dylib - 0x1830cb000 - 0x18310828f libsystem_kernel.dylib (12377.101.15) <51565B39-F595-3E96-A217-FEF29815057A> /usr/lib/system/libsystem_kernel.dylib - 0x183109000 - 0x183115b3b libsystem_pthread.dylib (539.100.4) /usr/lib/system/libsystem_pthread.dylib - 0x183116000 - 0x18311e8f3 libsystem_platform.dylib (375.100.10) /usr/lib/system/libsystem_platform.dylib - 0x18311f000 - 0x18314e6eb libsystem_info.dylib (600) <201FD67C-3DF6-3788-B132-A69CAA2AA3D7> /usr/lib/system/libsystem_info.dylib - 0x1870e4000 - 0x1870ede5f libsystem_darwin.dylib (1752.100.10) /usr/lib/system/libsystem_darwin.dylib - 0x18754f000 - 0x187560f5b libsystem_notify.dylib (348.100.7) <9F46F30B-B7C0-3DD7-AC38-57B78C7971FF> /usr/lib/system/libsystem_notify.dylib - 0x189819000 - 0x189833f5b libsystem_networkextension.dylib (2226.101.1) <85169C7B-48DD-3542-AD38-F1B88EA2A95A> /usr/lib/system/libsystem_networkextension.dylib - 0x1898b6000 - 0x1898cdfdf libsystem_asl.dylib (406) <6427D987-7938-3278-8C14-10FB9C06BBD5> /usr/lib/system/libsystem_asl.dylib - 0x18b471000 - 0x18b479387 libsystem_symptoms.dylib (2169.100.30) <28B6E34E-9C7D-3437-A3F1-A3C979DE579A> /usr/lib/system/libsystem_symptoms.dylib - 0x18f70c000 - 0x18f74425f libsystem_containermanager.dylib (725.100.37) <14750F95-BB3A-3654-8610-A05A454643A8> /usr/lib/system/libsystem_containermanager.dylib - 0x190b1c000 - 0x190b205d7 libsystem_configuration.dylib (1405.100.8) <634F597D-F8BD-3C00-B967-86047FC15D14> /usr/lib/system/libsystem_configuration.dylib - 0x190b21000 - 0x190b278cf libsystem_sandbox.dylib (2680.100.174) /usr/lib/system/libsystem_sandbox.dylib - 0x192167000 - 0x19216a1fb libquarantine.dylib (196.100.8) <268FEB6E-A237-3050-BFFF-AE3A66B7EAD4> /usr/lib/system/libquarantine.dylib - 0x192906000 - 0x19290cd03 libsystem_coreservices.dylib (191.4.5) <7129349D-04F9-3C3C-BF37-3082C1468654> /usr/lib/system/libsystem_coreservices.dylib - 0x192e8b000 - 0x192ec8a77 libsystem_m.dylib (3312.100.1) <83B173CD-7F32-3901-8E67-C0B2676BE015> /usr/lib/system/libsystem_m.dylib - 0x192eca000 - 0x192ecd527 libmacho.dylib (1376.6) <9729ECEA-0A08-32E3-8BDB-B42FC15FF258> /usr/lib/system/libmacho.dylib - 0x192ee7000 - 0x192ef43a7 libcommonCrypto.dylib (600035) <710EC5FA-F77C-3646-A9E3-C037C42E1539> /usr/lib/system/libcommonCrypto.dylib - 0x192ef5000 - 0x192efeca3 libunwind.dylib (2100.2) /usr/lib/system/libunwind.dylib - 0x192f07000 - 0x192f117ff libcopyfile.dylib (240) <0B7FF027-5579-3CBF-A12B-68A4FD36641C> /usr/lib/system/libcopyfile.dylib - 0x192f12000 - 0x192f15987 libcompiler_rt.dylib (103.3) <65E29E6E-7042-3F73-A1D2-F2C4EBCD7524> /usr/lib/system/libcompiler_rt.dylib - 0x192f16000 - 0x192f1a78b libsystem_collections.dylib (1752.100.10) /usr/lib/system/libsystem_collections.dylib - 0x192f1b000 - 0x192f1e4cf libsystem_secinit.dylib (168.100.7) /usr/lib/system/libsystem_secinit.dylib - 0x192f1f000 - 0x192f21bf7 libremovefile.dylib (85.100.6) /usr/lib/system/libremovefile.dylib - 0x192f22000 - 0x192f22f27 libkeymgr.dylib (31) /usr/lib/system/libkeymgr.dylib - 0x192f23000 - 0x192f2be3f libsystem_dnssd.dylib (2881.100.56.0.1) /usr/lib/system/libsystem_dnssd.dylib - 0x192f2c000 - 0x192f3109b libcache.dylib (95) <4D6833A3-C910-3A76-AA8A-303F698B36BF> /usr/lib/system/libcache.dylib - 0x192f32000 - 0x192f33ce3 libSystem.B.dylib (1356) /usr/lib/libSystem.B.dylib - 0x285815000 - 0x28581c349 libRosetta.dylib (367.5) <2FC1EF06-04C4-35FC-8DC3-BEA1E9FBD63F> /usr/lib/libRosetta.dylib - 0x2874f2000 - 0x2874f5a4b libsystem_darwindirectory.dylib (122) /usr/lib/system/libsystem_darwindirectory.dylib - 0x2874f6000 - 0x2874ff5a7 libsystem_eligibility.dylib (319.101.1) <2D19994A-87BB-34B8-A343-CB8DD47FF110> /usr/lib/system/libsystem_eligibility.dylib - 0x287500000 - 0x2875078db libsystem_sanitizers.dylib (26) /usr/lib/system/libsystem_sanitizers.dylib - 0x287508000 - 0x287508bb7 libsystem_trial.dylib (474.2.18) <5BB81430-4E33-3160-94D2-1FFB2B614DB2> /usr/lib/system/libsystem_trial.dylib diff --git a/src/storage/heap_table.cpp b/src/storage/heap_table.cpp index 5f69733..256a118 100644 --- a/src/storage/heap_table.cpp +++ b/src/storage/heap_table.cpp @@ -123,10 +123,6 @@ bool HeapTable::Iterator::next_meta(TupleMeta& out_meta) { size_t cursor = 18; std::pmr::vector values(mr_); - - std::cerr << "DEBUG: Iterator::next_meta values.reserve(" - << table_.schema_.column_count() << ") iter=" << this - << " table=" << &table_ << " mr=" << mr_ << std::endl; values.reserve(table_.schema_.column_count()); for (size_t i = 0; i < table_.schema_.column_count(); ++i) {