]> granicus.if.org Git - postgresql/commitdiff
Tweak mdnblocks() to avoid doing lseek() on segments that it has
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 7 Jan 2003 01:19:12 +0000 (01:19 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 7 Jan 2003 01:19:12 +0000 (01:19 +0000)
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.

src/backend/storage/smgr/md.c

index f8f82048f342ed35dfcbaab8a70e922784e12642..d67be96349ebee9cf4417f841fd1825382f99516 100644 (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);