31
31
*
32
32
*
33
33
* IDENTIFICATION
34
- * $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.19 2002/09/04 20:31:17 momjian Exp $
34
+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.20 2002/09/20 19:56:01 tgl Exp $
35
35
*
36
36
*-------------------------------------------------------------------------
37
37
*/
@@ -87,9 +87,8 @@ typedef struct LVRelStats
87
87
/* We use a simple array until it fills up, then convert to heap */
88
88
bool fs_is_heap ; /* are we using heap organization? */
89
89
int num_free_pages ; /* current # of entries */
90
- int max_free_pages ; /* # slots allocated in arrays */
91
- BlockNumber * free_pages ; /* array or heap of block numbers */
92
- Size * free_spaceavail ; /* array or heap of available space */
90
+ int max_free_pages ; /* # slots allocated in array */
91
+ PageFreeSpaceInfo * free_pages ; /* array or heap of blkno/avail */
93
92
} LVRelStats ;
94
93
95
94
@@ -119,6 +118,7 @@ static bool lazy_tid_reaped(ItemPointer itemptr, void *state);
119
118
static bool dummy_tid_reaped (ItemPointer itemptr , void * state );
120
119
static void lazy_update_fsm (Relation onerel , LVRelStats * vacrelstats );
121
120
static int vac_cmp_itemptr (const void * left , const void * right );
121
+ static int vac_cmp_page_spaces (const void * left , const void * right );
122
122
123
123
124
124
/*
@@ -432,8 +432,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
432
432
lazy_scan_index (Irel [i ], vacrelstats );
433
433
}
434
434
435
- elog (elevel , "Pages %u: Changed %u, Empty %u; \
436
- Tup %.0f: Vac %.0f, Keep %.0f, UnUsed %.0f.\n\tTotal %s" ,
435
+ elog (elevel , "Pages %u: Changed %u, Empty %u; Tup %.0f: Vac %.0f, Keep %.0f, UnUsed %.0f.\n\tTotal %s" ,
437
436
nblocks , changed_pages , empty_pages ,
438
437
num_tuples , tups_vacuumed , nkeep , nunused ,
439
438
vac_show_rusage (& ru0 ));
@@ -662,8 +661,7 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
662
661
{
663
662
BlockNumber old_rel_pages = vacrelstats -> rel_pages ;
664
663
BlockNumber new_rel_pages ;
665
- BlockNumber * pages ;
666
- Size * spaceavail ;
664
+ PageFreeSpaceInfo * pageSpaces ;
667
665
int n ;
668
666
int i ,
669
667
j ;
@@ -736,20 +734,20 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
736
734
* Drop free-space info for removed blocks; these must not get entered
737
735
* into the FSM!
738
736
*/
739
- pages = vacrelstats -> free_pages ;
740
- spaceavail = vacrelstats -> free_spaceavail ;
737
+ pageSpaces = vacrelstats -> free_pages ;
741
738
n = vacrelstats -> num_free_pages ;
742
739
j = 0 ;
743
740
for (i = 0 ; i < n ; i ++ )
744
741
{
745
- if (pages [i ] < new_rel_pages )
742
+ if (pageSpaces [i ]. blkno < new_rel_pages )
746
743
{
747
- pages [j ] = pages [i ];
748
- spaceavail [j ] = spaceavail [i ];
744
+ pageSpaces [j ] = pageSpaces [i ];
749
745
j ++ ;
750
746
}
751
747
}
752
748
vacrelstats -> num_free_pages = j ;
749
+ /* We destroyed the heap ordering, so mark array unordered */
750
+ vacrelstats -> fs_is_heap = false;
753
751
754
752
/*
755
753
* We keep the exclusive lock until commit (perhaps not necessary)?
@@ -913,10 +911,8 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
913
911
vacrelstats -> fs_is_heap = false;
914
912
vacrelstats -> num_free_pages = 0 ;
915
913
vacrelstats -> max_free_pages = maxpages ;
916
- vacrelstats -> free_pages = (BlockNumber * )
917
- palloc (maxpages * sizeof (BlockNumber ));
918
- vacrelstats -> free_spaceavail = (Size * )
919
- palloc (maxpages * sizeof (Size ));
914
+ vacrelstats -> free_pages = (PageFreeSpaceInfo * )
915
+ palloc (maxpages * sizeof (PageFreeSpaceInfo ));
920
916
}
921
917
922
918
/*
@@ -946,32 +942,30 @@ lazy_record_free_space(LVRelStats *vacrelstats,
946
942
BlockNumber page ,
947
943
Size avail )
948
944
{
949
- BlockNumber * pages ;
950
- Size * spaceavail ;
945
+ PageFreeSpaceInfo * pageSpaces ;
951
946
int n ;
952
947
953
948
/* Ignore pages with little free space */
954
949
if (avail < PAGE_SPACE_THRESHOLD )
955
950
return ;
956
951
957
952
/* Copy pointers to local variables for notational simplicity */
958
- pages = vacrelstats -> free_pages ;
959
- spaceavail = vacrelstats -> free_spaceavail ;
953
+ pageSpaces = vacrelstats -> free_pages ;
960
954
n = vacrelstats -> max_free_pages ;
961
955
962
956
/* If we haven't filled the array yet, just keep adding entries */
963
957
if (vacrelstats -> num_free_pages < n )
964
958
{
965
- pages [vacrelstats -> num_free_pages ] = page ;
966
- spaceavail [vacrelstats -> num_free_pages ] = avail ;
959
+ pageSpaces [vacrelstats -> num_free_pages ]. blkno = page ;
960
+ pageSpaces [vacrelstats -> num_free_pages ]. avail = avail ;
967
961
vacrelstats -> num_free_pages ++ ;
968
962
return ;
969
963
}
970
964
971
965
/*----------
972
966
* The rest of this routine works with "heap" organization of the
973
967
* free space arrays, wherein we maintain the heap property
974
- * spaceavail [(j-1) div 2] <= spaceavail [j] for 0 < j < n.
968
+ * avail [(j-1) div 2] <= avail [j] for 0 < j < n.
975
969
* In particular, the zero'th element always has the smallest available
976
970
* space and can be discarded to make room for a new page with more space.
977
971
* See Knuth's discussion of heap-based priority queues, sec 5.2.3;
@@ -991,8 +985,8 @@ lazy_record_free_space(LVRelStats *vacrelstats,
991
985
992
986
while (-- l >= 0 )
993
987
{
994
- BlockNumber R = pages [l ];
995
- Size K = spaceavail [l ];
988
+ BlockNumber R = pageSpaces [l ]. blkno ;
989
+ Size K = pageSpaces [l ]. avail ;
996
990
int i ; /* i is where the "hole" is */
997
991
998
992
i = l ;
@@ -1002,23 +996,22 @@ lazy_record_free_space(LVRelStats *vacrelstats,
1002
996
1003
997
if (j >= n )
1004
998
break ;
1005
- if (j + 1 < n && spaceavail [j ] > spaceavail [j + 1 ])
999
+ if (j + 1 < n && pageSpaces [j ]. avail > pageSpaces [j + 1 ]. avail )
1006
1000
j ++ ;
1007
- if (K <= spaceavail [j ])
1001
+ if (K <= pageSpaces [j ]. avail )
1008
1002
break ;
1009
- pages [i ] = pages [j ];
1010
- spaceavail [i ] = spaceavail [j ];
1003
+ pageSpaces [i ] = pageSpaces [j ];
1011
1004
i = j ;
1012
1005
}
1013
- pages [i ] = R ;
1014
- spaceavail [i ] = K ;
1006
+ pageSpaces [i ]. blkno = R ;
1007
+ pageSpaces [i ]. avail = K ;
1015
1008
}
1016
1009
1017
1010
vacrelstats -> fs_is_heap = true;
1018
1011
}
1019
1012
1020
1013
/* If new page has more than zero'th entry, insert it into heap */
1021
- if (avail > spaceavail [0 ])
1014
+ if (avail > pageSpaces [0 ]. avail )
1022
1015
{
1023
1016
/*
1024
1017
* Notionally, we replace the zero'th entry with the new data, and
@@ -1034,16 +1027,15 @@ lazy_record_free_space(LVRelStats *vacrelstats,
1034
1027
1035
1028
if (j >= n )
1036
1029
break ;
1037
- if (j + 1 < n && spaceavail [j ] > spaceavail [j + 1 ])
1030
+ if (j + 1 < n && pageSpaces [j ]. avail > pageSpaces [j + 1 ]. avail )
1038
1031
j ++ ;
1039
- if (avail <= spaceavail [j ])
1032
+ if (avail <= pageSpaces [j ]. avail )
1040
1033
break ;
1041
- pages [i ] = pages [j ];
1042
- spaceavail [i ] = spaceavail [j ];
1034
+ pageSpaces [i ] = pageSpaces [j ];
1043
1035
i = j ;
1044
1036
}
1045
- pages [i ] = page ;
1046
- spaceavail [i ] = avail ;
1037
+ pageSpaces [i ]. blkno = page ;
1038
+ pageSpaces [i ]. avail = avail ;
1047
1039
}
1048
1040
}
1049
1041
@@ -1085,16 +1077,17 @@ dummy_tid_reaped(ItemPointer itemptr, void *state)
1085
1077
static void
1086
1078
lazy_update_fsm (Relation onerel , LVRelStats * vacrelstats )
1087
1079
{
1080
+ PageFreeSpaceInfo * pageSpaces = vacrelstats -> free_pages ;
1081
+ int nPages = vacrelstats -> num_free_pages ;
1082
+
1088
1083
/*
1089
- * Since MultiRecordFreeSpace doesn't currently impose any
1090
- * restrictions on the ordering of the input, we can just pass it the
1091
- * arrays as-is, whether they are in heap or linear order.
1084
+ * Sort data into order, as required by MultiRecordFreeSpace.
1092
1085
*/
1093
- MultiRecordFreeSpace ( & onerel -> rd_node ,
1094
- 0 , MaxBlockNumber ,
1095
- vacrelstats -> num_free_pages ,
1096
- vacrelstats -> free_pages ,
1097
- vacrelstats -> free_spaceavail );
1086
+ if ( nPages > 1 )
1087
+ qsort ( pageSpaces , nPages , sizeof ( PageFreeSpaceInfo ) ,
1088
+ vac_cmp_page_spaces );
1089
+
1090
+ MultiRecordFreeSpace ( & onerel -> rd_node , 0 , nPages , pageSpaces );
1098
1091
}
1099
1092
1100
1093
/*
@@ -1126,3 +1119,16 @@ vac_cmp_itemptr(const void *left, const void *right)
1126
1119
1127
1120
return 0 ;
1128
1121
}
1122
+
1123
+ static int
1124
+ vac_cmp_page_spaces (const void * left , const void * right )
1125
+ {
1126
+ PageFreeSpaceInfo * linfo = (PageFreeSpaceInfo * ) left ;
1127
+ PageFreeSpaceInfo * rinfo = (PageFreeSpaceInfo * ) right ;
1128
+
1129
+ if (linfo -> blkno < rinfo -> blkno )
1130
+ return -1 ;
1131
+ else if (linfo -> blkno > rinfo -> blkno )
1132
+ return 1 ;
1133
+ return 0 ;
1134
+ }
0 commit comments