summaryrefslogtreecommitdiff
path: root/src/backend/storage/smgr/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/smgr/md.c')
-rw-r--r--src/backend/storage/smgr/md.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index fdecbad1709..091993ea45b 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -710,27 +710,44 @@ mdclose(SMgrRelation reln, ForkNumber forknum)
}
/*
- * mdprefetch() -- Initiate asynchronous read of the specified block of a relation
+ * mdprefetch() -- Initiate asynchronous read of the specified blocks of a relation
*/
bool
-mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
+mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
+ int nblocks)
{
#ifdef USE_PREFETCH
- off_t seekpos;
- MdfdVec *v;
Assert((io_direct_flags & IO_DIRECT_DATA) == 0);
- v = _mdfd_getseg(reln, forknum, blocknum, false,
- InRecovery ? EXTENSION_RETURN_NULL : EXTENSION_FAIL);
- if (v == NULL)
+ if ((uint64) blocknum + nblocks > (uint64) MaxBlockNumber + 1)
return false;
- seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
+ while (nblocks > 0)
+ {
+ off_t seekpos;
+ MdfdVec *v;
+ int nblocks_this_segment;
- Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
+ v = _mdfd_getseg(reln, forknum, blocknum, false,
+ InRecovery ? EXTENSION_RETURN_NULL : EXTENSION_FAIL);
+ if (v == NULL)
+ return false;
+
+ seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
- (void) FilePrefetch(v->mdfd_vfd, seekpos, BLCKSZ, WAIT_EVENT_DATA_FILE_PREFETCH);
+ Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
+
+ nblocks_this_segment =
+ Min(nblocks,
+ RELSEG_SIZE - (blocknum % ((BlockNumber) RELSEG_SIZE)));
+
+ (void) FilePrefetch(v->mdfd_vfd, seekpos, BLCKSZ * nblocks_this_segment,
+ WAIT_EVENT_DATA_FILE_PREFETCH);
+
+ blocknum += nblocks_this_segment;
+ nblocks -= nblocks_this_segment;
+ }
#endif /* USE_PREFETCH */
return true;