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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy