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