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