-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move key_begin and key_end members from scan_context to scan_info #127
Conversation
scan_testまで貫通いたしましたのでレビューお願いいたします |
src/jogasaki/data/aligned_buffer.h
Outdated
@@ -162,6 +162,7 @@ class aligned_buffer { | |||
* @return the output | |||
*/ | |||
friend std::ostream& operator<<(std::ostream& out, aligned_buffer const& value); | |||
void dump(std::ostream& out, int indent = 0) const noexcept; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doc commentを追加してください。あと、friend関数の上に移動させてください。
@@ -43,7 +43,7 @@ processor::processor( | |||
std::shared_ptr<ops::io_info> io_info, | |||
std::shared_ptr<relation_io_map> relation_io_map, | |||
io_exchange_map& io_exchange_map, | |||
memory::lifo_paged_memory_resource* resource | |||
request_context* resource |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resource
という名前も変更してください。
@@ -176,6 +176,7 @@ class operator_test_utils { | |||
takatori::plan::process& process_; //NOLINT | |||
|
|||
memory::page_pool pool_{}; //NOLINT | |||
request_context request_context_{}; //NOLINT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
これって必要なのでしょうか?どこかで使っています?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
必要です
改造でscan::openでiterator関連の設定をしなくなった関係でscan_test.cppを通すためにscan_info::encode_key関数呼び出しが必要になりました。その関数の引数としてrequest_context_が必要です。
その代わり従来のmemory::lifo_paged_memory_resource resource_; //NOLINTが不要になっていましたがこちらは消し忘れなのでresource_は消します
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
了解。使っているのであればOKです。
@@ -123,6 +123,9 @@ io::record_writer* task_context::external_writer() { | |||
class abstract::scan_info const* task_context::scan_info() { | |||
return scan_info_.get(); | |||
} | |||
std::shared_ptr<impl::scan_info> task_context::non_const_impl_scan_info() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数名が少し仰々しいので shared_scan_info あたりでどうでしょうか。
返り値の型も std::shared_ptr<impl::scan_info> const&
にしてもらえますか。(コピーが不要な場合のために)
@@ -132,7 +130,7 @@ std::unique_ptr<operator_base> operator_builder::operator()(const relation::scan | |||
// scan info is not passed to scan operator here, but passed back through task_context | |||
// in order to support parallel scan in the future | |||
scan_info_ = create_scan_info(node, secondary_or_primary_index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
create_scan_infoにrequest_context_を渡してエンコードまでしてしまうほうがシンプルではないでしょうか。
scan_infoのbegin_columns_, end_columns_メンバはもう不要で除去してしまっていいように思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
了解しました。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ざっくりとですが、レビューしてコメントしました。
648b10e
to
1425b34
Compare
df4165d
to
0384c68
Compare
0384c68
to
1d1e828
Compare
@kuron99 対応しました |
@@ -90,7 +90,7 @@ class operator_builder { | |||
std::shared_ptr<io_info> io_info, | |||
std::shared_ptr<relation_io_map> relation_io_map, | |||
io_exchange_map& io_exchange_map, | |||
memory::lifo_paged_memory_resource* resource = nullptr | |||
request_context* request_context = nullptr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doc commentの @param
部分も一緒に修正お願いします。
); | ||
} | ||
|
||
std::shared_ptr<impl::scan_info> operator_builder::create_scan_info( | ||
relation::scan const& node, | ||
yugawara::storage::index const& index | ||
yugawara::storage::index const& index, | ||
std::unique_ptr<ops::context_base::memory_resource> varlen_resource, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここはrequest_contextのrequest_resource()で取れるものを使うというのではダメですか?requestをconstructするのに必要なmemory resourceはあまり大きくないはずなので、この目的のためにglobal poolからアサインするのはもったいない印象です。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scan_infoでbegin_key,end_keyを設定するためにjogasaki::executor::process::impl::ops::details::encode_keyを呼び出していますがこれの第一引数が request_context* contextなのでencode_keyを改造する必要があります。改造しますか?
expr::evaluator_context ctx{
std::addressof(resource),
context ? utils::make_function_context(*context->transaction()) : nullptr,
};
global poolにアサインしているのはこれまでの挙動を変えたくないからで flow::create_task_context下記コードに引っ張らています。
ctx->work_context(
std::make_unique<impl::work_context>(
context_,
operators.size(),
info_->vars_info_list().size(),
std::make_unique<memory::lifo_paged_memory_resource>(&global::page_pool()),
std::make_unique<memory::lifo_paged_memory_resource>(&global::page_pool()),
context_->database(),
context_->transaction(),
empty_input_from_shuffle_
)
);
今回ここは下記の通り、これまでと同じ状態を保つために少し面倒な改造を行っています。
auto scan = ctx->shared_scan_info();
ctx->work_context(
std::make_unique<impl::work_context>(
context_,
operators.size(),
info_->vars_info_list().size(),
std::make_unique<memory::lifo_paged_memory_resource>(&global::page_pool()),
(scan == nullptr)?std::make_unique<memory::lifo_paged_memory_resource>(&global::page_pool()):scan->varlen_resource(),
context_->database(),
context_->transaction(),
empty_input_from_shuffle_
)
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scan_infoでbegin_key,end_keyを設定するためにjogasaki::executor::process::impl::ops::details::encode_keyを呼び出していますがこれの第一引数が request_context* contextなのでencode_keyを改造する必要があります。改造しますか?
request_contextがGODオブジェクト化していてよくないのですが、いまのところ必要な場所にrequest_contextを渡すのはしょうがないかなと思っています。なので、request_contextをoperator_builder等にわたす点については問題ありません。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
global poolにアサインしているのはこれまでの挙動を変えたくないからで flow::create_task_context下記コードに引っ張らています。
うーん、なるほど、work_contextへmake_uniqueして渡しているのがタイミングが変わったので移動してきた感じですか。ただ一旦scan_infoへ渡して、引き剥がしてimpl::work_contextへ渡すのが迂遠な感じはありますね。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@YoshiakiNishimura work_contextのmemory resourceを使う必要はないと思うので、scan_infoを作成するのに使う必要がある場合は request_contextのrequest_resource() を使う、という方針にしましょう。
既存のコードはwork_contextが持つvarlen resourceを使っていました。これはprocess内のオペレータが並列化された際、その並列化単位の1個1個にアサインされたvarlen resourceで、並列で動く(可能性のある) scanの内部でエンコードを行うのでこれを使うしかありませんでした。
一方これからはscanの外部で並列化前にシングルスレッドで処理される部分(create_tasksやcreate_scan_info, operator_builderなど)でscan_infoを作ることになるので、ここではwork_contextのものを使う必要はなく、リクエスト全体で持っている(request_context::request_resource()で取得できる)ものをつかっていいと思います。
/** | ||
* @brief create new object | ||
*/ | ||
explicit scan_info( | ||
std::vector<ops::details::search_key_field_info> = {}, | ||
std::vector<ops::details::search_key_field_info> const& begin_columns = {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
このPRでなくてもいいのですが、下記のような形でstd::string_view経由でキーを渡すコンストラクタが必要になりそうなので追加しておいてもいいかもしれません。(スキャンするキー区間を外部で作成した際にscan_infoを作る用途)
std::vectorops::details::search_key_field_infoを受け取るコンストラクタはstd::string_view経由のコンストラクタに委譲できるとキレイですが、コンストラクタ内部で複数の変数にアクセスしたりすると難しいかもしれません。その場合は別々のコンストラクタでもいいと思います。
explicit scan_info(
std::string_view key_begin = {},
kvs::end_point_kind begin_endpoint = kvs::end_point_kind::unbound,
std::string_view key_end = {},
kvs::end_point_kind end_endpoint = kvs::end_point_kind::unbound,
std::unique_ptr<memory_resource> varlen_resource = nullptr,
request_context* request_context = nullptr
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
上記について、もう少し細かく考えました。
「scan_infoは純粋にスキャン区間をあらわすものとする」
「スキャン区間をstd::vector<search_key_field_info>で表していたのはやめ、(data::aligned_bufferを使って保存される) std::string_viewで表す」
というポリシーとし、scan外部でscan_infoを作成しやすくするべきと考えます。既存のコードはindexの構造に密になっていたのでsearch_key_field_infoでよかったのですが、今後は外部でキー分布等の情報だけからscan_infoを作ることになるのでなるべく余計な依存を持たず、純粋に区間を表すキーだけを保持するのがいいと思います。
そのため、エンコードしてキーを作る、という部分はscan_infoから分離してcreate_scan_info等に移動しましょう。そうすれば、コンストラクタはvarlen_resourceやrequest_contextを受け取らなくてよくなります。
エンコード中にエラーが起きた際にstatus_result_に詰めてscan実行時にチェックするというロジックもやめて、エンコードした部分からエラーを戻すようにしましょう。
processorのコンストラクタやoperator_builder内部で構造を構築している際にエラーが起きたときのエラー処理としてはimpl::compiler_exceptionを投げる、というやり方が可能です。下記のコードを参考にしてください。
jogasaki/src/jogasaki/executor/process/impl/ops/write_existing.cpp
Lines 411 to 412 in 1d1e828
throw_exception(plan::impl::compile_exception{ | |
create_error_info(error_code::restricted_operation_exception, msg, status::err_illegal_operation) |
yugawara::storage::index const& index | ||
yugawara::storage::index const& index, | ||
std::unique_ptr<ops::context_base::memory_resource> varlen_resource, | ||
request_context* request_context | ||
) { | ||
return std::make_shared<impl::scan_info>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
別のコメントでも述べましたが、この位置にエンコード処理を持ってくることを検討してもらえませんか。エンコードで使うためにここまではrequest_contextが必要ですが、scan_infoのコンストラクタにはrequest_context, varlen_resourceを渡さなくてすむと思っています。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kuron99
これは最初のようにscan_info->encode_key(request_context)という感じでエンコード処理を分離するという認識であってます?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
いえ、scan_infoからもエンコード処理を分離することを意図しています。scan_infoの外側でエンコードを行い、scan_infoは出来上がったものを受け取るだけにする形です。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
コメントしました。レビュー完了で一旦戻します。
https://github.com/project-tsurugi/tsurugi-issues/issues/991
#124 の続き
scan_context
以下のメンバーを取り除く
data::aligned_buffer key_begin_{};
data::aligned_buffer key_end_{};
scan_info
以下のメンバーを追加する
data::aligned_buffer key_begin_{};
data::aligned_buffer key_end_{};
std::size_t blen_{};
std::size_t elen_{};
status status_result_{};
std::unique_ptr<memory_resource> varlen_resource_{};
operator_builder::operator
配下で以下の設定を行う
data::aligned_buffer key_begin_{};
data::aligned_buffer key_end_{};
std::size_t blen_{};
std::size_t elen_{};
status status_result_{};
std::unique_ptr<memory_resource> varlen_resource_{};
scan::open
operator_builder::operatorに設定を移動するのでそれ以外の設定を残す