| 58 | } |
| 59 | |
| 60 | void flushChanges() override |
| 61 | { |
| 62 | std::vector<CylinderHead> locations; |
| 63 | |
| 64 | for (const auto& trackid : _changedTracks) |
| 65 | { |
| 66 | auto& ltl = _diskLayout->layoutByLogicalLocation.at(trackid); |
| 67 | locations.push_back(trackid); |
| 68 | |
| 69 | /* If we don't have all the sectors of this track, we may need to |
| 70 | * populate any non-changed sectors as we can only write a track at |
| 71 | * a time. */ |
| 72 | |
| 73 | if (!imageContainsAllSectorsOf(_changedSectors, |
| 74 | trackid.cylinder, |
| 75 | trackid.head, |
| 76 | ltl->filesystemSectorOrder)) |
| 77 | { |
| 78 | /* If we don't have any loaded sectors for this track, pre-read |
| 79 | * it. */ |
| 80 | |
| 81 | if (_loadedTracks.find(trackid) == _loadedTracks.end()) |
| 82 | populateSectors(trackid.cylinder, trackid.head); |
| 83 | |
| 84 | /* Now merge the loaded track with the changed one, and write |
| 85 | * the result back. */ |
| 86 | |
| 87 | for (unsigned sectorId : ltl->naturalSectorOrder) |
| 88 | { |
| 89 | if (!_changedSectors.contains(trackid, sectorId)) |
| 90 | _changedSectors.put(trackid, sectorId)->data = |
| 91 | _loadedSectors.get(trackid, sectorId)->data; |
| 92 | } |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | /* We now have complete tracks which can be written. */ |
| 97 | |
| 98 | writeDiskCommand(*_diskLayout, |
| 99 | _changedSectors, |
| 100 | *_encoder, |
| 101 | *_fluxSink, |
| 102 | _decoder.get(), |
| 103 | _fluxSource.get(), |
| 104 | locations); |
| 105 | |
| 106 | discardChanges(); |
| 107 | } |
| 108 | |
| 109 | void discardChanges() override |
| 110 | { |