@@ -363,113 +363,120 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
363363}
364364
365365/*
366- * Search a page for the entry with lowest penalty.
366+ * Search an upper index page for the entry with lowest penalty for insertion
367+ * of the new index key contained in "it".
367368 *
368- * The index may have multiple columns, and there's a penalty value for each column.
369- * The penalty associated with a column which appears earlier in the index definition is
370- * strictly more important than the penalty of column which appears later in the index
371- * definition.
369+ * Returns the index of the page entry to insert into.
372370 */
373371OffsetNumber
374372gistchoose (Relation r ,Page p ,IndexTuple it ,/* it has compressed entry */
375373GISTSTATE * giststate )
376374{
375+ OffsetNumber result ;
377376OffsetNumber maxoff ;
378377OffsetNumber i ;
379- OffsetNumber which ;
380- float sum_grow ,
381- which_grow [INDEX_MAX_KEYS ];
378+ float best_penalty [INDEX_MAX_KEYS ];
382379GISTENTRY entry ,
383380identry [INDEX_MAX_KEYS ];
384381bool isnull [INDEX_MAX_KEYS ];
385382
386- maxoff = PageGetMaxOffsetNumber (p );
387- * which_grow = -1.0 ;
388- which = InvalidOffsetNumber ;
389- sum_grow = 1 ;
383+ Assert (!GistPageIsLeaf (p ));
384+
390385gistDeCompressAtt (giststate ,r ,
391386it ,NULL , (OffsetNumber )0 ,
392387identry ,isnull );
393388
394- Assert ( maxoff >= FirstOffsetNumber );
395- Assert (! GistPageIsLeaf ( p )) ;
389+ /* we'll return FirstOffsetNumber if page is empty (shouldn't happen) */
390+ result = FirstOffsetNumber ;
396391
397392/*
398- * Loop over tuples on page.
393+ * The index may have multiple columns, and there's a penalty value for
394+ * each column. The penalty associated with a column that appears earlier
395+ * in the index definition is strictly more important than the penalty of
396+ * a column that appears later in the index definition.
399397 *
400- * We'll exit early if we find an index key that can accommodate the new key with no
401- * penalty on any column. sum_grow is used to track this condition. Normally, it is the
402- * sum of the penalties we've seen for this column so far, which is not a very useful
403- * quantity in general because the penalties for each column are only considered
404- * independently, but all we really care about is whether or not it's greater than zero.
405- * Since penalties can't be negative, the sum of the penalties will be greater than
406- * zero if and only if at least one penalty was greater than zero. To make things just
407- * a bit more complicated, we arbitrarily set sum_grow to 1.0 whenever we want to force
408- * the at least one more iteration of this outer loop. Any non-zero value would serve
409- * just as well.
398+ * best_penalty[j] is the best penalty we have seen so far for column j,
399+ * or -1 when we haven't yet examined column j. Array entries to the
400+ * right of the first -1 are undefined.
410401 */
411- for (i = FirstOffsetNumber ;i <=maxoff && sum_grow ;i = OffsetNumberNext (i ))
402+ best_penalty [0 ]= -1 ;
403+
404+ /*
405+ * Loop over tuples on page.
406+ */
407+ maxoff = PageGetMaxOffsetNumber (p );
408+ Assert (maxoff >=FirstOffsetNumber );
409+
410+ for (i = FirstOffsetNumber ;i <=maxoff ;i = OffsetNumberNext (i ))
412411{
413- int j ;
414412IndexTuple itup = (IndexTuple )PageGetItem (p ,PageGetItemId (p ,i ));
413+ bool zero_penalty ;
414+ int j ;
415415
416- sum_grow = 0 ;
416+ zero_penalty = true ;
417417
418- /* Loop overindexed attribtues . */
418+ /* Loop overindex attributes . */
419419for (j = 0 ;j < r -> rd_att -> natts ;j ++ )
420420{
421421Datum datum ;
422422float usize ;
423423bool IsNull ;
424424
425+ /* Compute penalty for this column. */
425426datum = index_getattr (itup ,j + 1 ,giststate -> tupdesc ,& IsNull );
426427gistdentryinit (giststate ,j ,& entry ,datum ,r ,p ,i ,
427428 FALSE,IsNull );
428429usize = gistpenalty (giststate ,j ,& entry ,IsNull ,
429430& identry [j ],isnull [j ]);
431+ if (usize > 0 )
432+ zero_penalty = false;
430433
431- if (which_grow [j ]< 0 || usize < which_grow [j ])
434+ if (best_penalty [j ]< 0 || usize < best_penalty [j ])
432435{
433436/*
434- * We get here in two cases. First, we may have just discovered that the
435- * current tuple is the best one we've seen so far; that is, for the first
436- * column for which the penalty is not equal to the best tuple seen so far,
437- * this one has a lower penalty than the previously-seen one. But, when
438- * a new best tuple is found, we must record the best penalty value for
439- * all the remaining columns. We'll end up here for each remaining index
440- * column in that case, too.
437+ * New best penalty for column. Tentatively select this tuple
438+ * as the target, and record the best penalty.Then reset the
439+ * next column's penalty to "unknown" (and indirectly, the
440+ * same for all the ones to its right). This will force us to
441+ * adopt this tuple's penalty values as the best for all the
442+ * remaining columns during subsequent loop iterations.
441443 */
442- which = i ;
443- which_grow [j ]= usize ;
444+ result = i ;
445+ best_penalty [j ]= usize ;
446+
444447if (j < r -> rd_att -> natts - 1 )
445- which_grow [j + 1 ]= -1 ;
446- sum_grow += which_grow [j ];
448+ best_penalty [j + 1 ]= -1 ;
447449}
448- else if (which_grow [j ]== usize )
450+ else if (best_penalty [j ]== usize )
449451{
450452/*
451- * The current tuple is exactly as good for this column as the best tuple
452- * seen so far. The next iteration of this loop will compare the next
453- * column.
453+ * The current tuple is exactly as good for this column as the
454+ *best tuple seen so far. The next iteration of this loop
455+ *will compare the next column.
454456 */
455- sum_grow += usize ;
456457}
457458else
458459{
459460/*
460- * The current tuple is worse for this column than the best tuple seen so
461- * far. Skip the remaining columns and move on to the next tuple, if any.
461+ * The current tuple is worse for this column than the best
462+ * tuple seen so far. Skip the remaining columns and move on
463+ * to the next tuple, if any.
462464 */
463- sum_grow = 1 ;
465+ zero_penalty = false; /* so outer loop won't exit */
464466break ;
465467}
466468}
467- }
468469
469- if (which == InvalidOffsetNumber )
470- which = FirstOffsetNumber ;
470+ /*
471+ * If we find a tuple with zero penalty for all columns, there's no
472+ * need to examine remaining tuples; just break out of the loop and
473+ * return it.
474+ */
475+ if (zero_penalty )
476+ break ;
477+ }
471478
472- return which ;
479+ return result ;
473480}
474481
475482/*