|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.70 2000/12/03 10:27:26 vadim Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.71 2000/12/28 13:00:07 vadim Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -520,39 +520,40 @@ _bt_insertonpg(Relation rel,
|
520 | 520 | {
|
521 | 521 | /* XLOG stuff */
|
522 | 522 | {
|
523 |
| - char xlbuf[sizeof(xl_btree_insert) + |
524 |
| - sizeof(CommandId) + sizeof(RelFileNode)]; |
525 |
| - xl_btree_insert *xlrec = (xl_btree_insert*)xlbuf; |
526 |
| - int hsize = SizeOfBtreeInsert; |
527 |
| - BTItemData truncitem; |
528 |
| - BTItem xlitem = btitem; |
529 |
| - Size xlsize = IndexTupleDSize(btitem->bti_itup) + |
530 |
| - (sizeof(BTItemData) - sizeof(IndexTupleData)); |
| 523 | + xl_btree_insert xlrec; |
| 524 | + uint8 flag = XLOG_BTREE_INSERT; |
531 | 525 | XLogRecPtr recptr;
|
| 526 | + XLogRecData rdata[2]; |
532 | 527 |
|
533 |
| - xlrec->target.node = rel->rd_node; |
534 |
| - ItemPointerSet(&(xlrec->target.tid), BufferGetBlockNumber(buf), newitemoff); |
535 |
| - if (P_ISLEAF(lpageop)) |
536 |
| - { |
537 |
| - CommandId cid = GetCurrentCommandId(); |
538 |
| - memcpy(xlbuf + hsize, &cid, sizeof(CommandId)); |
539 |
| - hsize += sizeof(CommandId); |
540 |
| - memcpy(xlbuf + hsize, &(_xlheapRel->rd_node), sizeof(RelFileNode)); |
541 |
| - hsize += sizeof(RelFileNode); |
542 |
| - } |
543 |
| - /* |
544 |
| - * Read comments in _bt_pgaddtup |
545 |
| - */ |
546 |
| - else if (newitemoff == P_FIRSTDATAKEY(lpageop)) |
| 528 | + xlrec.target.node = rel->rd_node; |
| 529 | + ItemPointerSet(&(xlrec.target.tid), BufferGetBlockNumber(buf), newitemoff); |
| 530 | + rdata[0].buffer = InvalidBuffer; |
| 531 | + rdata[0].data = (char*)&xlrec; |
| 532 | + rdata[0].len = SizeOfBtreeInsert; |
| 533 | + rdata[0].next = &(rdata[1]); |
| 534 | + |
| 535 | + /* Read comments in _bt_pgaddtup */ |
| 536 | + if (!(P_ISLEAF(lpageop)) && newitemoff == P_FIRSTDATAKEY(lpageop)) |
547 | 537 | {
|
548 |
| - truncitem = *btitem; |
| 538 | + BTItemData truncitem = *btitem; |
| 539 | + |
549 | 540 | truncitem.bti_itup.t_info = sizeof(BTItemData);
|
550 |
| - xlitem = &truncitem; |
551 |
| - xlsize = sizeof(BTItemData); |
| 541 | + rdata[1].data = (char*)&truncitem; |
| 542 | + rdata[1].len = sizeof(BTItemData); |
| 543 | + } |
| 544 | + else |
| 545 | + { |
| 546 | + rdata[1].data = (char*)btitem; |
| 547 | + rdata[1].len = IndexTupleDSize(btitem->bti_itup) + |
| 548 | + (sizeof(BTItemData) - sizeof(IndexTupleData)); |
552 | 549 | }
|
| 550 | + rdata[1].buffer = buf; |
| 551 | + rdata[1].next = NULL; |
553 | 552 |
|
554 |
| - recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_INSERT, |
555 |
| - xlbuf, hsize, (char*) xlitem, xlsize); |
| 553 | + if (P_ISLEAF(lpageop)) |
| 554 | + flag |= XLOG_BTREE_LEAF; |
| 555 | + |
| 556 | + recptr = XLogInsert(RM_BTREE_ID, flag, rdata); |
556 | 557 |
|
557 | 558 | PageSetLSN(page, recptr);
|
558 | 559 | PageSetSUI(page, ThisStartUpID);
|
@@ -774,71 +775,63 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
|
774 | 775 | */
|
775 | 776 | START_CRIT_CODE;
|
776 | 777 | {
|
777 |
| - char xlbuf[sizeof(xl_btree_split) + |
778 |
| - sizeof(CommandId) + sizeof(RelFileNode) + BLCKSZ]; |
779 |
| - xl_btree_split *xlrec = (xl_btree_split*) xlbuf; |
780 |
| - int hsize = SizeOfBtreeSplit; |
781 |
| - int flag = (newitemonleft) ? |
782 |
| - XLOG_BTREE_SPLEFT : XLOG_BTREE_SPLIT; |
783 |
| - BlockNumber blkno; |
784 |
| - XLogRecPtr recptr; |
785 |
| - |
786 |
| - xlrec->target.node = rel->rd_node; |
787 |
| - ItemPointerSet(&(xlrec->target.tid), *itup_blkno, *itup_off); |
788 |
| - if (P_ISLEAF(lopaque)) |
789 |
| - { |
790 |
| - CommandId cid = GetCurrentCommandId(); |
791 |
| - memcpy(xlbuf + hsize, &cid, sizeof(CommandId)); |
792 |
| - hsize += sizeof(CommandId); |
793 |
| - memcpy(xlbuf + hsize, &(_xlheapRel->rd_node), sizeof(RelFileNode)); |
794 |
| - hsize += sizeof(RelFileNode); |
795 |
| - } |
796 |
| - else |
797 |
| - { |
798 |
| - Size itemsz = IndexTupleDSize(lhikey->bti_itup) + |
799 |
| - (sizeof(BTItemData) - sizeof(IndexTupleData)); |
800 |
| - memcpy(xlbuf + hsize, (char*) lhikey, itemsz); |
801 |
| - hsize += itemsz; |
802 |
| - } |
| 778 | + xl_btree_split xlrec; |
| 779 | + int flag = (newitemonleft) ? |
| 780 | + XLOG_BTREE_SPLEFT : XLOG_BTREE_SPLIT; |
| 781 | + BlockNumber blkno; |
| 782 | + XLogRecPtr recptr; |
| 783 | + XLogRecData rdata[4]; |
| 784 | + |
| 785 | + xlrec.target.node = rel->rd_node; |
| 786 | + ItemPointerSet(&(xlrec.target.tid), *itup_blkno, *itup_off); |
803 | 787 | if (newitemonleft)
|
804 | 788 | {
|
805 |
| - /* |
806 |
| - * Read comments in _bt_pgaddtup. |
807 |
| - * Actually, seems that in non-leaf splits newitem shouldn't |
808 |
| - * go to first data key position on left page. |
809 |
| - */ |
810 |
| - if (! P_ISLEAF(lopaque) && *itup_off == P_FIRSTDATAKEY(lopaque)) |
811 |
| - { |
812 |
| - BTItemData truncitem = *newitem; |
813 |
| - truncitem.bti_itup.t_info = sizeof(BTItemData); |
814 |
| - memcpy(xlbuf + hsize, &truncitem, sizeof(BTItemData)); |
815 |
| - hsize += sizeof(BTItemData); |
816 |
| - } |
817 |
| - else |
818 |
| - { |
819 |
| - Size itemsz = IndexTupleDSize(newitem->bti_itup) + |
820 |
| - (sizeof(BTItemData) - sizeof(IndexTupleData)); |
821 |
| - memcpy(xlbuf + hsize, (char*) newitem, itemsz); |
822 |
| - hsize += itemsz; |
823 |
| - } |
824 | 789 | blkno = BufferGetBlockNumber(rbuf);
|
825 |
| - BlockIdSet(&(xlrec->otherblk), blkno); |
| 790 | + BlockIdSet(&(xlrec.otherblk), blkno); |
826 | 791 | }
|
827 | 792 | else
|
828 | 793 | {
|
829 | 794 | blkno = BufferGetBlockNumber(buf);
|
830 |
| - BlockIdSet(&(xlrec->otherblk), blkno); |
| 795 | + BlockIdSet(&(xlrec.otherblk), blkno); |
831 | 796 | }
|
832 |
| - |
833 |
| - BlockIdSet(&(xlrec->rightblk), ropaque->btpo_next); |
834 |
| - |
| 797 | + BlockIdSet(&(xlrec.parentblk), lopaque->btpo_parent); |
| 798 | + BlockIdSet(&(xlrec.leftblk), lopaque->btpo_prev); |
| 799 | + BlockIdSet(&(xlrec.rightblk), ropaque->btpo_next); |
835 | 800 | /*
|
836 | 801 | * Dirrect access to page is not good but faster - we should
|
837 | 802 | * implement some new func in page API.
|
838 | 803 | */
|
839 |
| - recptr = XLogInsert(RM_BTREE_ID, flag, xlbuf, |
840 |
| - hsize, (char*)rightpage + ((PageHeader) rightpage)->pd_upper, |
841 |
| - ((PageHeader) rightpage)->pd_special - ((PageHeader) rightpage)->pd_upper); |
| 804 | + xlrec.leftlen = ((PageHeader)leftpage)->pd_special - |
| 805 | + ((PageHeader)leftpage)->pd_upper; |
| 806 | + rdata[0].buffer = InvalidBuffer; |
| 807 | + rdata[0].data = (char*)&xlrec; |
| 808 | + rdata[0].len = SizeOfBtreeSplit; |
| 809 | + rdata[0].next = &(rdata[1]); |
| 810 | + |
| 811 | + rdata[1].buffer = InvalidBuffer; |
| 812 | + rdata[1].data = (char*)leftpage + ((PageHeader)leftpage)->pd_upper; |
| 813 | + rdata[1].len = xlrec.leftlen; |
| 814 | + rdata[1].next = &(rdata[2]); |
| 815 | + |
| 816 | + rdata[2].buffer = InvalidBuffer; |
| 817 | + rdata[2].data = (char*)rightpage + ((PageHeader)rightpage)->pd_upper; |
| 818 | + rdata[2].len = ((PageHeader)rightpage)->pd_special - |
| 819 | + ((PageHeader)rightpage)->pd_upper; |
| 820 | + rdata[2].next = NULL; |
| 821 | + |
| 822 | + if (!P_RIGHTMOST(ropaque)) |
| 823 | + { |
| 824 | + rdata[2].next = &(rdata[3]); |
| 825 | + rdata[3].buffer = sbuf; |
| 826 | + rdata[3].data = NULL; |
| 827 | + rdata[3].len = 0; |
| 828 | + rdata[3].next = NULL; |
| 829 | + } |
| 830 | + |
| 831 | + if (P_ISLEAF(lopaque)) |
| 832 | + flag |= XLOG_BTREE_LEAF; |
| 833 | + |
| 834 | + recptr = XLogInsert(RM_BTREE_ID, flag, rdata); |
842 | 835 |
|
843 | 836 | PageSetLSN(leftpage, recptr);
|
844 | 837 | PageSetSUI(leftpage, ThisStartUpID);
|
@@ -1143,25 +1136,29 @@ _bt_getstackbuf(Relation rel, BTStack stack)
|
1143 | 1136 | void
|
1144 | 1137 | _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
|
1145 | 1138 | {
|
1146 |
| - Buffer rootbuf; |
1147 |
| - Page lpage, |
1148 |
| - rpage, |
1149 |
| - rootpage; |
1150 |
| - BlockNumber lbkno, |
1151 |
| - rbkno; |
1152 |
| - BlockNumber rootblknum; |
1153 |
| - BTPageOpaque rootopaque; |
1154 |
| - ItemId itemid; |
1155 |
| - BTItem item; |
1156 |
| - Size itemsz; |
1157 |
| - BTItem new_item; |
1158 |
| - Buffer metabuf; |
| 1139 | + Buffer rootbuf; |
| 1140 | + Page lpage, |
| 1141 | + rpage, |
| 1142 | + rootpage; |
| 1143 | + BlockNumber lbkno, |
| 1144 | + rbkno; |
| 1145 | + BlockNumber rootblknum; |
| 1146 | + BTPageOpaque rootopaque; |
| 1147 | + ItemId itemid; |
| 1148 | + BTItem item; |
| 1149 | + Size itemsz; |
| 1150 | + BTItem new_item; |
| 1151 | + Buffer metabuf; |
| 1152 | + Page metapg; |
| 1153 | + BTMetaPageData *metad; |
1159 | 1154 |
|
1160 | 1155 | /* get a new root page */
|
1161 | 1156 | rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
|
1162 | 1157 | rootpage = BufferGetPage(rootbuf);
|
1163 | 1158 | rootblknum = BufferGetBlockNumber(rootbuf);
|
1164 |
| - metabuf = _bt_getbuf(rel, BTREE_METAPAGE,BT_WRITE); |
| 1159 | + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE); |
| 1160 | + metapg = BufferGetPage(metabuf); |
| 1161 | + metad = BTPageGetMeta(metapg); |
1165 | 1162 |
|
1166 | 1163 | /* NO ELOG(ERROR) from here till newroot op is logged */
|
1167 | 1164 | START_CRIT_CODE;
|
@@ -1222,39 +1219,46 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
|
1222 | 1219 | elog(STOP, "btree: failed to add rightkey to new root page");
|
1223 | 1220 | pfree(new_item);
|
1224 | 1221 |
|
| 1222 | + metad->btm_root = rootblknum; |
| 1223 | + (metad->btm_level)++; |
| 1224 | + |
1225 | 1225 | /* XLOG stuff */
|
1226 | 1226 | {
|
1227 | 1227 | xl_btree_newroot xlrec;
|
1228 |
| - Page metapg = BufferGetPage(metabuf); |
1229 |
| - BTMetaPageData *metad = BTPageGetMeta(metapg); |
1230 | 1228 | XLogRecPtr recptr;
|
| 1229 | + XLogRecData rdata[2]; |
1231 | 1230 |
|
1232 | 1231 | xlrec.node = rel->rd_node;
|
| 1232 | + xlrec.level = metad->btm_level; |
1233 | 1233 | BlockIdSet(&(xlrec.rootblk), rootblknum);
|
| 1234 | + rdata[0].buffer = InvalidBuffer; |
| 1235 | + rdata[0].data = (char*)&xlrec; |
| 1236 | + rdata[0].len = SizeOfBtreeNewroot; |
| 1237 | + rdata[0].next = &(rdata[1]); |
1234 | 1238 |
|
1235 | 1239 | /*
|
1236 | 1240 | * Dirrect access to page is not good but faster - we should
|
1237 | 1241 | * implement some new func in page API.
|
1238 | 1242 | */
|
1239 |
| - recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_NEWROOT, |
1240 |
| - (char*)&xlrec, SizeOfBtreeNewroot, |
1241 |
| - (char*)rootpage + ((PageHeader) rootpage)->pd_upper, |
1242 |
| - ((PageHeader) rootpage)->pd_special - ((PageHeader) rootpage)->pd_upper); |
| 1243 | + rdata[1].buffer = InvalidBuffer; |
| 1244 | + rdata[1].data = (char*)rootpage + ((PageHeader) rootpage)->pd_upper; |
| 1245 | + rdata[1].len = ((PageHeader)rootpage)->pd_special - |
| 1246 | + ((PageHeader)rootpage)->pd_upper; |
| 1247 | + rdata[1].next = NULL; |
1243 | 1248 |
|
1244 |
| - metad->btm_root = rootblknum; |
1245 |
| - (metad->btm_level)++; |
| 1249 | + recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_NEWROOT, rdata); |
1246 | 1250 |
|
1247 | 1251 | PageSetLSN(rootpage, recptr);
|
1248 | 1252 | PageSetSUI(rootpage, ThisStartUpID);
|
1249 | 1253 | PageSetLSN(metapg, recptr);
|
1250 | 1254 | PageSetSUI(metapg, ThisStartUpID);
|
1251 | 1255 |
|
1252 |
| - _bt_wrtbuf(rel, metabuf); |
1253 | 1256 | }
|
1254 | 1257 | END_CRIT_CODE;
|
1255 | 1258 |
|
1256 | 1259 | /* write and let go of the new root buffer */
|
1257 | 1260 | _bt_wrtbuf(rel, rootbuf);
|
| 1261 | + _bt_wrtbuf(rel, metabuf); |
1258 | 1262 |
|
1259 | 1263 | /* update and release new sibling, and finally the old root */
|
1260 | 1264 | _bt_wrtbuf(rel, rbuf);
|
|
0 commit comments