| 359 | }; |
| 360 | |
| 361 | static ReadGroupResult readGroup(const DiskLayout& diskLayout, |
| 362 | FluxSourceIteratorHolder& fluxSourceIteratorHolder, |
| 363 | const std::shared_ptr<const LogicalTrackLayout>& ltl, |
| 364 | std::vector<std::shared_ptr<const Track>>& tracks, |
| 365 | Decoder& decoder) |
| 366 | { |
| 367 | ReadGroupResult rgr = {BAD_AND_CAN_NOT_RETRY}; |
| 368 | |
| 369 | /* Before doing the read, look to see if we already have the necessary |
| 370 | * sectors. */ |
| 371 | |
| 372 | { |
| 373 | auto [result, sectors] = combineRecordAndSectors(tracks, decoder, ltl); |
| 374 | rgr.combinedSectors = sectors; |
| 375 | if (result == HAS_NO_BAD_SECTORS) |
| 376 | { |
| 377 | /* We have all necessary sectors, so can stop here. */ |
| 378 | rgr.result = GOOD_READ; |
| 379 | if (globalConfig()->decoder().skip_unnecessary_tracks()) |
| 380 | return rgr; |
| 381 | } |
| 382 | } |
| 383 | |
| 384 | for (unsigned offset = 0; offset < ltl->groupSize; |
| 385 | offset += diskLayout.headWidth) |
| 386 | { |
| 387 | unsigned physicalCylinder = ltl->physicalCylinder + offset; |
| 388 | unsigned physicalHead = ltl->physicalHead; |
| 389 | auto& ptl = diskLayout.layoutByPhysicalLocation.at( |
| 390 | {physicalCylinder, physicalHead}); |
| 391 | |
| 392 | /* Do the physical read. */ |
| 393 | |
| 394 | log(BeginReadOperationLogMessage{physicalCylinder, physicalHead}); |
| 395 | |
| 396 | auto& fluxSourceIterator = fluxSourceIteratorHolder.getIterator( |
| 397 | physicalCylinder, physicalHead); |
| 398 | if (!fluxSourceIterator.hasNext()) |
| 399 | continue; |
| 400 | |
| 401 | auto fluxmap = fluxSourceIterator.next(); |
| 402 | log(EndReadOperationLogMessage()); |
| 403 | log("{0} ms in {1} bytes", |
| 404 | (int)(fluxmap->duration() / 1e6), |
| 405 | fluxmap->bytes()); |
| 406 | |
| 407 | auto flux = decoder.decodeToSectors(std::move(fluxmap), ptl); |
| 408 | flux->normalisedSectors = collectSectors(flux->allSectors); |
| 409 | tracks.push_back(flux); |
| 410 | |
| 411 | /* Decode what we've got so far. */ |
| 412 | |
| 413 | auto [result, sectors] = combineRecordAndSectors(tracks, decoder, ltl); |
| 414 | rgr.combinedSectors = sectors; |
| 415 | if (result == HAS_NO_BAD_SECTORS) |
| 416 | { |
| 417 | /* We have all necessary sectors, so can stop here. */ |
| 418 | rgr.result = GOOD_READ; |
no test coverage detected