From b6a77cd041f4eeef6d3b5d1683826d13d8cfcf03 Mon Sep 17 00:00:00 2001 From: Yoshiaki Nishimura Date: Thu, 17 Oct 2024 16:25:32 +0900 Subject: [PATCH] Move key_begin and key_end members from scan_context to scan_info --- src/jogasaki/executor/process/flow.cpp | 5 +- .../executor/process/impl/ops/scan.cpp | 64 ++----------------- .../process/impl/ops/scan_context.cpp | 14 +--- .../executor/process/impl/ops/scan_context.h | 9 +-- .../executor/process/impl/scan_info.cpp | 46 ++++++++++++- .../executor/process/impl/scan_info.h | 23 +++++-- .../executor/process/impl/task_context.cpp | 53 ++++++++++++++- .../executor/process/impl/task_context.h | 12 ++-- src/jogasaki/serializer/value_writer.h | 2 +- 9 files changed, 140 insertions(+), 88 deletions(-) diff --git a/src/jogasaki/executor/process/flow.cpp b/src/jogasaki/executor/process/flow.cpp index fa5682db8..c0da725ec 100644 --- a/src/jogasaki/executor/process/flow.cpp +++ b/src/jogasaki/executor/process/flow.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 Project Tsurugi. + * Copyright 2018-2024 Project Tsurugi. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -188,6 +188,9 @@ std::shared_ptr flow::create_task_context( empty_input_from_shuffle_ ) ); + if (ctx->scan_info() != nullptr){ + ctx->encode_key(); + } return ctx; } diff --git a/src/jogasaki/executor/process/impl/ops/scan.cpp b/src/jogasaki/executor/process/impl/ops/scan.cpp index 8d6b862a6..55721fc69 100644 --- a/src/jogasaki/executor/process/impl/ops/scan.cpp +++ b/src/jogasaki/executor/process/impl/ops/scan.cpp @@ -250,67 +250,15 @@ void scan::finish(abstract::task_context* context) { status scan::open(scan_context& ctx) { //NOLINT(readability-make-member-function-const) auto& stg = use_secondary_ ? *ctx.secondary_stg_ : *ctx.stg_; - auto be = ctx.scan_info_->begin_endpoint(); - auto ee = ctx.scan_info_->end_endpoint(); - if (use_secondary_) { - // at storage layer, secondary index key contains primary key index as postfix - // so boundary condition needs promotion to be compatible - // TODO verify the promotion - if (be == kvs::end_point_kind::inclusive) { - be = kvs::end_point_kind::prefixed_inclusive; - } - if (be == kvs::end_point_kind::exclusive) { - be = kvs::end_point_kind::prefixed_exclusive; - } - if (ee == kvs::end_point_kind::inclusive) { - ee = kvs::end_point_kind::prefixed_inclusive; - } - if (ee == kvs::end_point_kind::exclusive) { - ee = kvs::end_point_kind::prefixed_exclusive; - } - } - executor::process::impl::variable_table vars{}; - std::size_t blen{}; - std::string msg{}; - if(auto res = details::encode_key( - ctx.req_context(), - ctx.scan_info_->begin_columns(), - vars, - *ctx.varlen_resource(), - ctx.key_begin_, - blen, - msg - ); - res != status::ok) { - if(res == status::err_type_mismatch) { - // only on err_type_mismatch, msg is filled with error message. use it to create the error info in request context - set_error(*ctx.req_context(), error_code::unsupported_runtime_feature_exception, msg, res); - } - return res; - } - std::size_t elen{}; - if(auto res = details::encode_key( - ctx.req_context(), - ctx.scan_info_->end_columns(), - vars, - *ctx.varlen_resource(), - ctx.key_end_, - elen, - msg - ); - res != status::ok) { - if(res == status::err_type_mismatch) { - // only on err_type_mismatch, msg is filled with error message. use it to create the error info in request context - set_error(*ctx.req_context(), error_code::unsupported_runtime_feature_exception, msg, res); - } - return res; + if (auto status = ctx.scan_info_->status_result(); status != status::ok) { + return status; } if(auto res = stg.content_scan( *ctx.tx_, - {static_cast(ctx.key_begin_.data()), blen}, - be, - {static_cast(ctx.key_end_.data()), elen}, - ee, + ctx.scan_info_->begin_key(), + ctx.scan_info_->begin_kind(use_secondary_), + ctx.scan_info_->end_key(), + ctx.scan_info_->end_kind(use_secondary_), ctx.it_ ); res != status::ok) { handle_kvs_errors(*ctx.req_context(), res); diff --git a/src/jogasaki/executor/process/impl/ops/scan_context.cpp b/src/jogasaki/executor/process/impl/ops/scan_context.cpp index 40affd1bc..37f166a16 100644 --- a/src/jogasaki/executor/process/impl/ops/scan_context.cpp +++ b/src/jogasaki/executor/process/impl/ops/scan_context.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 Project Tsurugi. + * Copyright 2018-2024 Project Tsurugi. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,15 +67,7 @@ void scan_context::dump() const noexcept { << " " << std::setw(20) << "transaction_context:" << (tx_ ? tx_ : nullptr) << "\n" << " " << std::setw(20) << "iterator:" - << (it_ ? it_.get() : nullptr) << "\n" - << " " << std::setw(20) << "scan_info:" - << (scan_info_ ? scan_info_ : nullptr) << "\n" - << " " << std::setw(20) << "key_begin_size:" - << key_begin_.size() << "\n" - << " " << std::setw(20) << "key_end_size:" - << key_end_.size() << std::endl; + << (it_ ? it_.get() : nullptr) << "\n"; } -} - - +} // namespace jogasaki::executor::process::impl::ops diff --git a/src/jogasaki/executor/process/impl/ops/scan_context.h b/src/jogasaki/executor/process/impl/ops/scan_context.h index 330866c74..41be57c4a 100644 --- a/src/jogasaki/executor/process/impl/ops/scan_context.h +++ b/src/jogasaki/executor/process/impl/ops/scan_context.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 Project Tsurugi. + * Copyright 2018-2024 Project Tsurugi. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,6 @@ class scan_context : public context_base { void release() override; [[nodiscard]] transaction_context* transaction() const noexcept; - /** * @brief Support for debugging, callable in GDB: ctx->dump() */ @@ -75,10 +74,6 @@ class scan_context : public context_base { transaction_context* tx_{}; std::unique_ptr it_{}; impl::scan_info const* scan_info_{}; - data::aligned_buffer key_begin_{}; - data::aligned_buffer key_end_{}; }; -} - - +} // namespace jogasaki::executor::process::impl::ops diff --git a/src/jogasaki/executor/process/impl/scan_info.cpp b/src/jogasaki/executor/process/impl/scan_info.cpp index 6a23236a4..2e1857f76 100644 --- a/src/jogasaki/executor/process/impl/scan_info.cpp +++ b/src/jogasaki/executor/process/impl/scan_info.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 Project Tsurugi. + * Copyright 2018-2024 Project Tsurugi. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,4 +50,48 @@ kvs::end_point_kind scan_info::end_endpoint() const noexcept { return end_endpoint_; } +[[nodiscard]] data::aligned_buffer & scan_info::key_begin() noexcept { + return key_begin_; } + +[[nodiscard]] data::aligned_buffer & scan_info::key_end() noexcept { + return key_end_; +} +void scan_info::blen(std::size_t s) noexcept { + blen_ = s; +} +void scan_info::elen(std::size_t s) noexcept { + elen_ = s; +} +[[nodiscard]] std::string_view scan_info::begin_key() const noexcept{ + return {static_cast(key_begin_.data()), blen_}; +} +[[nodiscard]] std::string_view scan_info::end_key() const noexcept{ + return {static_cast(key_end_.data()), elen_}; +} +[[nodiscard]] kvs::end_point_kind scan_info::get_kind(bool use_secondary, kvs::end_point_kind endpoint) const noexcept { + if (use_secondary) { + if (endpoint == kvs::end_point_kind::inclusive) { + return kvs::end_point_kind::prefixed_inclusive; + } + if (endpoint == kvs::end_point_kind::exclusive) { + return kvs::end_point_kind::prefixed_exclusive; + } + } + return endpoint; +} +[[nodiscard]] kvs::end_point_kind scan_info::begin_kind(bool use_secondary) const noexcept{ + return get_kind(use_secondary, begin_endpoint_); +} +[[nodiscard]] kvs::end_point_kind scan_info::end_kind(bool use_secondary) const noexcept{ + return get_kind(use_secondary, end_endpoint_); +} + +[[nodiscard]] status scan_info::status_result() const noexcept{ + return status_result_; +} +void scan_info::status_result(status s) noexcept{ + status_result_ = s; +} + +} // namespace jogasaki::executor::process::impl diff --git a/src/jogasaki/executor/process/impl/scan_info.h b/src/jogasaki/executor/process/impl/scan_info.h index 824d84bc2..cdc4240a5 100644 --- a/src/jogasaki/executor/process/impl/scan_info.h +++ b/src/jogasaki/executor/process/impl/scan_info.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 Project Tsurugi. + * Copyright 2018-2024 Project Tsurugi. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -50,14 +51,28 @@ class scan_info : public abstract::scan_info { [[nodiscard]] std::vector const& end_columns() const noexcept; [[nodiscard]] kvs::end_point_kind begin_endpoint() const noexcept; [[nodiscard]] kvs::end_point_kind end_endpoint() const noexcept; + [[nodiscard]] data::aligned_buffer & key_begin() noexcept; + [[nodiscard]] data::aligned_buffer & key_end() noexcept; + void blen(std::size_t s) noexcept; + void elen(std::size_t s) noexcept; + [[nodiscard]] std::string_view begin_key() const noexcept; + [[nodiscard]] std::string_view end_key() const noexcept; + [[nodiscard]] kvs::end_point_kind begin_kind(bool use_secondary) const noexcept; + [[nodiscard]] kvs::end_point_kind end_kind(bool use_secondary) const noexcept; + [[nodiscard]] status status_result() const noexcept; + void status_result(status s) noexcept; private: std::vector begin_columns_{}; kvs::end_point_kind begin_endpoint_{}; std::vector end_columns_{}; kvs::end_point_kind end_endpoint_{}; + data::aligned_buffer key_begin_{}; + data::aligned_buffer key_end_{}; + std::size_t blen_{}; + std::size_t elen_{}; + status status_result_{}; + [[nodiscard]] kvs::end_point_kind get_kind(bool use_secondary, kvs::end_point_kind endpoint) const noexcept; }; -} - - +} // namespace jogasaki::executor::process::impl diff --git a/src/jogasaki/executor/process/impl/task_context.cpp b/src/jogasaki/executor/process/impl/task_context.cpp index 21fec4c4a..f4f243240 100644 --- a/src/jogasaki/executor/process/impl/task_context.cpp +++ b/src/jogasaki/executor/process/impl/task_context.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 Project Tsurugi. + * Copyright 2018-2024 Project Tsurugi. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,8 @@ #include #include +#include +#include #include #include #include @@ -132,4 +134,53 @@ io::record_channel* task_context::channel() const noexcept { return channel_; } +impl::work_context& task_context::getImplWorkContext() const { + return *dynamic_cast(work_context()); } + +void task_context::encode_key() noexcept { + std::size_t blen{}; + std::string msg{}; + executor::process::impl::variable_table vars{}; + if(auto res = impl::ops::details::encode_key( + request_context_, + scan_info_->begin_columns(), + vars, + *getImplWorkContext().varlen_resource(), + scan_info_->key_begin(), + blen, + msg + ); + res != status::ok) { + if(res == status::err_type_mismatch) { + // only on err_type_mismatch, msg is filled with error message. use it to create the error info in request context + set_error(*request_context_, error_code::unsupported_runtime_feature_exception, msg, res); + } + scan_info_->status_result(res); + return; + } + scan_info_->blen(blen); + std::size_t elen{}; + if(auto res = impl::ops::details::encode_key( + request_context_, + scan_info_->end_columns(), + vars, + *getImplWorkContext().varlen_resource(), + scan_info_->key_end(), + elen, + msg + ); + res != status::ok) { + if(res == status::err_type_mismatch) { + // only on err_type_mismatch, msg is filled with error message. use it to create the error info in request context + set_error(*request_context_, error_code::unsupported_runtime_feature_exception, msg, res); + } + scan_info_->status_result(res); + return; + } + scan_info_->elen(elen); + scan_info_->status_result(status::ok); + return; +} + +} // namespace jogasaki::executor::process::impl diff --git a/src/jogasaki/executor/process/impl/task_context.h b/src/jogasaki/executor/process/impl/task_context.h index b05eef24b..4c7d8e84c 100644 --- a/src/jogasaki/executor/process/impl/task_context.h +++ b/src/jogasaki/executor/process/impl/task_context.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 Project Tsurugi. + * Copyright 2018-2024 Project Tsurugi. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,10 @@ class task_context : public abstract::task_context { void deactivate_writer(writer_index idx) override; + impl::work_context& getImplWorkContext() const; + + void encode_key() noexcept; + private: request_context* request_context_{}; std::size_t partition_{}; @@ -92,8 +97,7 @@ class task_context : public abstract::task_context { io::record_channel* channel_{}; std::shared_ptr external_writer_{}; partition_index sink_index_{}; + status status_result_{}; }; -} - - +} // namespace jogasaki::executor::process::impl diff --git a/src/jogasaki/serializer/value_writer.h b/src/jogasaki/serializer/value_writer.h index 410f39757..d76610004 100644 --- a/src/jogasaki/serializer/value_writer.h +++ b/src/jogasaki/serializer/value_writer.h @@ -25,7 +25,7 @@ class value_writer { /// @brief Size the size type represents the number of bytes to write. using size_type = Size; - + /// @brief the result type of `T::write(char const*, size_type)`. using result_type = decltype( std::declval().write(