btree index (2)
_bt_doinsert
btreeへBTItemを登録する。public interfaceのbtbuildやbtinsertから実行される。
(1)_bt_mkscankeyでインデックスのデータを比較するためのScanKeyを生成する
(2)_bt_searchでBTItemを登録する,先頭のリーフページを取得する
(3)Read lockを開放して,Write lockを取得する
(4)Read lock開放後,Write lockを取得する前にページが分割されたかもしれないので,_bt_moverightで正しいページに移動する
(5)unique indexの場合,_bt_check_uniqueでチェック
(6)_bt_insertonpgで登録する。
_bt_search
ScanKeyで指定したキーが登録されているべきリーフページを検索する。
_bt_searchではキーがあるとしたらこのページというところまで調べるが,ページ内にキーが存在するかどうかまでは調べない。
rootページから検索を開始し,_bt_binsrchで次の階層のページを探しながら,リーフページまで進んでいく。次の階層へ進むたびに現在のページの情報をstack_inへ登録していく。
stackはリンクリストで表現されており,リーフページにたどりついたときに,リーフページからrootまでのページの情報(ブロックIDなど)が登録されている。
_bt_searchはこのstackを戻り値として返す。また,bufPにはリーフページが設定されている。
Indexのデータ登録でページが満杯だったときはページを分割し,親ページに新しいページを登録する必要があり,さらにこの親のページが満杯だったら親の親のページを更新する必要があるため,rootまでたぐっていけるようになっている。
Indexの検索(_bt_first)ではstackの情報は不要で,_bt_search実行直後にstackを開放している。
/* * Use the manufactured scan key to descend the tree and position * ourselves on the target leaf page. */ stack = _bt_search(rel, keysCount, scankeys, nextkey, &buf, BT_READ); /* don't need to keep the stack around... */ _bt_freestack(stack);
_bt_searchをコピーして、stackを作成しないバージョンを作ったほうがいいのかもしれない。