@@ -132,6 +132,8 @@ static bool SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno,
132
132
static void SlruReportIOError (SlruCtl ctl , int pageno , TransactionId xid );
133
133
static int SlruSelectLRUPage (SlruCtl ctl , int pageno );
134
134
135
+ static bool SlruScanDirCbDeleteCutoff (SlruCtl ctl , char * filename ,
136
+ int segpage , void * data );
135
137
136
138
/*
137
139
* Initialization of shared memory
@@ -1137,33 +1139,84 @@ restart:;
1137
1139
LWLockRelease (shared -> ControlLock );
1138
1140
1139
1141
/* Now we can remove the old segment(s) */
1140
- (void ) SlruScanDirectory (ctl , cutoffPage , true );
1142
+ (void ) SlruScanDirectory (ctl , SlruScanDirCbDeleteCutoff , & cutoffPage );
1141
1143
}
1142
1144
1143
1145
/*
1144
- * SimpleLruTruncate subroutine: scan directory for removable segments.
1145
- * Actually remove them iff doDeletions is true. Return TRUE iff any
1146
- * removable segments were found. Note: no locking is needed.
1146
+ * SlruScanDirectory callback
1147
+ * This callback reports true if there's any segment prior to the one
1148
+ * containing the page passed as "data".
1149
+ */
1150
+ bool
1151
+ SlruScanDirCbReportPresence (SlruCtl ctl , char * filename , int segpage , void * data )
1152
+ {
1153
+ int cutoffPage = * (int * ) data ;
1154
+
1155
+ cutoffPage -= cutoffPage % SLRU_PAGES_PER_SEGMENT ;
1156
+
1157
+ if (ctl -> PagePrecedes (segpage , cutoffPage ))
1158
+ return true; /* found one; don't iterate any more */
1159
+
1160
+ return false; /* keep going */
1161
+ }
1162
+
1163
+ /*
1164
+ * SlruScanDirectory callback.
1165
+ * This callback deletes segments prior to the one passed in as "data".
1166
+ */
1167
+ static bool
1168
+ SlruScanDirCbDeleteCutoff (SlruCtl ctl , char * filename , int segpage , void * data )
1169
+ {
1170
+ char path [MAXPGPATH ];
1171
+ int cutoffPage = * (int * ) data ;
1172
+
1173
+ if (ctl -> PagePrecedes (segpage , cutoffPage ))
1174
+ {
1175
+ snprintf (path , MAXPGPATH , "%s/%s" , ctl -> Dir , filename );
1176
+ ereport (DEBUG2 ,
1177
+ (errmsg ("removing file \"%s\"" , path )));
1178
+ unlink (path );
1179
+ }
1180
+
1181
+ return false; /* keep going */
1182
+ }
1183
+
1184
+ /*
1185
+ * SlruScanDirectory callback.
1186
+ * This callback deletes all segments.
1187
+ */
1188
+ bool
1189
+ SlruScanDirCbDeleteAll (SlruCtl ctl , char * filename , int segpage , void * data )
1190
+ {
1191
+ char path [MAXPGPATH ];
1192
+
1193
+ snprintf (path , MAXPGPATH , "%s/%s" , ctl -> Dir , filename );
1194
+ ereport (DEBUG2 ,
1195
+ (errmsg ("removing file \"%s\"" , path )));
1196
+ unlink (path );
1197
+
1198
+ return false; /* keep going */
1199
+ }
1200
+
1201
+ /*
1202
+ * Scan the SimpleLRU directory and apply a callback to each file found in it.
1203
+ *
1204
+ * If the callback returns true, the scan is stopped. The last return value
1205
+ * from the callback is returned.
1147
1206
*
1148
- * This can be called directly from clog.c, for reasons explained there.
1207
+ * Note that the ordering in which the directory is scanned is not guaranteed.
1208
+ *
1209
+ * Note that no locking is applied.
1149
1210
*/
1150
1211
bool
1151
- SlruScanDirectory (SlruCtl ctl , int cutoffPage , bool doDeletions )
1212
+ SlruScanDirectory (SlruCtl ctl , SlruScanCallback callback , void * data )
1152
1213
{
1153
- bool found = false;
1154
1214
DIR * cldir ;
1155
1215
struct dirent * clde ;
1156
1216
int segno ;
1157
1217
int segpage ;
1158
- char path [MAXPGPATH ];
1159
-
1160
- /*
1161
- * The cutoff point is the start of the segment containing cutoffPage.
1162
- * (This is redundant when called from SimpleLruTruncate, but not when
1163
- * called directly from clog.c.)
1164
- */
1165
- cutoffPage -= cutoffPage % SLRU_PAGES_PER_SEGMENT ;
1166
-
1218
+ bool retval ;
1219
+
1167
1220
cldir = AllocateDir (ctl -> Dir );
1168
1221
while ((clde = ReadDir (cldir , ctl -> Dir )) != NULL )
1169
1222
{
@@ -1172,20 +1225,15 @@ SlruScanDirectory(SlruCtl ctl, int cutoffPage, bool doDeletions)
1172
1225
{
1173
1226
segno = (int ) strtol (clde -> d_name , NULL , 16 );
1174
1227
segpage = segno * SLRU_PAGES_PER_SEGMENT ;
1175
- if (ctl -> PagePrecedes (segpage , cutoffPage ))
1176
- {
1177
- found = true;
1178
- if (doDeletions )
1179
- {
1180
- snprintf (path , MAXPGPATH , "%s/%s" , ctl -> Dir , clde -> d_name );
1181
- ereport (DEBUG2 ,
1182
- (errmsg ("removing file \"%s\"" , path )));
1183
- unlink (path );
1184
- }
1185
- }
1228
+
1229
+ elog (DEBUG2 , "SlruScanDirectory invoking callback on %s/%s" ,
1230
+ ctl -> Dir , clde -> d_name );
1231
+ retval = callback (ctl , clde -> d_name , segpage , data );
1232
+ if (retval )
1233
+ break ;
1186
1234
}
1187
1235
}
1188
1236
FreeDir (cldir );
1189
1237
1190
- return found ;
1238
+ return retval ;
1191
1239
}
0 commit comments