28
28
29
29
#include "postgres.h"
30
30
31
- #include "access/heapam.h"
32
31
#include "access/relscan.h"
33
32
#include "access/tsmapi.h"
34
33
#include "catalog/pg_type.h"
@@ -46,7 +45,6 @@ typedef struct
46
45
{
47
46
uint32 seed ; /* random seed */
48
47
int64 ntuples ; /* number of tuples to return */
49
- int64 donetuples ; /* number of tuples already returned */
50
48
OffsetNumber lt ; /* last tuple returned from current block */
51
49
BlockNumber doneblocks ; /* number of already-scanned blocks */
52
50
BlockNumber lb ; /* last block visited */
@@ -67,11 +65,10 @@ static void system_rows_beginsamplescan(SampleScanState *node,
67
65
Datum * params ,
68
66
int nparams ,
69
67
uint32 seed );
70
- static BlockNumber system_rows_nextsampleblock (SampleScanState * node );
68
+ static BlockNumber system_rows_nextsampleblock (SampleScanState * node , BlockNumber nblocks );
71
69
static OffsetNumber system_rows_nextsampletuple (SampleScanState * node ,
72
70
BlockNumber blockno ,
73
71
OffsetNumber maxoffset );
74
- static bool SampleOffsetVisible (OffsetNumber tupoffset , HeapScanDesc scan );
75
72
static uint32 random_relative_prime (uint32 n , SamplerRandomState randstate );
76
73
77
74
@@ -187,7 +184,6 @@ system_rows_beginsamplescan(SampleScanState *node,
187
184
188
185
sampler -> seed = seed ;
189
186
sampler -> ntuples = ntuples ;
190
- sampler -> donetuples = 0 ;
191
187
sampler -> lt = InvalidOffsetNumber ;
192
188
sampler -> doneblocks = 0 ;
193
189
/* lb will be initialized during first NextSampleBlock call */
@@ -206,11 +202,9 @@ system_rows_beginsamplescan(SampleScanState *node,
206
202
* Uses linear probing algorithm for picking next block.
207
203
*/
208
204
static BlockNumber
209
- system_rows_nextsampleblock (SampleScanState * node )
205
+ system_rows_nextsampleblock (SampleScanState * node , BlockNumber nblocks )
210
206
{
211
207
SystemRowsSamplerData * sampler = (SystemRowsSamplerData * ) node -> tsm_state ;
212
- TableScanDesc scan = node -> ss .ss_currentScanDesc ;
213
- HeapScanDesc hscan = (HeapScanDesc ) scan ;
214
208
215
209
/* First call within scan? */
216
210
if (sampler -> doneblocks == 0 )
@@ -222,14 +216,14 @@ system_rows_nextsampleblock(SampleScanState *node)
222
216
SamplerRandomState randstate ;
223
217
224
218
/* If relation is empty, there's nothing to scan */
225
- if (hscan -> rs_nblocks == 0 )
219
+ if (nblocks == 0 )
226
220
return InvalidBlockNumber ;
227
221
228
222
/* We only need an RNG during this setup step */
229
223
sampler_random_init_state (sampler -> seed , randstate );
230
224
231
225
/* Compute nblocks/firstblock/step only once per query */
232
- sampler -> nblocks = hscan -> rs_nblocks ;
226
+ sampler -> nblocks = nblocks ;
233
227
234
228
/* Choose random starting block within the relation */
235
229
/* (Actually this is the predecessor of the first block visited) */
@@ -246,7 +240,7 @@ system_rows_nextsampleblock(SampleScanState *node)
246
240
247
241
/* If we've read all blocks or returned all needed tuples, we're done */
248
242
if (++ sampler -> doneblocks > sampler -> nblocks ||
249
- sampler -> donetuples >= sampler -> ntuples )
243
+ node -> donetuples >= sampler -> ntuples )
250
244
return InvalidBlockNumber ;
251
245
252
246
/*
@@ -259,7 +253,7 @@ system_rows_nextsampleblock(SampleScanState *node)
259
253
{
260
254
/* Advance lb, using uint64 arithmetic to forestall overflow */
261
255
sampler -> lb = ((uint64 ) sampler -> lb + sampler -> step ) % sampler -> nblocks ;
262
- } while (sampler -> lb >= hscan -> rs_nblocks );
256
+ } while (sampler -> lb >= nblocks );
263
257
264
258
return sampler -> lb ;
265
259
}
@@ -279,77 +273,27 @@ system_rows_nextsampletuple(SampleScanState *node,
279
273
OffsetNumber maxoffset )
280
274
{
281
275
SystemRowsSamplerData * sampler = (SystemRowsSamplerData * ) node -> tsm_state ;
282
- TableScanDesc scan = node -> ss .ss_currentScanDesc ;
283
- HeapScanDesc hscan = (HeapScanDesc ) scan ;
284
276
OffsetNumber tupoffset = sampler -> lt ;
285
277
286
278
/* Quit if we've returned all needed tuples */
287
- if (sampler -> donetuples >= sampler -> ntuples )
279
+ if (node -> donetuples >= sampler -> ntuples )
288
280
return InvalidOffsetNumber ;
289
281
290
- /*
291
- * Because we should only count visible tuples as being returned, we need
292
- * to search for a visible tuple rather than just let the core code do it.
293
- */
294
-
295
- /* We rely on the data accumulated in pagemode access */
296
- Assert (scan -> rs_pageatatime );
297
- for (;;)
298
- {
299
- /* Advance to next possible offset on page */
300
- if (tupoffset == InvalidOffsetNumber )
301
- tupoffset = FirstOffsetNumber ;
302
- else
303
- tupoffset ++ ;
304
-
305
- /* Done? */
306
- if (tupoffset > maxoffset )
307
- {
308
- tupoffset = InvalidOffsetNumber ;
309
- break ;
310
- }
282
+ /* Advance to next possible offset on page */
283
+ if (tupoffset == InvalidOffsetNumber )
284
+ tupoffset = FirstOffsetNumber ;
285
+ else
286
+ tupoffset ++ ;
311
287
312
- /* Found a candidate? */
313
- if (SampleOffsetVisible (tupoffset , hscan ))
314
- {
315
- sampler -> donetuples ++ ;
316
- break ;
317
- }
318
- }
288
+ /* Done? */
289
+ if (tupoffset > maxoffset )
290
+ tupoffset = InvalidOffsetNumber ;
319
291
320
292
sampler -> lt = tupoffset ;
321
293
322
294
return tupoffset ;
323
295
}
324
296
325
- /*
326
- * Check if tuple offset is visible
327
- *
328
- * In pageatatime mode, heapgetpage() already did visibility checks,
329
- * so just look at the info it left in rs_vistuples[].
330
- */
331
- static bool
332
- SampleOffsetVisible (OffsetNumber tupoffset , HeapScanDesc scan )
333
- {
334
- int start = 0 ,
335
- end = scan -> rs_ntuples - 1 ;
336
-
337
- while (start <= end )
338
- {
339
- int mid = (start + end ) / 2 ;
340
- OffsetNumber curoffset = scan -> rs_vistuples [mid ];
341
-
342
- if (tupoffset == curoffset )
343
- return true;
344
- else if (tupoffset < curoffset )
345
- end = mid - 1 ;
346
- else
347
- start = mid + 1 ;
348
- }
349
-
350
- return false;
351
- }
352
-
353
297
/*
354
298
* Compute greatest common divisor of two uint32's.
355
299
*/
0 commit comments