まとめて、そのサイズを返します。「"piyo","hugahuga"\n」を格納し、その終端を表すためにサイズを返すのがこの関数のゴールです。カラム情報を読み取るためのフラグを立てています。変数から情報を取得する際にアサーションで落ちてしまいます。それぞれの値が格納されてきます。入ってくるイメージです。ループを回してそれぞれのカラムを処理していきます。格納されている値は末尾に大量のスペースが入っていることです。実際の値なのか判断する必要があります。挿入すべき文字列の長さ(=文字列の終端)を格納しています。ループの終了条件になります。「"piyo","hugahuga"\n」という文字列が格納されます。文字列が追記されているはずです。処理は実装できました。テーブルスキャンテーブルの作成やオープンはそれぞれに対応する関数を一つ実装するだけでしたが、テーブルスキャンでは複数の関数の実装が必要になります。ストレージエンジンが5行取得する際の関数コールの流れですが、眺めてみるとなんとなくテーブルスキャンの流れを掴めると思います。openつまり実装が必要なのは、store_lock()内部ロックexternal_lock()外部ロックなどinfo()最適化情報の設定rnd_init()テーブルスキャンの準備extra()ヒントの設定rnd_next()行の読み取りの6つです。サーバがロックを取得しようとした時に呼び出される関数です。呼び出すことで、ストレージエンジン側にもロックの裁量を与えているみたいです。サーバ側で判断したロック種別をストレージエンジンに合わせたものに変更できるようにしているみたいですが、今回は細かいロック機構を実装するつもりはありませんし、ぶっちゃけどんな状況でこのロックの変更が必要になるのか不明なので変更しないでおきます(一切ロックを提供しないストレージエンジンではここに何も書かないとかになりそう)。to;}external_lock()外部ロックのためのフックです。外部ロックは簡単に言えば、テーブルデータファイルへのファイルロックのことです。サーバが単一のデータファイルを弄る場合なんかで競合を回避するために外部ロックが必要になります。返すだけの実装でいきます。DBUG_RETURN(0);}rnd_init()テーブルスキャンのための準備をする関数です。データファイル内をトレースするためのポジション情報やレコード数情報を初期化しておきます。DBUG_RETURN(0);}ポジション情報はハンドラに持たせておきます。~~info()最適化のためにオプティマイザが使う統計情報などを設定する関数です。結果は、ここで設定された情報が基になっているようです。例によって細かい実装はしませんが、以下のコードだけ入れておきます。DBUG_RETURN(0);}コメントによればレコード数が0もしくは1の場合と、2以上の場合とで、オプティマイザの処理が変わるみたいで、前者だとテーブルスキャンの時に全部のレコードが読まれない可能性があるっぽいです(詳しいことはわかりません)。2以上の値を返しておく感じで。サーバ側からストレージエンジンの動作に対してヒントを送るための関数らしいですが、これも拡張的というか応用的な機能なのでスルーします。操作するファイルの種類に応じてスキャン動作を変えたりする時なんかに必要なのかもしれません。データファイルから実際にレコードを読み取る関数です。テーブルスキャンは、終了条件を満たすまでこいつが呼ばれ続ける形で行われます。イメージとしては、1行読み取る度に1回この関数が呼ばれる感じです。返して処理を終了してあげるのが正常な動作です。まで読んでいくだけの実装をしてみます。ファイルから読み取ったレコードを格納する先です。格納してもらい、結果をクライアントに返す形になっています。内では大枠の処理だけ書いています。先頭を0で埋めています。指示ビットマップだからです(カラムの内容はその後に続きます)。あることを明示するための仕組みです。このビットマップ部分をすべて0に設定しているわけです。0を埋めるサイズの指定にはこれを使います。指示とは関係のない開始ビットが付加されます。カラムを2つ用意した場合の挙動は以下のようになります。表現できるように実装する必要があります。書き込み用のフラグを立てることです。書き込むときにアサーションエラーになります。回します(カラム数文回ります)。いうメンバです(カラムデータのインメモリコピーと言えます)。同じ場所を指しています。格納しているコードが存在しないのはこのためです。扱っている形になります。格納しているだけの単純なものです。各行に対して呼ばれるので、複数行を読み取る場合には「現在どこの行まで読んだか」を記録しておく必要があります。管理していて、文字を読む度にカウントしています。以上が読み取り処理の実装になります。格納したデータがしっかりと返っくるはずです。ta_test;おわりということで、ストレージエンジンの基本的な入出力機能を一通り実装してみました。本格的にやろうとすると、ここから更にインデクシングやロッキングなどの高度な機能が必要になりますが、とりあえずこれだけでもストレージエンジンの概要はざっくりと掴めた気がします。謎のビルドエラーでハマったりして面倒臭さが強烈でしたが、気が向いたらその辺の機能もまた実装してみようかなあと思います。インフラパーティショニングについての覚書。先に具体的な実体を書いたあと、それがパフォーマンス向上にどう寄与するのかを書きます。簡単に言えば、データベースのテーブルを物理的に分割することです。テーブルのデータが分割されてしまっても、外からは論理的(透過的)に単一のテーブルとして見えます。レイヤはそれを意識する必要はありません。分割されたパーティションを表しています。サーバによって提供されています。ストレージエンジンは分割された各パーティションを独立したテーブルのように扱います。これを図にすると次のような感じになります。このため、例えばパーティショニングするテーブルにインデックスを張ると、各パーティションごとにインデックスが作られることになります。パーティショニングタイプで、どういう基準でテーブルをパーティションに分割するのかというと、これにはいろいろな方法があります。有名というか、例でよく使われるのは次のような範囲による分割です。このような分割基準はパーティショニングタイプと呼ばれます。日付を表現するカラムを基にパーティショニングをしているとします。このように、基本的なパーティショニングでは、特定のカラムをキーとして各レコードの配置先が決まります。パーティショニングに使うこのキーはパーティションキーと呼ばれます。パーティションキーを基に、どこのパーティションにレコードを配置するかを決定するのがパーティション関数です。範囲に基づくパーティショニング環境下で新たに行を挿入する場合、以下のようにパーティション関数が振り分け先を判断します。1月のレコードを挿入しようとしているので、パーティション関数によってそれが評価されて、1月用のパーティションへの挿入が決定されます。逆に言えば、このパーティション関数を変えればパーティション分割の基準を変えられるということです。ここでは範囲条件による分割を紹介しましたが、他にはハッシュを使ったものなどがあります。パーティショニングのメリットやデメリットパーティショニングの利点には幾らかありますが、ここではクエリ処理の高速化(レスポンスの向上)につながるものについて書いていきます。パーティショニングでは前述のように、テーブルをパーティションという単位に分割します。ここで、分割されたテーブルに問い合わせが発生したことを考えます。クエリの実行時になんの工夫もしないとすると、以下のようにすべてのパーティションを検索して特定のレコードを探し出すことになるでしょう。上のように検索条件が特定のパーティション内に閉じているのであれば、次のように、当該パーティションだけを検索するだけで済むはずです。検索する必要のないパーティションは検索しないに越したことありません。スキャンする行数が減れば、無駄な検索処理が減り、パフォーマンスが上がります。このような仕組みはすでに実装されていて、パーティションプルーニングと呼ばれています。いう感じで、パーティショニングによってスキャンの範囲を局所化できるケースでは、パフォーマンスを高められるのです。ちなみに、検索からどのパーティションを除外するのか、といった判断はオプティマイザが担当します。インデックスを効果的に使えるクエリであれば十分高速に検索できるので、あえてこの仕組みを使った高速化を図るまでもないかもしれません。サマリテーブルで対応できる場合なども、あえてパーティショニングを使う必要もないということで、レスポンス高速化面でのパーティショニングの使い所は限られてくるかもしれません。インデックスのカーディナリティが低いケースなど、テーブルスキャンが発生する場合には、検索範囲を局所化できるためパーティションプルーニングの効果は大きくなります。大規模なテーブル且つカラムのカーディナリティが低いといったインデックスを貼るのが現実的でないようなケースであれば特に、パーティショニングが簡易インデックスのような形で威力を発揮します。パーティションが増えれば増えるほどパーティションあたりのレコード数を減らせるので、プルーニングによる効果は大きくなります。プルーニングが発動しないケースではパーティション数が増えるほどオーバヘッドが大きくなります。キーの範囲によってパーティショニングしている場合の行の挿入時には、オプティマイザがどのパーティションに行を挿入するかを考えることになりますが、パーティションが多いとこの作業が大変になります。ネイティブパーティションが導入されておらず、分割されたそれぞれのパーティションに対してハンドラ(ストレージエンジンの抽象化レイヤ)が割り当てられていました。ネイティブパーティション機能が導入され、単一のハンドラで一元管理するようになっているのでこの問題は回避できる模様)。いうことで、パーティションは増え過ぎもよろしくないので、適度な数に抑えたほうが良さげです。コアが沢山あれば並列処理である程度はカバーできるかもしれませんが。句でパーティションキーが指定されないと発動しません。句を意図的に追加したり、パーティショニングが上手く効くように条件を書き換えたりしたほうがいいことがあります。それから、結合時のWHERE条件にパーティションキーが指定された時にもプルーニングは発動します。コストを抑えられます。プルーニングが効かなければ前述のようなマイナス面を喰らうだけなので、こんな感じでクエリを最適化した方がよさそうです。ICP(詳しくはこちらの記事で紹介しています)が効かず、プルーニングに失敗した場合のダメージが大きくなりそうなので、よく注意したほうがいいかもしれません(大量の行フェッチが発生する可能性があります)。おわりパーティショニングは他の技術と同様に、とりあえずやっておけば高速化できるというような銀の弾丸ではありません。その仕組みをある程度理解しておいて、適切な状況で活用することが大事ですね。言われているのは、パーティショニングが威力を発揮できる状況は主に超大規模なテーブルを扱う場合、ということです。結局のところ、パーティショニングによる高速化が成功するかどうかはテーブルの構造やレコード数といった要因だけでなく、クエリにも大きく依存します。パーティショニングを検討する場合にはクエリについてもよく分析すべきということですね。