diff data/fileio/MatrixFile.cpp @ 554:60482f13e627

* Some changes and debug toward reducing backward seeks (v. slow on os/x apparently)
author Chris Cannam
date Sun, 08 Feb 2009 20:03:54 +0000
parents 107d3f3705c9
children 8accc7969c1c
line wrap: on
line diff
--- a/data/fileio/MatrixFile.cpp	Fri Feb 06 15:06:23 2009 +0000
+++ b/data/fileio/MatrixFile.cpp	Sun Feb 08 20:03:54 2009 +0000
@@ -62,7 +62,8 @@
     m_height(height),
     m_headerSize(2 * sizeof(size_t)),
     m_setColumns(0),
-    m_autoClose(false)
+    m_autoClose(false),
+    m_readyToReadColumn(-1)
 {
     Profiler profiler("MatrixFile::MatrixFile", true);
 
@@ -240,7 +241,7 @@
     std::cerr << "MatrixFile: Total storage " << totalStorage/1024 << "K" << std::endl;
 #endif
 
-    seekTo(0, 0);
+    seekTo(0);
 }
 
 void
@@ -272,21 +273,26 @@
 
     Profiler profiler("MatrixFile::getColumnAt");
 
-    unsigned char set = 0;
-    if (!seekTo(x, 0)) {
-        std::cerr << "ERROR: MatrixFile::getColumnAt(" << x << "): Seek failed" << std::endl;
-        throw FileOperationFailed(m_fileName, "seek");
-    }
+    ssize_t r = -1;
 
-    ssize_t r = -1;
-    r = ::read(m_fd, &set, 1);
-    if (r < 0) {
-        ::perror("MatrixFile::getColumnAt: read failed");
-        throw FileReadFailed(m_fileName);
-    }
-    if (!set) {
-        std::cerr << "MatrixFile[" << m_fd << "]::getColumnAt(" << x << "): Column has not been set" << std::endl;
-        return;
+    if (m_readyToReadColumn < 0 ||
+        size_t(m_readyToReadColumn) != x) {
+
+        unsigned char set = 0;
+        if (!seekTo(x)) {
+            std::cerr << "ERROR: MatrixFile::getColumnAt(" << x << "): Seek failed" << std::endl;
+            throw FileOperationFailed(m_fileName, "seek");
+        }
+
+        r = ::read(m_fd, &set, 1);
+        if (r < 0) {
+            ::perror("MatrixFile::getColumnAt: read failed");
+            throw FileReadFailed(m_fileName);
+        }
+        if (!set) {
+            std::cerr << "MatrixFile[" << m_fd << "]::getColumnAt(" << x << "): Column has not been set" << std::endl;
+            return;
+        }
     }
 
     r = ::read(m_fd, data, m_height * m_cellSize);
@@ -303,6 +309,9 @@
         return m_setColumns->get(x);
     }
 
+    if (m_readyToReadColumn >= 0 &&
+        size_t(m_readyToReadColumn) == x) return true;
+    
     Profiler profiler("MatrixFile::haveSetColumnAt");
 
 #ifdef DEBUG_MATRIX_FILE_READ_SET
@@ -311,7 +320,7 @@
 #endif
 
     unsigned char set = 0;
-    if (!seekTo(x, 0)) {
+    if (!seekTo(x)) {
         std::cerr << "ERROR: MatrixFile::haveSetColumnAt(" << x << "): Seek failed" << std::endl;
         throw FileOperationFailed(m_fileName, "seek");
     }
@@ -323,6 +332,8 @@
         throw FileReadFailed(m_fileName);
     }
 
+    if (set) m_readyToReadColumn = int(x);
+
     return set;
 }
 
@@ -339,7 +350,7 @@
 
     ssize_t w = 0;
 
-    if (!seekTo(x, 0)) {
+    if (!seekTo(x)) {
         std::cerr << "ERROR: MatrixFile::setColumnAt(" << x << "): Seek failed" << std::endl;
         throw FileOperationFailed(m_fileName, "seek");
     }
@@ -365,7 +376,7 @@
         std::cerr << std::endl;
     }
 */
-    if (!seekTo(x, 0)) {
+    if (!seekTo(x)) {
         std::cerr << "MatrixFile[" << m_fd << "]::setColumnAt(" << x << "): Seek failed" << std::endl;
         throw FileOperationFailed(m_fileName, "seek");
     }
@@ -395,22 +406,28 @@
 }
 
 bool
-MatrixFile::seekTo(size_t x, size_t y) const
+MatrixFile::seekTo(size_t x) const
 {
     if (m_fd < 0) {
         std::cerr << "ERROR: MatrixFile::seekTo: File not open" << std::endl;
         return false;
     }
 
-    off_t off = m_headerSize + x * m_height * m_cellSize + x + y * m_cellSize;
+    m_readyToReadColumn = -1; // not ready, unless this is subsequently re-set
+
+    off_t off = m_headerSize + x * m_height * m_cellSize + x;
+
+    if (m_mode == ReadOnly) {
+        std::cerr << "MatrixFile[" << m_fd << "]::seekTo(" << x << "): off = " << off << std::endl;
+    }
 
 #ifdef DEBUG_MATRIX_FILE_READ_SET
-    std::cerr << "MatrixFile[" << m_fd << "]::seekTo(" << x << "," << y << "): off = " << off << std::endl;
+    std::cerr << "MatrixFile[" << m_fd << "]::seekTo(" << x << "): off = " << off << std::endl;
 #endif
 
     if (::lseek(m_fd, off, SEEK_SET) == (off_t)-1) {
         ::perror("Seek failed");
-        std::cerr << "ERROR: MatrixFile::seekTo(" << x << ", " << y
+        std::cerr << "ERROR: MatrixFile::seekTo(" << x 
                   << ") = " << off << " failed" << std::endl;
         return false;
     }