> If read or write fails. Position will left the same. This
authorBruce Momjian <[email protected]>
Wed, 14 Jun 2000 03:19:24 +0000 (03:19 +0000)
committerBruce Momjian <[email protected]>
Wed, 14 Jun 2000 03:19:24 +0000 (03:19 +0000)
> situation is already tracked in File routines, but a little bit
> incorrectly.

> After small survey in Linux kernel code, I am not sure about
> it.  New patch set pos to unknown in the case of read/write
> fails. And do lseek again.

> Here is the full patch for this. This patch reduce amount of
> lseek call ten ti mes for update statement and twenty times for
> select statement. I tested joined up date and count(*) select
> for table with rows > 170000 and 10 indices.  I think this is
> worse of trying. Before lseek calls account for more than 5% o
> f time.  Now they are 0.89 and 0.15 respectevly.
>
> Due to only one file modification patch should be applied in
> src/backedn/stora ge/file/ dir.

-- Sincerely Yours,
Denis Perchine

src/backend/storage/file/fd.c

index fdb2fc57a59d5e6d52bcb2000dfe2381967005fa..b8ad36d0162d2939a0d75ba67263eadb6cfe22ea 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.59 2000/06/02 15:57:24 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.60 2000/06/14 03:19:24 momjian Exp $
  *
  * NOTES:
  *
@@ -95,6 +95,8 @@
 
 #define FileIsNotOpen(file) (VfdCache[file].fd == VFD_CLOSED)
 
+#define FileUnknownPos (-1)
+
 typedef struct vfd
 {
        signed short fd;                        /* current FD, or VFD_CLOSED if none */
@@ -790,6 +792,8 @@ FileRead(File file, char *buffer, int amount)
        returnCode = read(VfdCache[file].fd, buffer, amount);
        if (returnCode > 0)
                VfdCache[file].seekPos += returnCode;
+       else
+               VfdCache[file].seekPos = FileUnknownPos;
 
        return returnCode;
 }
@@ -806,11 +810,12 @@ FileWrite(File file, char *buffer, int amount)
 
        FileAccess(file);
        returnCode = write(VfdCache[file].fd, buffer, amount);
-       if (returnCode > 0)
+       if (returnCode > 0) {
                VfdCache[file].seekPos += returnCode;
-
        /* mark the file as needing fsync */
        VfdCache[file].fdstate |= FD_DIRTY;
+       } else
+               VfdCache[file].seekPos = FileUnknownPos;
 
        return returnCode;
 }
@@ -840,10 +845,26 @@ FileSeek(File file, long offset, int whence)
                        default:
                                elog(ERROR, "FileSeek: invalid whence: %d", whence);
                                break;
-               }
        }
-       else
+       } else
+               switch (whence) {
+                       case SEEK_SET:
+                               if (offset < 0)
+                                       elog(ERROR, "FileSeek: invalid offset: %ld", offset);
+                               if (VfdCache[file].seekPos != offset)
+                                       VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence);
+                               break;
+                       case SEEK_CUR:
+                               if ((offset != 0) || (VfdCache[file].seekPos == FileUnknownPos));
                VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence);
+                               break;
+                       case SEEK_END:
+                               VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence);
+                               break;
+                       default:
+                               elog(ERROR, "FileSeek: invalid whence: %d", whence);
+                               break;
+               }
        return VfdCache[file].seekPos;
 }