btree index (19)

_bt_relandgetbuf

obufに指定したBufferのロックを開放してから,blknoで指定したBufferのロックを取得する。

_bt_get_endpoint

指定したlevelの右端か左端のページを取得する。rightmostをtrueに指定したら右端を取得する。leaf pageを取得するときはfast rootから検索を開始する。それ以外はtrue rootから検索を開始している。

     if (level == 0)
         buf = _bt_getroot(rel, BT_READ);
     else
         buf = _bt_gettrueroot(rel);

_bt_new_root

rootページを分割したとき,新しいroot pageを作成する。
(1)_bt_getbufで新しいroot pageを作成する
(2)meta pageをwrite lock
(3)root pageのBTPageOpaqueを設定
(4)meta pageに新しいroot pageの位置を登録
(5)root pageに左のページ(元のroot page)を登録
(6)root pageに右のページ(新しく作成されたページ)を登録
(7)ログレコードを出力
(8)_bt_wrtbufでmeta pageをwriteする

_bt_getstackbuf

stack->bts_btitemのアイテムを探す。stack->bts_blkno, bts_offsetから検索を開始し,アイテムが見つかったらstack->bts_blkno, bts_offsetにセットする。stack->bts_offsetに有効な値が設定されていたら,最初のページのbts_offsetの位置から右に向かって探す。そのページの右側に見つからなかったら,今度はbts_offsetから左に向かって探す。最初のページに見つからなかったら,右のページに移動していく。

_bt_insert_parent

ページを分割した後,新しいページ(右のページ)を親のページに登録する。
root pageの分割の場合,_bt_new_rootで処理する。root pageではない場合,以下の処理を行う。
(1)stackがNULLの場合,_bt_get_endpointで親のレベルの一番左のページを取得する。stackがNULLになるのはWAL replayのとき。
(2)左のページのhigh keyを使って,親ページに登録するアイテムを作成する。
(ページを分割したときは,左のページのhigh keyと右のページの一番小さいアイテムは同じになっている)
(3)_bt_getstackbufで親ページの登録する場所を探す。
(4)左右のページをwriteする。
(5)_bt_insertonpgで親ページに登録する。

_bt_isequal

ItemがScanKeyと一致するか調べる。_bt_compareよりもNULLの扱いがシンプルになっている。

_bt_pgaddtup

ページにBTItemを登録する。登録処理はPageAddItemを実行して登録している。
リーフページ以外の最初のアイテムのデータは,検索するときにマイナス∞として扱われるため,データの部分を削除して登録する。

    if (!P_ISLEAF(opaque) && itup_off == P_FIRSTDATAKEY(opaque))
    {
        memcpy(&truncitem, btitem, sizeof(BTItemData));
        truncitem.bti_itup.t_info = sizeof(BTItemData);
        btitem = &truncitem;
        itemsize = sizeof(BTItemData);
    }