Commit 0fd0f368 authored by Tom Lane's avatar Tom Lane

Document and clean up gistsplit.c.

Improve comments, rename some variables and functions, slightly simplify
a couple of APIs, in an attempt to make this code readable by people other
than its original author.

Even though this is essentially just cosmetic, back-patch to all active
branches, because otherwise it's going to make back-patching future fixes
in this file very painful.
parent a187c96d
...@@ -1237,18 +1237,12 @@ gistSplit(Relation r, ...@@ -1237,18 +1237,12 @@ gistSplit(Relation r,
IndexTuple *lvectup, IndexTuple *lvectup,
*rvectup; *rvectup;
GistSplitVector v; GistSplitVector v;
GistEntryVector *entryvec;
int i; int i;
SplitedPageLayout *res = NULL; SplitedPageLayout *res = NULL;
/* generate the item array */
entryvec = palloc(GEVHDRSZ + (len + 1) * sizeof(GISTENTRY));
entryvec->n = len + 1;
memset(v.spl_lisnull, TRUE, sizeof(bool) * giststate->tupdesc->natts); memset(v.spl_lisnull, TRUE, sizeof(bool) * giststate->tupdesc->natts);
memset(v.spl_risnull, TRUE, sizeof(bool) * giststate->tupdesc->natts); memset(v.spl_risnull, TRUE, sizeof(bool) * giststate->tupdesc->natts);
gistSplitByKey(r, page, itup, len, giststate, gistSplitByKey(r, page, itup, len, giststate, &v, 0);
&v, entryvec, 0);
/* form left and right vector */ /* form left and right vector */
lvectup = (IndexTuple *) palloc(sizeof(IndexTuple) * (len + 1)); lvectup = (IndexTuple *) palloc(sizeof(IndexTuple) * (len + 1));
......
This diff is collapsed.
...@@ -90,11 +90,30 @@ typedef GISTPageOpaqueData *GISTPageOpaque; ...@@ -90,11 +90,30 @@ typedef GISTPageOpaqueData *GISTPageOpaque;
/* /*
* This is the Split Vector to be returned by the PickSplit method. * This is the Split Vector to be returned by the PickSplit method.
* PickSplit should check spl_(r|l)datum_exists. If it is 'true', * PickSplit should fill the indexes of tuples to go to the left side into
* that corresponding spl_(r|l)datum already defined and * spl_left[], and those to go to the right into spl_right[] (note the method
* PickSplit should use that value. PickSplit should always set * is responsible for palloc'ing both of these arrays!). The tuple counts
* spl_(r|l)datum_exists to false: GiST will check value to * go into spl_nleft/spl_nright, and spl_ldatum/spl_rdatum must be set to
* control supporting this feature by PickSplit... * the union keys for each side.
*
* If spl_ldatum_exists and spl_rdatum_exists are true, then we are performing
* a "secondary split" using a non-first index column. In this case some
* decisions have already been made about a page split, and the set of tuples
* being passed to PickSplit is just the tuples about which we are undecided.
* spl_ldatum/spl_rdatum then contain the union keys for the tuples already
* chosen to go left or right. Ideally the PickSplit method should take those
* keys into account while deciding what to do with the remaining tuples, ie
* it should try to "build out" from those unions so as to minimally expand
* them. If it does so, it should union the given tuples' keys into the
* existing spl_ldatum/spl_rdatum values rather than just setting those values
* from scratch, and then set spl_ldatum_exists/spl_rdatum_exists to false to
* show it has done this.
*
* If the PickSplit method fails to clear spl_ldatum_exists/spl_rdatum_exists,
* the core GiST code will make its own decision about how to merge the
* secondary-split results with the previously-chosen tuples, and will then
* recompute the union keys from scratch. This is a workable though often not
* optimal approach.
*/ */
typedef struct GIST_SPLITVEC typedef struct GIST_SPLITVEC
{ {
......
...@@ -248,20 +248,21 @@ typedef struct GISTInsertStack ...@@ -248,20 +248,21 @@ typedef struct GISTInsertStack
struct GISTInsertStack *parent; struct GISTInsertStack *parent;
} GISTInsertStack; } GISTInsertStack;
/* Working state and results for multi-column split logic in gistsplit.c */
typedef struct GistSplitVector typedef struct GistSplitVector
{ {
GIST_SPLITVEC splitVector; /* to/from PickSplit method */ GIST_SPLITVEC splitVector; /* passed to/from user PickSplit method */
Datum spl_lattr[INDEX_MAX_KEYS]; /* Union of subkeys in Datum spl_lattr[INDEX_MAX_KEYS]; /* Union of subkeys in
* spl_left */ * splitVector.spl_left */
bool spl_lisnull[INDEX_MAX_KEYS]; bool spl_lisnull[INDEX_MAX_KEYS];
Datum spl_rattr[INDEX_MAX_KEYS]; /* Union of subkeys in Datum spl_rattr[INDEX_MAX_KEYS]; /* Union of subkeys in
* spl_right */ * splitVector.spl_right */
bool spl_risnull[INDEX_MAX_KEYS]; bool spl_risnull[INDEX_MAX_KEYS];
bool *spl_equiv; /* equivalent tuples which can be freely bool *spl_dontcare; /* flags tuples which could go to either side
* distributed between left and right pages */ * of the split for zero penalty */
} GistSplitVector; } GistSplitVector;
typedef struct typedef struct
...@@ -520,7 +521,7 @@ extern Datum gistvacuumcleanup(PG_FUNCTION_ARGS); ...@@ -520,7 +521,7 @@ extern Datum gistvacuumcleanup(PG_FUNCTION_ARGS);
/* gistsplit.c */ /* gistsplit.c */
extern void gistSplitByKey(Relation r, Page page, IndexTuple *itup, extern void gistSplitByKey(Relation r, Page page, IndexTuple *itup,
int len, GISTSTATE *giststate, int len, GISTSTATE *giststate,
GistSplitVector *v, GistEntryVector *entryvec, GistSplitVector *v,
int attno); int attno);
/* gistbuild.c */ /* gistbuild.c */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment