comparison 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
comparison
equal deleted inserted replaced
553:98077b21a9e1 554:60482f13e627
60 m_cellSize(cellSize), 60 m_cellSize(cellSize),
61 m_width(width), 61 m_width(width),
62 m_height(height), 62 m_height(height),
63 m_headerSize(2 * sizeof(size_t)), 63 m_headerSize(2 * sizeof(size_t)),
64 m_setColumns(0), 64 m_setColumns(0),
65 m_autoClose(false) 65 m_autoClose(false),
66 m_readyToReadColumn(-1)
66 { 67 {
67 Profiler profiler("MatrixFile::MatrixFile", true); 68 Profiler profiler("MatrixFile::MatrixFile", true);
68 69
69 #ifdef DEBUG_MATRIX_FILE 70 #ifdef DEBUG_MATRIX_FILE
70 std::cerr << "MatrixFile::MatrixFile(" << fileBase.toStdString() << ", " << int(mode) << ", " << cellSize << ", " << width << ", " << height << ")" << std::endl; 71 std::cerr << "MatrixFile::MatrixFile(" << fileBase.toStdString() << ", " << int(mode) << ", " << cellSize << ", " << width << ", " << height << ")" << std::endl;
238 << (m_headerSize + m_width * m_height * m_cellSize + m_width) << std::endl; 239 << (m_headerSize + m_width * m_height * m_cellSize + m_width) << std::endl;
239 240
240 std::cerr << "MatrixFile: Total storage " << totalStorage/1024 << "K" << std::endl; 241 std::cerr << "MatrixFile: Total storage " << totalStorage/1024 << "K" << std::endl;
241 #endif 242 #endif
242 243
243 seekTo(0, 0); 244 seekTo(0);
244 } 245 }
245 246
246 void 247 void
247 MatrixFile::close() 248 MatrixFile::close()
248 { 249 {
270 std::cerr << "MatrixFile[" << m_fd << "]::getColumnAt(" << x << ")" << std::endl; 271 std::cerr << "MatrixFile[" << m_fd << "]::getColumnAt(" << x << ")" << std::endl;
271 #endif 272 #endif
272 273
273 Profiler profiler("MatrixFile::getColumnAt"); 274 Profiler profiler("MatrixFile::getColumnAt");
274 275
275 unsigned char set = 0;
276 if (!seekTo(x, 0)) {
277 std::cerr << "ERROR: MatrixFile::getColumnAt(" << x << "): Seek failed" << std::endl;
278 throw FileOperationFailed(m_fileName, "seek");
279 }
280
281 ssize_t r = -1; 276 ssize_t r = -1;
282 r = ::read(m_fd, &set, 1); 277
283 if (r < 0) { 278 if (m_readyToReadColumn < 0 ||
284 ::perror("MatrixFile::getColumnAt: read failed"); 279 size_t(m_readyToReadColumn) != x) {
285 throw FileReadFailed(m_fileName); 280
286 } 281 unsigned char set = 0;
287 if (!set) { 282 if (!seekTo(x)) {
288 std::cerr << "MatrixFile[" << m_fd << "]::getColumnAt(" << x << "): Column has not been set" << std::endl; 283 std::cerr << "ERROR: MatrixFile::getColumnAt(" << x << "): Seek failed" << std::endl;
289 return; 284 throw FileOperationFailed(m_fileName, "seek");
285 }
286
287 r = ::read(m_fd, &set, 1);
288 if (r < 0) {
289 ::perror("MatrixFile::getColumnAt: read failed");
290 throw FileReadFailed(m_fileName);
291 }
292 if (!set) {
293 std::cerr << "MatrixFile[" << m_fd << "]::getColumnAt(" << x << "): Column has not been set" << std::endl;
294 return;
295 }
290 } 296 }
291 297
292 r = ::read(m_fd, data, m_height * m_cellSize); 298 r = ::read(m_fd, data, m_height * m_cellSize);
293 if (r < 0) { 299 if (r < 0) {
294 ::perror("MatrixFile::getColumnAt: read failed"); 300 ::perror("MatrixFile::getColumnAt: read failed");
301 { 307 {
302 if (m_mode == WriteOnly) { 308 if (m_mode == WriteOnly) {
303 return m_setColumns->get(x); 309 return m_setColumns->get(x);
304 } 310 }
305 311
312 if (m_readyToReadColumn >= 0 &&
313 size_t(m_readyToReadColumn) == x) return true;
314
306 Profiler profiler("MatrixFile::haveSetColumnAt"); 315 Profiler profiler("MatrixFile::haveSetColumnAt");
307 316
308 #ifdef DEBUG_MATRIX_FILE_READ_SET 317 #ifdef DEBUG_MATRIX_FILE_READ_SET
309 std::cerr << "MatrixFile[" << m_fd << "]::haveSetColumnAt(" << x << ")" << std::endl; 318 std::cerr << "MatrixFile[" << m_fd << "]::haveSetColumnAt(" << x << ")" << std::endl;
310 // std::cerr << "."; 319 // std::cerr << ".";
311 #endif 320 #endif
312 321
313 unsigned char set = 0; 322 unsigned char set = 0;
314 if (!seekTo(x, 0)) { 323 if (!seekTo(x)) {
315 std::cerr << "ERROR: MatrixFile::haveSetColumnAt(" << x << "): Seek failed" << std::endl; 324 std::cerr << "ERROR: MatrixFile::haveSetColumnAt(" << x << "): Seek failed" << std::endl;
316 throw FileOperationFailed(m_fileName, "seek"); 325 throw FileOperationFailed(m_fileName, "seek");
317 } 326 }
318 327
319 ssize_t r = -1; 328 ssize_t r = -1;
321 if (r < 0) { 330 if (r < 0) {
322 ::perror("MatrixFile::haveSetColumnAt: read failed"); 331 ::perror("MatrixFile::haveSetColumnAt: read failed");
323 throw FileReadFailed(m_fileName); 332 throw FileReadFailed(m_fileName);
324 } 333 }
325 334
335 if (set) m_readyToReadColumn = int(x);
336
326 return set; 337 return set;
327 } 338 }
328 339
329 void 340 void
330 MatrixFile::setColumnAt(size_t x, const void *data) 341 MatrixFile::setColumnAt(size_t x, const void *data)
337 // std::cerr << "."; 348 // std::cerr << ".";
338 #endif 349 #endif
339 350
340 ssize_t w = 0; 351 ssize_t w = 0;
341 352
342 if (!seekTo(x, 0)) { 353 if (!seekTo(x)) {
343 std::cerr << "ERROR: MatrixFile::setColumnAt(" << x << "): Seek failed" << std::endl; 354 std::cerr << "ERROR: MatrixFile::setColumnAt(" << x << "): Seek failed" << std::endl;
344 throw FileOperationFailed(m_fileName, "seek"); 355 throw FileOperationFailed(m_fileName, "seek");
345 } 356 }
346 357
347 unsigned char set = 0; 358 unsigned char set = 0;
363 std::cerr << (int)(((char *)data)[i]) << " "; 374 std::cerr << (int)(((char *)data)[i]) << " ";
364 } 375 }
365 std::cerr << std::endl; 376 std::cerr << std::endl;
366 } 377 }
367 */ 378 */
368 if (!seekTo(x, 0)) { 379 if (!seekTo(x)) {
369 std::cerr << "MatrixFile[" << m_fd << "]::setColumnAt(" << x << "): Seek failed" << std::endl; 380 std::cerr << "MatrixFile[" << m_fd << "]::setColumnAt(" << x << "): Seek failed" << std::endl;
370 throw FileOperationFailed(m_fileName, "seek"); 381 throw FileOperationFailed(m_fileName, "seek");
371 } 382 }
372 383
373 set = 1; 384 set = 1;
393 } 404 }
394 } 405 }
395 } 406 }
396 407
397 bool 408 bool
398 MatrixFile::seekTo(size_t x, size_t y) const 409 MatrixFile::seekTo(size_t x) const
399 { 410 {
400 if (m_fd < 0) { 411 if (m_fd < 0) {
401 std::cerr << "ERROR: MatrixFile::seekTo: File not open" << std::endl; 412 std::cerr << "ERROR: MatrixFile::seekTo: File not open" << std::endl;
402 return false; 413 return false;
403 } 414 }
404 415
405 off_t off = m_headerSize + x * m_height * m_cellSize + x + y * m_cellSize; 416 m_readyToReadColumn = -1; // not ready, unless this is subsequently re-set
417
418 off_t off = m_headerSize + x * m_height * m_cellSize + x;
419
420 if (m_mode == ReadOnly) {
421 std::cerr << "MatrixFile[" << m_fd << "]::seekTo(" << x << "): off = " << off << std::endl;
422 }
406 423
407 #ifdef DEBUG_MATRIX_FILE_READ_SET 424 #ifdef DEBUG_MATRIX_FILE_READ_SET
408 std::cerr << "MatrixFile[" << m_fd << "]::seekTo(" << x << "," << y << "): off = " << off << std::endl; 425 std::cerr << "MatrixFile[" << m_fd << "]::seekTo(" << x << "): off = " << off << std::endl;
409 #endif 426 #endif
410 427
411 if (::lseek(m_fd, off, SEEK_SET) == (off_t)-1) { 428 if (::lseek(m_fd, off, SEEK_SET) == (off_t)-1) {
412 ::perror("Seek failed"); 429 ::perror("Seek failed");
413 std::cerr << "ERROR: MatrixFile::seekTo(" << x << ", " << y 430 std::cerr << "ERROR: MatrixFile::seekTo(" << x
414 << ") = " << off << " failed" << std::endl; 431 << ") = " << off << " failed" << std::endl;
415 return false; 432 return false;
416 } 433 }
417 434
418 return true; 435 return true;