Tweak mdnblocks() to avoid doing lseek() on segments that it has

previously determined not to be the last segment of a relation.
This reduces the expected cost to one seek, rather than one seek per
segment.  We can get away with this because truncation of a relation
will cause a relcache flush and so the md.c file descriptor will be
closed; when it is re-opened we will re-determine the last segment.
This commit is contained in:
Tom Lane 2003-01-07 01:19:12 +00:00
parent c9cf982038
commit 973a210cce
1 changed files with 16 additions and 1 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.93 2002/11/12 15:26:30 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.94 2003/01/07 01:19:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -569,6 +569,21 @@ mdnblocks(Relation reln)
#ifndef LET_OS_MANAGE_FILESIZE
segno = 0;
/*
* Skip through any segments that aren't the last one, to avoid redundant
* seeks on them. We have previously verified that these segments are
* exactly RELSEG_SIZE long, and it's useless to recheck that each time.
* (NOTE: this assumption could only be wrong if another backend has
* truncated the relation. We rely on higher code levels to handle that
* scenario by closing and re-opening the md fd.)
*/
while (v->mdfd_chain != (MdfdVec *) NULL)
{
segno++;
v = v->mdfd_chain;
}
for (;;)
{
nblocks = _mdnblocks(v->mdfd_vfd, BLCKSZ);