# HG changeset patch # User Chris Cannam # Date 1234179488 0 # Node ID 8accc7969c1c23eee0667a38a49c9acfc7b8b80a # Parent 60482f13e62735777fb9dcabda5d752ea00c4bdc * Some steps to avoid backward seeks in MatrixFile in common use cases diff -r 60482f13e627 -r 8accc7969c1c data/fft/FFTFileCacheReader.cpp --- a/data/fft/FFTFileCacheReader.cpp Sun Feb 08 20:03:54 2009 +0000 +++ b/data/fft/FFTFileCacheReader.cpp Mon Feb 09 11:38:08 2009 +0000 @@ -34,6 +34,7 @@ m_readbuf(0), m_readbufCol(0), m_readbufWidth(0), + m_readbufGood(false), m_storageType(writer->getStorageType()), m_factorSize(m_storageType == FFTCache::Compact ? 2 : 1), m_mfc(new MatrixFile @@ -156,6 +157,8 @@ void FFTFileCacheReader::getValuesAt(size_t x, size_t y, float &real, float &imag) const { +// std::cerr << "FFTFileCacheReader::getValuesAt(" << x << "," << y << ")" << std::endl; + switch (m_storageType) { case FFTCache::Rectangular: @@ -211,6 +214,11 @@ bool FFTFileCacheReader::haveSetColumnAt(size_t x) const { + if (m_readbuf && m_readbufGood && + (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) { +// std::cerr << "FFTFileCacheReader::haveSetColumnAt: short-circuiting; we know about this one" << std::endl; + return true; + } return m_mfc->haveSetColumnAt(x); } @@ -228,14 +236,28 @@ { Profiler profiler("FFTFileCacheReader::populateReadBuf", false); - std::cerr << "FFTFileCacheReader::populateReadBuf(" << x << ")" << std::endl; +// std::cerr << "FFTFileCacheReader::populateReadBuf(" << x << ")" << std::endl; if (!m_readbuf) { m_readbuf = new char[m_mfc->getHeight() * 2 * m_mfc->getCellSize()]; } + m_readbufGood = false; + try { - m_mfc->getColumnAt(x, m_readbuf); + bool good = false; + if (m_mfc->haveSetColumnAt(x)) { + // If the column is not available, we have no obligation + // to do anything with the readbuf -- we can cheerfully + // return garbage. It's the responsibility of the caller + // to check haveSetColumnAt before trusting any retrieved + // data. However, we do record whether the data in the + // readbuf is good or not, because we can use that to + // return an immediate result for haveSetColumnAt if the + // column is right. + good = true; + m_mfc->getColumnAt(x, m_readbuf); + } if (m_mfc->haveSetColumnAt(x + 1)) { m_mfc->getColumnAt (x + 1, m_readbuf + m_mfc->getCellSize() * m_mfc->getHeight()); @@ -243,6 +265,7 @@ } else { m_readbufWidth = 1; } + m_readbufGood = good; } catch (FileReadFailed f) { std::cerr << "ERROR: FFTFileCacheReader::populateReadBuf: File read failed: " << f.what() << std::endl; diff -r 60482f13e627 -r 8accc7969c1c data/fft/FFTFileCacheReader.h --- a/data/fft/FFTFileCacheReader.h Sun Feb 08 20:03:54 2009 +0000 +++ b/data/fft/FFTFileCacheReader.h Mon Feb 09 11:38:08 2009 +0000 @@ -50,6 +50,7 @@ mutable char *m_readbuf; mutable size_t m_readbufCol; mutable size_t m_readbufWidth; + mutable bool m_readbufGood; float getFromReadBufStandard(size_t x, size_t y) const { float v; diff -r 60482f13e627 -r 8accc7969c1c data/fileio/MatrixFile.cpp --- a/data/fileio/MatrixFile.cpp Sun Feb 08 20:03:54 2009 +0000 +++ b/data/fileio/MatrixFile.cpp Mon Feb 09 11:38:08 2009 +0000 @@ -417,9 +417,11 @@ off_t off = m_headerSize + x * m_height * m_cellSize + x; +#ifdef DEBUG_MATRIX_FILE_READ_SET if (m_mode == ReadOnly) { std::cerr << "MatrixFile[" << m_fd << "]::seekTo(" << x << "): off = " << off << std::endl; } +#endif #ifdef DEBUG_MATRIX_FILE_READ_SET std::cerr << "MatrixFile[" << m_fd << "]::seekTo(" << x << "): off = " << off << std::endl;