Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8cb6242

Browse files
committed
Replace inefficient _bt_invokestrat calls with direct calls to the
appropriate btree three-way comparison routine. Not clear why the three-way comparison routines were being used in some paths and not others in btree --- incomplete changes by someone long ago, maybe? Anyway, this makes for a nice speedup in CREATE INDEX.
1 parent 4935369 commit 8cb6242

File tree

7 files changed

+265
-287
lines changed

7 files changed

+265
-287
lines changed

src/backend/access/nbtree/nbtinsert.c

Lines changed: 101 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.54 2000/01/26 05:55:58 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.55 2000/02/18 06:32:33 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -20,8 +20,11 @@
2020

2121

2222
static InsertIndexResult _bt_insertonpg(Relation rel, Buffer buf, BTStack stack, int keysz, ScanKey scankey, BTItem btitem, BTItem afteritem);
23-
static Buffer _bt_split(Relation rel, Buffer buf, OffsetNumber firstright);
24-
static OffsetNumber _bt_findsplitloc(Relation rel, Page page, OffsetNumber start, OffsetNumber maxoff, Size llimit);
23+
static Buffer _bt_split(Relation rel, Size keysz, ScanKey scankey,
24+
Buffer buf, OffsetNumber firstright);
25+
static OffsetNumber _bt_findsplitloc(Relation rel, Size keysz, ScanKey scankey,
26+
Page page, OffsetNumber start,
27+
OffsetNumber maxoff, Size llimit);
2528
static void _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf);
2629
static OffsetNumber _bt_pgaddtup(Relation rel, Buffer buf, int keysz, ScanKey itup_scankey, Size itemsize, BTItem btitem, BTItem afteritem);
2730
static bool _bt_goesonpg(Relation rel, Buffer buf, Size keysz, ScanKey scankey, BTItem afteritem);
@@ -297,7 +300,7 @@ _bt_insertonpg(Relation rel,
297300
hitemid = PageGetItemId(page, P_HIKEY);
298301
hitem = (BTItem) PageGetItem(page, hitemid);
299302
if (maxoff > P_HIKEY &&
300-
!_bt_itemcmp(rel, keysz, hitem,
303+
!_bt_itemcmp(rel, keysz, scankey, hitem,
301304
(BTItem) PageGetItem(page, PageGetItemId(page, P_FIRSTKEY)),
302305
BTEqualStrategyNumber))
303306
elog(FATAL, "btree: bad key on the page in the chain of duplicates");
@@ -373,7 +376,8 @@ _bt_insertonpg(Relation rel,
373376
{
374377
itid = PageGetItemId(page, offnum);
375378
chkitem = (BTItem) PageGetItem(page, itid);
376-
if (!_bt_itemcmp(rel, keysz, previtem, chkitem,
379+
if (!_bt_itemcmp(rel, keysz, scankey,
380+
previtem, chkitem,
377381
BTEqualStrategyNumber))
378382
{
379383
if (currsize > maxsize)
@@ -471,9 +475,10 @@ _bt_insertonpg(Relation rel,
471475
MAXALIGN(sizeof(BTPageOpaqueData))
472476
+sizeof(ItemIdData);
473477
llimit /= 2;
474-
firstright = _bt_findsplitloc(rel, page, start, maxoff, llimit);
478+
firstright = _bt_findsplitloc(rel, keysz, scankey,
479+
page, start, maxoff, llimit);
475480

476-
if (_bt_itemcmp(rel, keysz,
481+
if (_bt_itemcmp(rel, keysz, scankey,
477482
(BTItem) PageGetItem(page, PageGetItemId(page, start)),
478483
(BTItem) PageGetItem(page, PageGetItemId(page, firstright)),
479484
BTEqualStrategyNumber))
@@ -503,7 +508,8 @@ _bt_insertonpg(Relation rel,
503508
ItemPointerSet(&(stack->bts_btitem->bti_itup.t_tid),
504509
bknum, P_HIKEY);
505510
pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
506-
if (_bt_itemcmp(rel, keysz, stack->bts_btitem,
511+
if (_bt_itemcmp(rel, keysz, scankey,
512+
stack->bts_btitem,
507513
(BTItem) PageGetItem(page,
508514
PageGetItemId(page, start)),
509515
BTLessStrategyNumber))
@@ -519,7 +525,7 @@ _bt_insertonpg(Relation rel,
519525
}
520526

521527
/* split the buffer into left and right halves */
522-
rbuf = _bt_split(rel, buf, firstright);
528+
rbuf = _bt_split(rel, keysz, scankey, buf, firstright);
523529

524530
/* which new page (left half or right half) gets the tuple? */
525531
if (_bt_goesonpg(rel, buf, keysz, scankey, afteritem))
@@ -550,7 +556,7 @@ _bt_insertonpg(Relation rel,
550556
elog(FATAL, "btree: un-shifted page is empty");
551557
lowLeftItem = (BTItem) PageGetItem(page,
552558
PageGetItemId(page, P_FIRSTKEY));
553-
if (_bt_itemcmp(rel, keysz, lowLeftItem,
559+
if (_bt_itemcmp(rel, keysz, scankey, lowLeftItem,
554560
(BTItem) PageGetItem(page, PageGetItemId(page, P_HIKEY)),
555561
BTEqualStrategyNumber))
556562
lpageop->btpo_flags |= BTP_CHAIN;
@@ -613,7 +619,8 @@ l_spl: ;
613619
{
614620
ritem = (BTItem) PageGetItem(rpage,
615621
PageGetItemId(rpage, P_FIRSTKEY));
616-
if (_bt_itemcmp(rel, keysz, ritem,
622+
if (_bt_itemcmp(rel, keysz, scankey,
623+
ritem,
617624
(BTItem) PageGetItem(rpage,
618625
PageGetItemId(rpage, P_HIKEY)),
619626
BTEqualStrategyNumber))
@@ -663,13 +670,16 @@ l_spl: ;
663670
* possible in splitting leftmost page) and current parent
664671
* item == new_item. - vadim 05/27/97
665672
*/
666-
if (_bt_itemcmp(rel, keysz, stack->bts_btitem, new_item,
673+
if (_bt_itemcmp(rel, keysz, scankey,
674+
stack->bts_btitem, new_item,
667675
BTGreaterStrategyNumber) ||
668676
(!shifted &&
669-
_bt_itemcmp(rel, keysz, stack->bts_btitem,
670-
new_item, BTEqualStrategyNumber) &&
671-
_bt_itemcmp(rel, keysz, lowLeftItem,
672-
new_item, BTLessStrategyNumber)))
677+
_bt_itemcmp(rel, keysz, scankey,
678+
stack->bts_btitem, new_item,
679+
BTEqualStrategyNumber) &&
680+
_bt_itemcmp(rel, keysz, scankey,
681+
lowLeftItem, new_item,
682+
BTLessStrategyNumber)))
673683
{
674684
do_update = true;
675685

@@ -831,7 +841,8 @@ l_spl: ;
831841
* pin and lock on buf are maintained.
832842
*/
833843
static Buffer
834-
_bt_split(Relation rel, Buffer buf, OffsetNumber firstright)
844+
_bt_split(Relation rel, Size keysz, ScanKey scankey,
845+
Buffer buf, OffsetNumber firstright)
835846
{
836847
Buffer rbuf;
837848
Page origpage;
@@ -915,7 +926,8 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright)
915926
{
916927
Size llimit = PageGetFreeSpace(leftpage) / 2;
917928

918-
firstright = _bt_findsplitloc(rel, origpage, start, maxoff, llimit);
929+
firstright = _bt_findsplitloc(rel, keysz, scankey,
930+
origpage, start, maxoff, llimit);
919931
}
920932

921933
for (i = start; i <= maxoff; i = OffsetNumberNext(i))
@@ -1027,6 +1039,8 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright)
10271039
*/
10281040
static OffsetNumber
10291041
_bt_findsplitloc(Relation rel,
1042+
Size keysz,
1043+
ScanKey scankey,
10301044
Page page,
10311045
OffsetNumber start,
10321046
OffsetNumber maxoff,
@@ -1039,12 +1053,10 @@ _bt_findsplitloc(Relation rel,
10391053
BTItem safeitem,
10401054
nxtitem;
10411055
Size nbytes;
1042-
int natts;
10431056

10441057
if (start >= maxoff)
10451058
elog(FATAL, "btree: cannot split if start (%d) >= maxoff (%d)",
10461059
start, maxoff);
1047-
natts = rel->rd_rel->relnatts;
10481060
saferight = start;
10491061
safeitemid = PageGetItemId(page, saferight);
10501062
nbytes = ItemIdGetLength(safeitemid) + sizeof(ItemIdData);
@@ -1064,7 +1076,7 @@ _bt_findsplitloc(Relation rel,
10641076
* at isn't equal to the last safe one we saw, then it's our new
10651077
* safe tuple.
10661078
*/
1067-
if (!_bt_itemcmp(rel, natts,
1079+
if (!_bt_itemcmp(rel, keysz, scankey,
10681080
safeitem, nxtitem, BTEqualStrategyNumber))
10691081
{
10701082
safeitem = nxtitem;
@@ -1345,92 +1357,94 @@ _bt_goesonpg(Relation rel,
13451357
}
13461358

13471359
/*
1348-
* _bt_itemcmp() -- compare item1 to item2 using a requested
1349-
* strategy (<, <=, =, >=, >)
1360+
* _bt_tuplecompare() -- compare two IndexTuples,
1361+
* return -1, 0, or +1
13501362
*
13511363
*/
1352-
bool
1353-
_bt_itemcmp(Relation rel,
1354-
Size keysz,
1355-
BTItem item1,
1356-
BTItem item2,
1357-
StrategyNumber strat)
1364+
int32
1365+
_bt_tuplecompare(Relation rel,
1366+
Size keysz,
1367+
ScanKey scankey,
1368+
IndexTuple tuple1,
1369+
IndexTuple tuple2)
13581370
{
13591371
TupleDesc tupDes;
1360-
IndexTuple indexTuple1,
1361-
indexTuple2;
1362-
Datum attrDatum1,
1363-
attrDatum2;
13641372
int i;
1365-
bool isFirstNull,
1366-
isSecondNull;
1367-
bool compare;
1368-
bool useEqual = false;
1369-
1370-
if (strat == BTLessEqualStrategyNumber)
1371-
{
1372-
useEqual = true;
1373-
strat = BTLessStrategyNumber;
1374-
}
1375-
else if (strat == BTGreaterEqualStrategyNumber)
1376-
{
1377-
useEqual = true;
1378-
strat = BTGreaterStrategyNumber;
1379-
}
1373+
int32 compare = 0;
13801374

13811375
tupDes = RelationGetDescr(rel);
1382-
indexTuple1 = &(item1->bti_itup);
1383-
indexTuple2 = &(item2->bti_itup);
13841376

13851377
for (i = 1; i <= keysz; i++)
13861378
{
1387-
attrDatum1 = index_getattr(indexTuple1, i, tupDes, &isFirstNull);
1388-
attrDatum2 = index_getattr(indexTuple2, i, tupDes, &isSecondNull);
1379+
ScanKey entry = &scankey[i - 1];
1380+
Datum attrDatum1,
1381+
attrDatum2;
1382+
bool isFirstNull,
1383+
isSecondNull;
1384+
1385+
attrDatum1 = index_getattr(tuple1, i, tupDes, &isFirstNull);
1386+
attrDatum2 = index_getattr(tuple2, i, tupDes, &isSecondNull);
13891387

13901388
/* see comments about NULLs handling in btbuild */
1391-
if (isFirstNull) /* attr in item1 is NULL */
1389+
if (isFirstNull) /* attr in tuple1 is NULL */
13921390
{
1393-
if (isSecondNull) /* attr in item2 is NULL too */
1394-
compare = (strat == BTEqualStrategyNumber) ? true : false;
1391+
if (isSecondNull) /* attr in tuple2 is NULL too */
1392+
compare = 0;
13951393
else
1396-
compare = (strat == BTGreaterStrategyNumber) ? true : false;
1394+
compare = 1; /* NULL ">" not-NULL */
13971395
}
1398-
else if (isSecondNull) /* attr in item1 is NOT_NULL and */
1399-
{ /* and attr in item2 is NULL */
1400-
compare = (strat == BTLessStrategyNumber) ? true : false;
1396+
else if (isSecondNull) /* attr in tuple1 is NOT_NULL and */
1397+
{ /* attr in tuple2 is NULL */
1398+
compare = -1; /* not-NULL "<" NULL */
14011399
}
14021400
else
1403-
compare = _bt_invokestrat(rel, i, strat, attrDatum1, attrDatum2);
1404-
1405-
if (compare) /* true for one of ">, <, =" */
14061401
{
1407-
if (strat != BTEqualStrategyNumber)
1408-
return true;
1402+
compare = (int32) FMGR_PTR2(&entry->sk_func,
1403+
attrDatum1, attrDatum2);
14091404
}
1410-
else
1411-
/* false for one of ">, <, =" */
1412-
{
1413-
if (strat == BTEqualStrategyNumber)
1414-
return false;
14151405

1416-
/*
1417-
* if original strat was "<=, >=" OR "<, >" but some
1418-
* attribute(s) left - need to test for Equality
1419-
*/
1420-
if (useEqual || i < keysz)
1421-
{
1422-
if (isFirstNull || isSecondNull)
1423-
compare = (isFirstNull && isSecondNull) ? true : false;
1424-
else
1425-
compare = _bt_invokestrat(rel, i, BTEqualStrategyNumber,
1426-
attrDatum1, attrDatum2);
1427-
if (compare) /* item1' and item2' attributes are equal */
1428-
continue; /* - try to compare next attributes */
1429-
}
1430-
return false;
1431-
}
1406+
if (compare != 0)
1407+
break; /* done when we find unequal attributes */
14321408
}
1433-
return true;
1409+
1410+
return compare;
1411+
}
1412+
1413+
/*
1414+
* _bt_itemcmp() -- compare two BTItems using a requested
1415+
* strategy (<, <=, =, >=, >)
1416+
*
1417+
*/
1418+
bool
1419+
_bt_itemcmp(Relation rel,
1420+
Size keysz,
1421+
ScanKey scankey,
1422+
BTItem item1,
1423+
BTItem item2,
1424+
StrategyNumber strat)
1425+
{
1426+
int32 compare;
1427+
1428+
compare = _bt_tuplecompare(rel, keysz, scankey,
1429+
&(item1->bti_itup),
1430+
&(item2->bti_itup));
1431+
1432+
switch (strat)
1433+
{
1434+
case BTLessStrategyNumber:
1435+
return (bool) (compare < 0);
1436+
case BTLessEqualStrategyNumber:
1437+
return (bool) (compare <= 0);
1438+
case BTEqualStrategyNumber:
1439+
return (bool) (compare == 0);
1440+
case BTGreaterEqualStrategyNumber:
1441+
return (bool) (compare >= 0);
1442+
case BTGreaterStrategyNumber:
1443+
return (bool) (compare > 0);
1444+
}
1445+
1446+
elog(ERROR, "_bt_itemcmp: bogus strategy %d", (int) strat);
1447+
return false;
14341448
}
14351449

14361450
/*
@@ -1585,7 +1599,7 @@ _bt_shift(Relation rel, Buffer buf, BTStack stack, int keysz,
15851599
/* init old page opaque */
15861600
pageop->btpo_flags = npageop->btpo_flags; /* restore flags */
15871601
pageop->btpo_flags &= ~BTP_CHAIN;
1588-
if (_bt_itemcmp(rel, keysz, hikey, btitem, BTEqualStrategyNumber))
1602+
if (_bt_itemcmp(rel, keysz, scankey, hikey, btitem, BTEqualStrategyNumber))
15891603
pageop->btpo_flags |= BTP_CHAIN;
15901604
pageop->btpo_prev = npageop->btpo_prev; /* restore prev */
15911605
pageop->btpo_next = nbknum; /* next points to the new page */

0 commit comments

Comments
 (0)