btree index (3)

_bt_insertonpg

指定したページにBTItemを登録する。
non-unique indexで重複したキーを登録する場合,以下のルールで登録する場所を決めている。

(1)指定したページに登録できる場合:同じキーの先頭に挿入する。(新しく登録するアイテムが先頭になる)

(2)指定したページの空き容量が足りず,ページのhigh keyとアイテムのキーが違う場合:ページを分割して登録する。

(3)指定したページの空き容量が足りず,ページのhigh keyとアイテムのキーが同じ場合:空き容量があるページが見つかるまで,右のページを探していく。
ただし空き容量が見つかる前に,high keyとアイテムのキーが違ったら,そこに登録しなければならないので,ページを分割する。また,high keyとアイテムのキーが一致していても,乱数で100分の1の確率で右のページに進むのをやめて,そこでページを分割する。重複するキーが非常に多い場合は一番右のページまで進むのに時間がかかるため,乱数で適当に止めている。

    while (PageGetFreeSpace(page) < itemsz &&
           !P_RIGHTMOST(lpageop) &&
           _bt_compare(rel, keysz, scankey, page, P_HIKEY) == 0 &&
           random() > (MAX_RANDOM_VALUE / 100))

リーフページのhigh keyについて

リーフページには,そのページで管理する最大のキーが登録されている(high keyと呼ばれる)。high keyはページ内のアイテムの最大の値または,それよりも大きい値が登録されている。
OffsetにP_HIKEYを指定すると,high keyにアクセスできる。

    itemid = PageGetItemId(origpage, P_HIKEY);
    itemsz = ItemIdGetLength(itemid);
    item = (BTItem) PageGetItem(origpage, itemid);