12
12
* Portions Copyright (c) 1994, Regents of the University of California
13
13
*
14
14
* IDENTIFICATION
15
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.64 2000/10/13 02:03:00 vadim Exp $
15
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.65 2000/10/13 12:05:20 vadim Exp $
16
16
*
17
17
*-------------------------------------------------------------------------
18
18
*/
@@ -837,7 +837,7 @@ static void btree_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
837
837
ItemPointerGetOffsetNumber (& (xlrec -> target .tid )),
838
838
(char * )xlrec + hsize ,
839
839
record -> xl_len - hsize ,
840
- & hnode ))
840
+ hnode ))
841
841
elog (STOP , "btree_insert_redo: failed to add item" );
842
842
843
843
PageSetLSN (page , lsn );
@@ -908,7 +908,7 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
908
908
else
909
909
{
910
910
/* Delete items related to new right sibling */
911
- _bt_thin_left_page (page , record );
911
+ _bt_fix_left_page (page , record , onleft );
912
912
913
913
if (onleft )
914
914
{
@@ -924,6 +924,13 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
924
924
memcpy (& hnode , (char * )xlrec + SizeOfBtreeSplit +
925
925
sizeof (CommandId ), sizeof (RelFileNode ));
926
926
}
927
+ else
928
+ {
929
+ memcpy (& btdata , (char * )xlrec + hsize , sizeof (BTItemData ));
930
+ itemsz = IndexTupleDSize (btdata .bti_itup ) +
931
+ (sizeof (BTItemData ) - sizeof (IndexTupleData ));
932
+ hsize += itemsz ;
933
+ }
927
934
928
935
memcpy (& btdata , (char * )xlrec + hsize , sizeof (BTItemData ));
929
936
itemsz = IndexTupleDSize (btdata .bti_itup ) +
@@ -933,7 +940,7 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
933
940
ItemPointerGetOffsetNumber (& (xlrec -> target .tid )),
934
941
(char * )xlrec + hsize ,
935
942
itemsz ,
936
- & hnode ))
943
+ hnode ))
937
944
elog (STOP , "btree_split_redo: failed to add item" );
938
945
}
939
946
else
@@ -994,6 +1001,13 @@ btree_xlog_split(bool redo, bool onleft, XLogRecPtr lsn, XLogRecord *record)
994
1001
pageop -> btpo_flags |= BTP_LEAF ;
995
1002
hsize += (sizeof (CommandId ) + sizeof (RelFileNode ));
996
1003
}
1004
+ else
1005
+ {
1006
+ memcpy (& btdata , (char * )xlrec + hsize , sizeof (BTItemData ));
1007
+ itemsz = IndexTupleDSize (btdata .bti_itup ) +
1008
+ (sizeof (BTItemData ) - sizeof (IndexTupleData ));
1009
+ hsize += itemsz ;
1010
+ }
997
1011
if (onleft ) /* skip target item */
998
1012
{
999
1013
memcpy (& btdata , (char * )xlrec + hsize , sizeof (BTItemData ));
@@ -1198,17 +1212,28 @@ _bt_del_item(Relation reln, Buffer buffer, BTItem btitem, bool insert,
1198
1212
{
1199
1213
char * xlrec = (char * ) XLogRecGetData (record );
1200
1214
Page page = (Page ) BufferGetPage (buffer );
1201
- BTPageOpaque pageop ;
1215
+ BTPageOpaque pageop = ( BTPageOpaque ) PageGetSpecialPointer ( page ) ;
1202
1216
BlockNumber blkno ;
1203
1217
OffsetNumber offno ;
1204
1218
ItemId lp ;
1219
+ BTItem item ;
1205
1220
1206
1221
for ( ; ; )
1207
1222
{
1208
- offno = _bt_find_btitem (page , btitem );
1209
- if (offno != InvalidOffsetNumber )
1223
+ OffsetNumber maxoff = PageGetMaxOffsetNumber (page );
1224
+
1225
+ for (offno = P_FIRSTDATAKEY (pageop );
1226
+ offno <= maxoff ;
1227
+ offno = OffsetNumberNext (offno ))
1228
+ {
1229
+ lp = PageGetItemId (page , offno );
1230
+ item = (BTItem ) PageGetItem (page , lp );
1231
+ if (BTItemSame (item , btitem ))
1232
+ break ;
1233
+ }
1234
+ if (offno <= maxoff )
1210
1235
break ;
1211
- pageop = ( BTPageOpaque ) PageGetSpecialPointer ( page ) ;
1236
+ offno = InvalidOffsetNumber ;
1212
1237
if (P_RIGHTMOST (pageop ))
1213
1238
break ;
1214
1239
blkno = pageop -> btpo_next ;
@@ -1221,6 +1246,7 @@ _bt_del_item(Relation reln, Buffer buffer, BTItem btitem, bool insert,
1221
1246
if (PageIsNew ((PageHeader ) page ))
1222
1247
elog (STOP , "btree_%s_undo: uninitialized right sibling" ,
1223
1248
(insert ) ? "insert" : "split" );
1249
+ pageop = (BTPageOpaque ) PageGetSpecialPointer (page );
1224
1250
if (XLByteLT (PageGetLSN (page ), lsn ))
1225
1251
break ;
1226
1252
}
@@ -1250,9 +1276,9 @@ _bt_del_item(Relation reln, Buffer buffer, BTItem btitem, bool insert,
1250
1276
1251
1277
memcpy (& cid , (char * )xlrec + hsize , sizeof (CommandId ));
1252
1278
memcpy (& hnode , (char * )xlrec + hsize + sizeof (CommandId ), sizeof (RelFileNode ));
1253
- result = XLogCheckHeapTuple (hnode , & (btitem -> bti_itup .t_tid ),
1279
+ result = XLogIsOwnerOfTuple (hnode , & (btitem -> bti_itup .t_tid ),
1254
1280
record -> xl_xid , cid );
1255
- if (result <= 0 ) /* no tuple or not owner */
1281
+ if (result < 0 ) /* not owner */
1256
1282
{
1257
1283
UnlockAndReleaseBuffer (buffer );
1258
1284
return ;
@@ -1278,7 +1304,7 @@ _bt_del_item(Relation reln, Buffer buffer, BTItem btitem, bool insert,
1278
1304
1279
1305
static bool
1280
1306
_bt_add_item (Page page , OffsetNumber offno ,
1281
- char * item , Size size , RelFileNode * hnode )
1307
+ char * item , Size size , RelFileNode hnode )
1282
1308
{
1283
1309
BTPageOpaque pageop = (BTPageOpaque ) PageGetSpecialPointer (page );
1284
1310
@@ -1309,4 +1335,125 @@ _bt_add_item(Page page, OffsetNumber offno,
1309
1335
return (true);
1310
1336
}
1311
1337
1338
+ static bool
1339
+ _bt_cleanup_page (Page page , RelFileNode hnode )
1340
+ {
1341
+ OffsetNumber maxoff = PageGetMaxOffsetNumber (page );
1342
+ OffsetNumber offno ;
1343
+ ItemId lp ;
1344
+ BTItem item ;
1345
+ bool result = false;
1346
+
1347
+ for (offno = P_FIRSTDATAKEY (pageop ); offno <= maxoff ; )
1348
+ {
1349
+ lp = PageGetItemId (page , offno );
1350
+ item = (BTItem ) PageGetItem (page , lp );
1351
+ if (XLogIsValidTuple (hnode , & (item -> bti_itup .t_tid ))
1352
+ offno = OffsetNumberNext (offno );
1353
+ else
1354
+ {
1355
+ PageIndexTupleDelete (page , offno );
1356
+ maxoff = PageGetMaxOffsetNumber (page );
1357
+ result = true;
1358
+ }
1359
+ }
1360
+
1361
+ return (result );
1362
+ }
1363
+
1364
+ /*
1365
+ * Remove from left sibling items belonging to right sibling
1366
+ * and change P_HIKEY
1367
+ */
1368
+ static void
1369
+ _bt_fix_left_page (Page page , XLogRecord * record , bool onleft )
1370
+ {
1371
+ char * xlrec = (char * ) XLogRecGetData (record );
1372
+ BTPageOpaque pageop = (BTPageOpaque ) PageGetSpecialPointer (page );
1373
+ Size hsize = SizeOfBtreeSplit ;
1374
+ RelFileNode hnode ;
1375
+ BTItemData btdata ;
1376
+ OffsetNumber maxoff = PageGetMaxOffsetNumber (page );
1377
+ OffsetNumber offno ;
1378
+ char * item ;
1379
+ Size itemsz ;
1380
+ char * previtem = NULL ;
1381
+ char * lhikey = NULL ;
1382
+ Size lhisize = 0 ;
1383
+
1384
+ if (pageop -> btpo_flags & BTP_LEAF )
1385
+ {
1386
+ hsize += (sizeof (CommandId ) + sizeof (RelFileNode ));
1387
+ memcpy (& hnode , (char * )xlrec + SizeOfBtreeSplit +
1388
+ sizeof (CommandId ), sizeof (RelFileNode ));
1389
+ }
1390
+ else
1391
+ {
1392
+ lhikey = (char * )xlrec + hsize ;
1393
+ memcpy (& btdata , lhikey , sizeof (BTItemData ));
1394
+ lhisize = IndexTupleDSize (btdata .bti_itup ) +
1395
+ (sizeof (BTItemData ) - sizeof (IndexTupleData ));
1396
+ hsize += lhisize ;
1397
+ }
1398
+
1399
+ if (! P_RIGHTMOST (pageop ))
1400
+ PageIndexTupleDelete (page , P_HIKEY );
1401
+
1402
+ if (onleft ) /* skip target item */
1403
+ {
1404
+ memcpy (& btdata , (char * )xlrec + hsize , sizeof (BTItemData ));
1405
+ itemsz = IndexTupleDSize (btdata .bti_itup ) +
1406
+ (sizeof (BTItemData ) - sizeof (IndexTupleData ));
1407
+ hsize += itemsz ;
1408
+ }
1409
+
1410
+ for (item = (char * )xlrec + hsize ; ; )
1411
+ {
1412
+ memcpy (& btdata , item , sizeof (BTItemData ));
1413
+ for (offno = P_FIRSTDATAKEY (pageop );
1414
+ offno <= maxoff ;
1415
+ offno = OffsetNumberNext (offno ))
1416
+ {
1417
+ ItemId lp = PageGetItemId (page , offno );
1418
+ BTItem btitem = (BTItem ) PageGetItem (page , lp );
1419
+
1420
+ if (BTItemSame (& btdata , btitem ))
1421
+ {
1422
+ PageIndexTupleDelete (page , offno );
1423
+ break ;
1424
+ }
1425
+ }
1426
+
1427
+ itemsz = IndexTupleDSize (btdata .bti_itup ) +
1428
+ (sizeof (BTItemData ) - sizeof (IndexTupleData ));
1429
+ itemsz = MAXALIGN (itemsz );
1430
+
1431
+ if (item + itemsz < (char * )record + record -> xl_len )
1432
+ {
1433
+ previtem = item ;
1434
+ item += itemsz ;
1435
+ }
1436
+ else
1437
+ break ;
1438
+ }
1439
+
1440
+ /* time to insert hi-key */
1441
+ if (pageop -> btpo_flags & BTP_LEAF )
1442
+ {
1443
+ lhikey = (P_RIGHTMOST (pageop )) ? item : previtem ;
1444
+ memcpy (& btdata , lhikey , sizeof (BTItemData ));
1445
+ lhisize = IndexTupleDSize (btdata .bti_itup ) +
1446
+ (sizeof (BTItemData ) - sizeof (IndexTupleData ));
1447
+ }
1448
+
1449
+ if (! _bt_add_item (page ,
1450
+ P_HIKEY ,
1451
+ lhikey ,
1452
+ lhisize ,
1453
+ & hnode ))
1454
+ elog (STOP , "btree_split_redo: failed to add hi key to left sibling" );
1455
+
1456
+ return ;
1457
+ }
1458
+
1312
1459
#endif
0 commit comments