@@ -363,113 +363,120 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
363
363
}
364
364
365
365
/*
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".
367
368
*
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.
372
370
*/
373
371
OffsetNumber
374
372
gistchoose (Relation r , Page p , IndexTuple it , /* it has compressed entry */
375
373
GISTSTATE * giststate )
376
374
{
375
+ OffsetNumber result ;
377
376
OffsetNumber maxoff ;
378
377
OffsetNumber i ;
379
- OffsetNumber which ;
380
- float sum_grow ,
381
- which_grow [INDEX_MAX_KEYS ];
378
+ float best_penalty [INDEX_MAX_KEYS ];
382
379
GISTENTRY entry ,
383
380
identry [INDEX_MAX_KEYS ];
384
381
bool isnull [INDEX_MAX_KEYS ];
385
382
386
- maxoff = PageGetMaxOffsetNumber (p );
387
- * which_grow = -1.0 ;
388
- which = InvalidOffsetNumber ;
389
- sum_grow = 1 ;
383
+ Assert (!GistPageIsLeaf (p ));
384
+
390
385
gistDeCompressAtt (giststate , r ,
391
386
it , NULL , (OffsetNumber ) 0 ,
392
387
identry , isnull );
393
388
394
- Assert ( maxoff >= FirstOffsetNumber );
395
- Assert (! GistPageIsLeaf ( p )) ;
389
+ /* we'll return FirstOffsetNumber if page is empty (shouldn't happen) */
390
+ result = FirstOffsetNumber ;
396
391
397
392
/*
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.
399
397
*
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.
410
401
*/
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 ))
412
411
{
413
- int j ;
414
412
IndexTuple itup = (IndexTuple ) PageGetItem (p , PageGetItemId (p , i ));
413
+ bool zero_penalty ;
414
+ int j ;
415
415
416
- sum_grow = 0 ;
416
+ zero_penalty = true ;
417
417
418
- /* Loop over indexed attribtues . */
418
+ /* Loop over index attributes . */
419
419
for (j = 0 ; j < r -> rd_att -> natts ; j ++ )
420
420
{
421
421
Datum datum ;
422
422
float usize ;
423
423
bool IsNull ;
424
424
425
+ /* Compute penalty for this column. */
425
426
datum = index_getattr (itup , j + 1 , giststate -> tupdesc , & IsNull );
426
427
gistdentryinit (giststate , j , & entry , datum , r , p , i ,
427
428
FALSE, IsNull );
428
429
usize = gistpenalty (giststate , j , & entry , IsNull ,
429
430
& identry [j ], isnull [j ]);
431
+ if (usize > 0 )
432
+ zero_penalty = false;
430
433
431
- if (which_grow [j ] < 0 || usize < which_grow [j ])
434
+ if (best_penalty [j ] < 0 || usize < best_penalty [j ])
432
435
{
433
436
/*
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.
441
443
*/
442
- which = i ;
443
- which_grow [j ] = usize ;
444
+ result = i ;
445
+ best_penalty [j ] = usize ;
446
+
444
447
if (j < r -> rd_att -> natts - 1 )
445
- which_grow [j + 1 ] = -1 ;
446
- sum_grow += which_grow [j ];
448
+ best_penalty [j + 1 ] = -1 ;
447
449
}
448
- else if (which_grow [j ] == usize )
450
+ else if (best_penalty [j ] == usize )
449
451
{
450
452
/*
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.
454
456
*/
455
- sum_grow += usize ;
456
457
}
457
458
else
458
459
{
459
460
/*
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.
462
464
*/
463
- sum_grow = 1 ;
465
+ zero_penalty = false; /* so outer loop won't exit */
464
466
break ;
465
467
}
466
468
}
467
- }
468
469
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
+ }
471
478
472
- return which ;
479
+ return result ;
473
480
}
474
481
475
482
/*
0 commit comments