Mercurial > hg > svcore
comparison base/MatrixFileCache.cpp @ 91:1dcf41ed3863
* minor changes for win32
| author | Chris Cannam |
|---|---|
| date | Wed, 03 May 2006 16:03:27 +0000 |
| parents | c4e163f911dd |
| children | 27d726916ab3 |
comparison
equal
deleted
inserted
replaced
| 90:c4e163f911dd | 91:1dcf41ed3863 |
|---|---|
| 25 #include <iostream> | 25 #include <iostream> |
| 26 | 26 |
| 27 #include <cstdio> | 27 #include <cstdio> |
| 28 | 28 |
| 29 #include <QFileInfo> | 29 #include <QFileInfo> |
| 30 #include <QFile> | |
| 30 #include <QDir> | 31 #include <QDir> |
| 31 | 32 |
| 32 #define HAVE_MMAP 1 | 33 //#define HAVE_MMAP 1 |
| 33 | 34 |
| 34 #ifdef HAVE_MMAP | 35 #ifdef HAVE_MMAP |
| 35 #include <sys/mman.h> | 36 #include <sys/mman.h> |
| 36 #endif | 37 #endif |
| 38 | |
| 39 std::map<QString, int> MatrixFileCache::m_refcount; | |
| 40 QMutex MatrixFileCache::m_refcountMutex; | |
| 37 | 41 |
| 38 //!!! This class is a work in progress -- it does only as much as we | 42 //!!! This class is a work in progress -- it does only as much as we |
| 39 // need for the current SpectrogramLayer. Slated for substantial | 43 // need for the current SpectrogramLayer. Slated for substantial |
| 40 // refactoring and extension. | 44 // refactoring and extension. |
| 41 | 45 |
| 43 m_fd(-1), | 47 m_fd(-1), |
| 44 m_mode(mode), | 48 m_mode(mode), |
| 45 m_width(0), | 49 m_width(0), |
| 46 m_height(0), | 50 m_height(0), |
| 47 m_headerSize(2 * sizeof(size_t)), | 51 m_headerSize(2 * sizeof(size_t)), |
| 48 m_autoRegionWidth(2048), | 52 m_autoRegionWidth(256), |
| 49 m_off(-1), | 53 m_off(-1), |
| 50 m_rx(0), | 54 m_rx(0), |
| 51 m_rw(0), | 55 m_rw(0), |
| 52 m_userRegion(false), | 56 m_userRegion(false), |
| 53 m_region(0), | 57 m_region(0), |
| 54 m_mmapped(false), | 58 m_mmapped(false), |
| 55 m_mmapSize(0), | 59 m_mmapSize(0), |
| 56 m_mmapOff(0), | 60 m_mmapOff(0), |
| 57 m_preferMmap(true) | 61 m_preferMmap(false) |
| 58 { | 62 { |
| 59 // Ensure header size is a multiple of the size of our data (for | 63 // Ensure header size is a multiple of the size of our data (for |
| 60 // alignment purposes) | 64 // alignment purposes) |
| 61 size_t hs = ((m_headerSize / sizeof(float)) * sizeof(float)); | 65 size_t hs = ((m_headerSize / sizeof(float)) * sizeof(float)); |
| 62 if (hs != m_headerSize) m_headerSize = hs + sizeof(float); | 66 if (hs != m_headerSize) m_headerSize = hs + sizeof(float); |
| 85 std::cerr << "ERROR: MatrixFileCache::MatrixFileCache: " | 89 std::cerr << "ERROR: MatrixFileCache::MatrixFileCache: " |
| 86 << "Failed to open cache file \"" | 90 << "Failed to open cache file \"" |
| 87 << fileName.toStdString() << "\""; | 91 << fileName.toStdString() << "\""; |
| 88 if (mode == ReadWrite) std::cerr << " for writing"; | 92 if (mode == ReadWrite) std::cerr << " for writing"; |
| 89 std::cerr << std::endl; | 93 std::cerr << std::endl; |
| 94 return; | |
| 90 } | 95 } |
| 91 | 96 |
| 92 if (newFile) { | 97 if (newFile) { |
| 93 resize(0, 0); // write header | 98 resize(0, 0); // write header |
| 94 } else { | 99 } else { |
| 103 m_width = header[0]; | 108 m_width = header[0]; |
| 104 m_height = header[1]; | 109 m_height = header[1]; |
| 105 seekTo(0, 0); | 110 seekTo(0, 0); |
| 106 } | 111 } |
| 107 | 112 |
| 113 m_fileName = fileName; | |
| 114 QMutexLocker locker(&m_refcountMutex); | |
| 115 ++m_refcount[fileName]; | |
| 116 | |
| 108 std::cerr << "MatrixFileCache::MatrixFileCache: Done, size is " << "(" << m_width << ", " << m_height << ")" << std::endl; | 117 std::cerr << "MatrixFileCache::MatrixFileCache: Done, size is " << "(" << m_width << ", " << m_height << ")" << std::endl; |
| 109 | 118 |
| 110 } | 119 } |
| 111 | 120 |
| 112 MatrixFileCache::~MatrixFileCache() | 121 MatrixFileCache::~MatrixFileCache() |
| 125 if (::close(m_fd) < 0) { | 134 if (::close(m_fd) < 0) { |
| 126 ::perror("MatrixFileCache::~MatrixFileCache: close failed"); | 135 ::perror("MatrixFileCache::~MatrixFileCache: close failed"); |
| 127 } | 136 } |
| 128 } | 137 } |
| 129 | 138 |
| 130 //!!! refcount and unlink | 139 if (m_fileName != "") { |
| 140 QMutexLocker locker(&m_refcountMutex); | |
| 141 if (--m_refcount[m_fileName] == 0) { | |
| 142 if (!QFile(m_fileName).remove()) { | |
| 143 std::cerr << "WARNING: MatrixFileCache::~MatrixFileCache: reference count reached 0, but failed to unlink file \"" << m_fileName.toStdString() << "\"" << std::endl; | |
| 144 } else { | |
| 145 std::cerr << "deleted " << m_fileName.toStdString() << std::endl; | |
| 146 } | |
| 147 } | |
| 148 } | |
| 131 } | 149 } |
| 132 | 150 |
| 133 size_t | 151 size_t |
| 134 MatrixFileCache::getWidth() const | 152 MatrixFileCache::getWidth() const |
| 135 { | 153 { |
| 245 if (rp) return *rp; | 263 if (rp) return *rp; |
| 246 } else if (!m_userRegion) { | 264 } else if (!m_userRegion) { |
| 247 if (autoSetRegion(x)) { | 265 if (autoSetRegion(x)) { |
| 248 float *rp = getRegionPtr(x, y); | 266 float *rp = getRegionPtr(x, y); |
| 249 if (rp) return *rp; | 267 if (rp) return *rp; |
| 268 else return 0.f; | |
| 250 } | 269 } |
| 251 } | 270 } |
| 252 | 271 |
| 253 if (!seekTo(x, y)) return 0.f; | 272 if (!seekTo(x, y)) return 0.f; |
| 254 float value; | 273 float value; |
| 255 ssize_t r = ::read(m_fd, &value, sizeof(float)); | 274 ssize_t r = ::read(m_fd, &value, sizeof(float)); |
| 275 if (r < 0) { | |
| 276 ::perror("MatrixFileCache::getValueAt: Read failed"); | |
| 277 } | |
| 256 if (r != sizeof(float)) { | 278 if (r != sizeof(float)) { |
| 257 ::perror("MatrixFileCache::getValueAt: read failed"); | |
| 258 value = 0.f; | 279 value = 0.f; |
| 259 } | 280 } |
| 260 if (r > 0) m_off += r; | 281 if (r > 0) m_off += r; |
| 261 return value; | 282 return value; |
| 262 } | 283 } |
| 268 float *rp = getRegionPtr(x, 0); | 289 float *rp = getRegionPtr(x, 0); |
| 269 if (rp) { | 290 if (rp) { |
| 270 for (size_t y = 0; y < m_height; ++y) { | 291 for (size_t y = 0; y < m_height; ++y) { |
| 271 values[y] = rp[y]; | 292 values[y] = rp[y]; |
| 272 } | 293 } |
| 273 return; | 294 } |
| 274 } | 295 return; |
| 275 } else if (!m_userRegion) { | 296 } else if (!m_userRegion) { |
| 276 if (autoSetRegion(x)) { | 297 if (autoSetRegion(x)) { |
| 277 float *rp = getRegionPtr(x, 0); | 298 float *rp = getRegionPtr(x, 0); |
| 278 if (rp) { | 299 if (rp) { |
| 279 for (size_t y = 0; y < m_height; ++y) { | 300 for (size_t y = 0; y < m_height; ++y) { |
| 284 } | 305 } |
| 285 } | 306 } |
| 286 | 307 |
| 287 if (!seekTo(x, 0)) return; | 308 if (!seekTo(x, 0)) return; |
| 288 ssize_t r = ::read(m_fd, values, m_height * sizeof(float)); | 309 ssize_t r = ::read(m_fd, values, m_height * sizeof(float)); |
| 289 if (r != m_height * sizeof(float)) { | 310 if (r < 0) { |
| 290 ::perror("MatrixFileCache::getColumnAt: read failed"); | 311 ::perror("MatrixFileCache::getColumnAt: read failed"); |
| 291 } | 312 } |
| 292 if (r > 0) m_off += r; | 313 if (r > 0) m_off += r; |
| 293 } | 314 } |
| 294 | 315 |
| 320 return; | 341 return; |
| 321 } | 342 } |
| 322 | 343 |
| 323 if (!seekTo(x, 0)) return; | 344 if (!seekTo(x, 0)) return; |
| 324 ssize_t w = ::write(m_fd, values, m_height * sizeof(float)); | 345 ssize_t w = ::write(m_fd, values, m_height * sizeof(float)); |
| 325 if (w != m_height * sizeof(float)) { | 346 if (w != ssize_t(m_height * sizeof(float))) { |
| 326 ::perror("WARNING: MatrixFileCache::setColumnAt: write failed"); | 347 ::perror("WARNING: MatrixFileCache::setColumnAt: write failed"); |
| 327 } | 348 } |
| 328 if (w > 0) m_off += w; | 349 if (w > 0) m_off += w; |
| 329 | 350 |
| 330 //... update region as appropriate | 351 //... update region as appropriate |
| 420 m_mmapSize = mmapSize; | 441 m_mmapSize = mmapSize; |
| 421 m_mmapOff = mmapOff; | 442 m_mmapOff = mmapOff; |
| 422 m_rx = x; | 443 m_rx = x; |
| 423 m_rw = width; | 444 m_rw = width; |
| 424 if (user) m_userRegion = true; | 445 if (user) m_userRegion = true; |
| 425 // MUNLOCK(m_region, m_mmapSize); | 446 MUNLOCK(m_region, m_mmapSize); |
| 426 return true; | 447 return true; |
| 427 } | 448 } |
| 428 } | 449 } |
| 429 #endif | 450 #endif |
| 430 | 451 |
| 431 if (!seekTo(x, 0)) return false; | 452 if (!seekTo(x, 0)) return false; |
| 432 | 453 |
| 433 m_region = new float[width * m_height]; | 454 m_region = new float[width * m_height]; |
| 455 MUNLOCK(m_region, width * m_height * sizeof(float)); | |
| 434 | 456 |
| 435 ssize_t r = ::read(m_fd, m_region, width * m_height * sizeof(float)); | 457 ssize_t r = ::read(m_fd, m_region, width * m_height * sizeof(float)); |
| 436 if (r < 0) { | 458 if (r < 0) { |
| 437 ::perror("Read failed"); | 459 ::perror("Read failed"); |
| 438 std::cerr << "ERROR: MatrixFileCache::setRegion(" << x << ", " << width | 460 std::cerr << "ERROR: MatrixFileCache::setRegion(" << x << ", " << width |
| 442 return false; | 464 return false; |
| 443 } | 465 } |
| 444 | 466 |
| 445 m_off += r; | 467 m_off += r; |
| 446 | 468 |
| 447 if (r < width * m_height * sizeof(float)) { | 469 if (r < ssize_t(width * m_height * sizeof(float))) { |
| 448 // didn't manage to read the whole thing, but did get something | 470 // didn't manage to read the whole thing, but did get something |
| 449 std::cerr << "WARNING: MatrixFileCache::setRegion(" << x << ", " << width | 471 std::cerr << "WARNING: MatrixFileCache::setRegion(" << x << ", " << width |
| 450 << "): "; | 472 << "): "; |
| 451 width = r / (m_height * sizeof(float)); | 473 width = r / (m_height * sizeof(float)); |
| 452 std::cerr << "Only got " << width << " columns" << std::endl; | 474 std::cerr << "Only got " << width << " columns" << std::endl; |
| 460 } | 482 } |
| 461 | 483 |
| 462 std::cerr << "MatrixFileCache::setRegion: set region to " << x << ", " << width << std::endl; | 484 std::cerr << "MatrixFileCache::setRegion: set region to " << x << ", " << width << std::endl; |
| 463 | 485 |
| 464 if (user) m_userRegion = true; | 486 if (user) m_userRegion = true; |
| 465 if (m_rw > 0) MUNLOCK(m_region, m_rw * m_height); | |
| 466 return true; | 487 return true; |
| 467 } | 488 } |
| 468 | 489 |
| 469 bool | 490 bool |
| 470 MatrixFileCache::seekTo(size_t x, size_t y) const | 491 MatrixFileCache::seekTo(size_t x, size_t y) const |
