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 |