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

Commit 420cbff

Browse files
committed
Simplify gistSplit() and some refactoring related code.
1 parent 49b3462 commit 420cbff

File tree

4 files changed

+168
-203
lines changed

4 files changed

+168
-203
lines changed

src/backend/access/gist/gist.c

Lines changed: 42 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.135 2006/05/17 16:34:59 teodor Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.136 2006/05/19 16:15:17 teodor Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -936,31 +936,6 @@ gistmakedeal(GISTInsertState *state, GISTSTATE *giststate)
936936
gistxlogInsertCompletion(state->r->rd_node, &(state->key), 1);
937937
}
938938

939-
static void
940-
gistToRealOffset(OffsetNumber *arr, int len, OffsetNumber *reasloffset)
941-
{
942-
int i;
943-
944-
for (i = 0; i < len; i++)
945-
arr[i] = reasloffset[arr[i]];
946-
}
947-
948-
static IndexTupleData *
949-
gistfillitupvec(IndexTuple *vec, int veclen, int *memlen) {
950-
char *ptr, *ret = palloc(BLCKSZ);
951-
int i;
952-
953-
ptr = ret;
954-
for (i = 0; i < veclen; i++) {
955-
memcpy(ptr, vec[i], IndexTupleSize(vec[i]));
956-
ptr += IndexTupleSize(vec[i]);
957-
}
958-
959-
*memlen = ptr - ret;
960-
Assert( *memlen < BLCKSZ );
961-
return (IndexTupleData*)ret;
962-
}
963-
964939
/*
965940
* gistSplit -- split a page in the tree.
966941
*/
@@ -975,100 +950,70 @@ gistSplit(Relation r,
975950
*rvectup;
976951
GIST_SPLITVEC v;
977952
GistEntryVector *entryvec;
978-
int i,
979-
fakeoffset;
980-
OffsetNumber *realoffset;
981-
IndexTuple *cleaneditup = itup;
982-
int lencleaneditup = len;
953+
int i;
954+
OffsetNumber offInvTuples[ MaxOffsetNumber ];
955+
int nOffInvTuples = 0;
983956
SplitedPageLayout *res = NULL;
984957

985958
/* generate the item array */
986-
realoffset = palloc((len + 1) * sizeof(OffsetNumber));
987959
entryvec = palloc(GEVHDRSZ + (len + 1) * sizeof(GISTENTRY));
988960
entryvec->n = len + 1;
989961

990-
fakeoffset = FirstOffsetNumber;
991962
for (i = 1; i <= len; i++)
992963
{
993964
Datum datum;
994965
bool IsNull;
995966

996967
if (!GistPageIsLeaf(page) && GistTupleIsInvalid(itup[i - 1]))
997-
{
998-
entryvec->n--;
999968
/* remember position of invalid tuple */
1000-
realoffset[entryvec->n] = i;
1001-
continue;
1002-
}
969+
offInvTuples[ nOffInvTuples++ ] = i;
970+
971+
if ( nOffInvTuples > 0 )
972+
/* we can safely do not decompress other keys, because
973+
we will do splecial processing, but
974+
it's needed to find another invalid tuples */
975+
continue;
1003976

1004977
datum = index_getattr(itup[i - 1], 1, giststate->tupdesc, &IsNull);
1005-
gistdentryinit(giststate, 0, &(entryvec->vector[fakeoffset]),
978+
gistdentryinit(giststate, 0, &(entryvec->vector[i]),
1006979
datum, r, page, i,
1007980
ATTSIZE(datum, giststate->tupdesc, 1, IsNull),
1008981
FALSE, IsNull);
1009-
realoffset[fakeoffset] = i;
1010-
fakeoffset++;
1011982
}
1012983

1013984
/*
1014-
* if it was invalid tuple then we need special processing. If it's
1015-
* possible, we move all invalid tuples on right page. We should remember,
1016-
* that union with invalid tuples is a invalid tuple.
985+
* if it was invalid tuple then we need special processing.
986+
* We move all invalid tuples on right page.
987+
*
988+
* if there is no place on left page, gistSplit will be called one more
989+
* time for left page.
990+
*
991+
* Normally, we never exec this code, but after crash replay it's possible
992+
* to get 'invalid' tuples (probability is low enough)
1017993
*/
1018-
if (entryvec->n != len + 1)
994+
if (nOffInvTuples > 0)
1019995
{
1020-
lencleaneditup = entryvec->n - 1;
1021-
cleaneditup = (IndexTuple *) palloc(lencleaneditup * sizeof(IndexTuple));
1022-
for (i = 1; i < entryvec->n; i++)
1023-
cleaneditup[i - 1] = itup[realoffset[i] - 1];
1024-
1025-
if (!gistfitpage(cleaneditup, lencleaneditup))
1026-
{
1027-
/* no space on left to put all good tuples, so picksplit */
1028-
gistUserPicksplit(r, entryvec, &v, cleaneditup, lencleaneditup, giststate);
1029-
v.spl_leftvalid = true;
1030-
v.spl_rightvalid = false;
1031-
gistToRealOffset(v.spl_left, v.spl_nleft, realoffset);
1032-
gistToRealOffset(v.spl_right, v.spl_nright, realoffset);
1033-
}
1034-
else
1035-
{
1036-
/* we can try to store all valid tuples on one page */
1037-
v.spl_right = (OffsetNumber *) palloc(entryvec->n * sizeof(OffsetNumber));
1038-
v.spl_left = (OffsetNumber *) palloc(entryvec->n * sizeof(OffsetNumber));
1039-
1040-
if (lencleaneditup == 0)
1041-
{
1042-
/* all tuples are invalid, so moves half of its to right */
1043-
v.spl_leftvalid = v.spl_rightvalid = false;
1044-
v.spl_nright = 0;
1045-
v.spl_nleft = 0;
1046-
for (i = 1; i <= len; i++)
1047-
if (i - 1 < len / 2)
1048-
v.spl_left[v.spl_nleft++] = i;
1049-
else
1050-
v.spl_right[v.spl_nright++] = i;
1051-
}
1052-
else
1053-
{
1054-
/*
1055-
* we will not call gistUserPicksplit, just put good tuples on
1056-
* left and invalid on right
1057-
*/
1058-
v.spl_nleft = lencleaneditup;
1059-
v.spl_nright = 0;
1060-
for (i = 1; i < entryvec->n; i++)
1061-
v.spl_left[i - 1] = i;
1062-
gistToRealOffset(v.spl_left, v.spl_nleft, realoffset);
1063-
v.spl_lattr[0] = v.spl_ldatum = (Datum) 0;
1064-
v.spl_rattr[0] = v.spl_rdatum = (Datum) 0;
1065-
v.spl_lisnull[0] = true;
1066-
v.spl_risnull[0] = true;
1067-
gistunionsubkey(r, giststate, itup, &v, true);
1068-
v.spl_leftvalid = true;
1069-
v.spl_rightvalid = false;
1070-
}
1071-
}
996+
GistSplitVec gsvp;
997+
998+
v.spl_right = offInvTuples;
999+
v.spl_nright = nOffInvTuples;
1000+
v.spl_rightvalid = false;
1001+
1002+
v.spl_left = (OffsetNumber *) palloc(entryvec->n * sizeof(OffsetNumber));
1003+
v.spl_nleft = 0;
1004+
for(i = 1; i <= len; i++)
1005+
if ( !GistTupleIsInvalid(itup[i - 1]) )
1006+
v.spl_left[ v.spl_nleft++ ] = i;
1007+
v.spl_leftvalid = true;
1008+
1009+
gsvp.idgrp = NULL;
1010+
gsvp.attrsize = v.spl_lattrsize;
1011+
gsvp.attr = v.spl_lattr;
1012+
gsvp.len = v.spl_nleft;
1013+
gsvp.entries = v.spl_left;
1014+
gsvp.isnull = v.spl_lisnull;
1015+
1016+
gistunionsubkeyvec(giststate, itup, &gsvp, true);
10721017
}
10731018
else
10741019
{
@@ -1088,12 +1033,6 @@ gistSplit(Relation r,
10881033
for (i = 0; i < v.spl_nright; i++)
10891034
rvectup[i] = itup[v.spl_right[i] - 1];
10901035

1091-
/* place invalid tuples on right page if itsn't done yet */
1092-
for (fakeoffset = entryvec->n; fakeoffset < len + 1 && lencleaneditup; fakeoffset++)
1093-
{
1094-
rvectup[v.spl_nright++] = itup[realoffset[fakeoffset] - 1];
1095-
}
1096-
10971036
/* finalyze splitting (may need another split) */
10981037
if (!gistfitpage(rvectup, v.spl_nright))
10991038
{

0 commit comments

Comments
 (0)