8
8
* Portions Copyright (c) 1994, Regents of the University of California
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -936,31 +936,6 @@ gistmakedeal(GISTInsertState *state, GISTSTATE *giststate)
936
936
gistxlogInsertCompletion (state -> r -> rd_node , & (state -> key ), 1 );
937
937
}
938
938
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
-
964
939
/*
965
940
* gistSplit -- split a page in the tree.
966
941
*/
@@ -975,100 +950,70 @@ gistSplit(Relation r,
975
950
* rvectup ;
976
951
GIST_SPLITVEC v ;
977
952
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 ;
983
956
SplitedPageLayout * res = NULL ;
984
957
985
958
/* generate the item array */
986
- realoffset = palloc ((len + 1 ) * sizeof (OffsetNumber ));
987
959
entryvec = palloc (GEVHDRSZ + (len + 1 ) * sizeof (GISTENTRY ));
988
960
entryvec -> n = len + 1 ;
989
961
990
- fakeoffset = FirstOffsetNumber ;
991
962
for (i = 1 ; i <= len ; i ++ )
992
963
{
993
964
Datum datum ;
994
965
bool IsNull ;
995
966
996
967
if (!GistPageIsLeaf (page ) && GistTupleIsInvalid (itup [i - 1 ]))
997
- {
998
- entryvec -> n -- ;
999
968
/* 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 ;
1003
976
1004
977
datum = index_getattr (itup [i - 1 ], 1 , giststate -> tupdesc , & IsNull );
1005
- gistdentryinit (giststate , 0 , & (entryvec -> vector [fakeoffset ]),
978
+ gistdentryinit (giststate , 0 , & (entryvec -> vector [i ]),
1006
979
datum , r , page , i ,
1007
980
ATTSIZE (datum , giststate -> tupdesc , 1 , IsNull ),
1008
981
FALSE, IsNull );
1009
- realoffset [fakeoffset ] = i ;
1010
- fakeoffset ++ ;
1011
982
}
1012
983
1013
984
/*
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)
1017
993
*/
1018
- if (entryvec -> n != len + 1 )
994
+ if (nOffInvTuples > 0 )
1019
995
{
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);
1072
1017
}
1073
1018
else
1074
1019
{
@@ -1088,12 +1033,6 @@ gistSplit(Relation r,
1088
1033
for (i = 0 ; i < v .spl_nright ; i ++ )
1089
1034
rvectup [i ] = itup [v .spl_right [i ] - 1 ];
1090
1035
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
-
1097
1036
/* finalyze splitting (may need another split) */
1098
1037
if (!gistfitpage (rvectup , v .spl_nright ))
1099
1038
{
0 commit comments