【Red Data Tools開発者に聞け!】第15回目の振り返り記事になります。
今回から each_raw_record
の実装に入っていきます!実装の参考となるように既存のソースコードを読みながら、C++ でのクラスやメソッドの実装はどのように行われるか?を中心に学んでいきます!
今回主に触れるソースコードは以下になります。お手元で併せて読んで頂けると理解が深まるのではないかと思います。
yield を実装する
each_raw_record
では引数としてブロックを受け取り、各要素に対して逐次ブロックを呼び出した結果を返すメソッドとして実装します。
そのためには ruby だったら yield
を呼び出せばいいですが、Ruby の C API を利用する場合は rb_yield
をコールします。
Ruby C API には ruby のメソッドに rb_
の prefix をつけたインターフェースが多く用意されているので、実装の際にはこの規則に従ってメソッドを探してみると良いかもしれません。
C++ のコンストラクタ
新しく実装するメソッドの参考にするために、既存の table_raw_records
を読んでいきます。このメソッドにおいて Arrow::Table
から ruby の Array
への変換を実際に行なっているのは以下の部分になります。
RawRecordsBuilder builder(records, n_columns);
builder.build(*table);
まず初めに RawRecordsBuilder
オブジェクトを生成しています。このクラスの定義を見ていきましょう。
class RawRecordsBuilder : private Converter, public arrow::ArrayVisitor {
public:
explicit RawRecordsBuilder(VALUE records, int n_columns)
: Converter(),
records_(records),
n_columns_(n_columns) {
}
↑のコードがこのクラスのコンストラクタになっています。3行目の部分で初期化変数を定義します。このクラスは records
, n_columns
として2つの初期化変数を受け取ることができます。
5~6 行目ではクラスのメンバ変数を宣言しています。このクラスは records_
, n_columns_
の2つのメンバを持っています。また、records_(records)
のように書くことでメンバの定義をするとともに、その値の初期化を行うことができます。
C++ のメソッド定義とオーバーロード
次に table_raw_records
内でコールされている RawRecordsBuilder
のメソッド、 build
の実装を見ていきましょう。C++ では返り値の型、メソッド名、引数の順に指定してメソッドを定義を行います。
void build(const arrow::RecordBatch& record_batch) {
//...
}
void build(const arrow::Table& table) {
//...
}
RawRecordsBuilder
クラスには2つの build
メソッドが定義されています。C++ ではメソッドのオーバーロードが可能です。
先に挙げた build
メソッドは引数に RecordBatch
クラスの引数を与えた場合に実行され、もう一方は Table
クラスの引数を与えた場合に実行されます。
配列の生成
build
メソッドの実装を見ていきましょう。
このメソッドで初めに行っているのは ruby の Array
を生成する処理です。
const auto n_rows = table.num_rows();
for (int64_t i = 0; i < n_rows; ++i) {
auto record = rb_ary_new_capa(n_columns_);
rb_ary_push(records_, record);
}
rb_ary_new_capa
で Array
を生成することができます。このメソッドは整数型の引数を受け取って、コンパイル時にあらかじめ指定された数値の長さのメモリ領域を確保して配列を生成します。このような配列を静的配列と言います。
逆にプログラムの実行時に長さを伸び縮みできるように宣言した配列を動的配列と言います。静的配列の方が実行速度が速く、また動的配列は実行時にメモリが割り当てられなくなる危険性があるため大きなデータは扱いずらいという欠点があります。
もし、あらかじめ配列の長さがわかっているケースでは今回のように静的配列を生成した方が良いです。
次回
次回も build
メソッドの実装を読み進めていきます。有名なデザインパターンの一つである Visitor
パターンの解説にも入っていきますので、引き続き動画のチェックしてみてもらえたらと思います!
コメント