Rework the flux data structures to be a bit more sensibly designed and

more amenable to copying.
This commit is contained in:
David Given
2025-10-06 22:58:24 +02:00
parent 38618532c4
commit cff0a9703c
10 changed files with 169 additions and 136 deletions

View File

@@ -84,11 +84,9 @@ void renderLogMessage(
void renderLogMessage( void renderLogMessage(
LogRenderer& r, std::shared_ptr<const TrackReadLogMessage> m) LogRenderer& r, std::shared_ptr<const TrackReadLogMessage> m)
{ {
const auto& track = *m->track;
std::set<std::shared_ptr<const Sector>> rawSectors; std::set<std::shared_ptr<const Sector>> rawSectors;
std::set<std::shared_ptr<const Record>> rawRecords; std::set<std::shared_ptr<const Record>> rawRecords;
for (const auto& trackDataFlux : track.trackDatas) for (const auto& trackDataFlux : m->fluxes)
{ {
rawSectors.insert( rawSectors.insert(
trackDataFlux->sectors.begin(), trackDataFlux->sectors.end()); trackDataFlux->sectors.begin(), trackDataFlux->sectors.end());
@@ -114,7 +112,7 @@ void renderLogMessage(
r.newline().add("sectors:"); r.newline().add("sectors:");
std::vector<std::shared_ptr<const Sector>> sectors( std::vector<std::shared_ptr<const Sector>> sectors(
track.sectors.begin(), track.sectors.end()); m->sectors.begin(), m->sectors.end());
std::sort(sectors.begin(), sectors.end(), sectorPointerSortPredicate); std::sort(sectors.begin(), sectors.end(), sectorPointerSortPredicate);
for (const auto& sector : sectors) for (const auto& sector : sectors)
@@ -126,7 +124,7 @@ void renderLogMessage(
int size = 0; int size = 0;
std::set<std::pair<int, int>> track_ids; std::set<std::pair<int, int>> track_ids;
for (const auto& sector : m->track->sectors) for (const auto& sector : m->sectors)
{ {
track_ids.insert( track_ids.insert(
std::make_pair(sector->logicalCylinder, sector->logicalHead)); std::make_pair(sector->logicalCylinder, sector->logicalHead));
@@ -229,14 +227,14 @@ void measureDiskRotation()
/* Given a set of sectors, deduplicates them sensibly (e.g. if there is a good /* Given a set of sectors, deduplicates them sensibly (e.g. if there is a good
* and bad version of the same sector, the bad version is dropped). */ * and bad version of the same sector, the bad version is dropped). */
static std::set<std::shared_ptr<const Sector>> collectSectors( static std::vector<std::shared_ptr<const Sector>> collectSectors(
std::set<std::shared_ptr<const Sector>>& track_sectors, std::vector<std::shared_ptr<const Sector>>& trackSectors,
bool collapse_conflicts = true) bool collapse_conflicts = true)
{ {
typedef std::tuple<unsigned, unsigned, unsigned> key_t; typedef std::tuple<unsigned, unsigned, unsigned> key_t;
std::multimap<key_t, std::shared_ptr<const Sector>> sectors; std::multimap<key_t, std::shared_ptr<const Sector>> sectors;
for (const auto& sector : track_sectors) for (const auto& sector : trackSectors)
{ {
key_t sectorid = {sector->logicalCylinder, key_t sectorid = {sector->logicalCylinder,
sector->logicalHead, sector->logicalHead,
@@ -282,20 +280,28 @@ static std::set<std::shared_ptr<const Sector>> collectSectors(
sector_set.insert(new_sector); sector_set.insert(new_sector);
it = ub; it = ub;
} }
return sector_set; return sector_set | std::ranges::to<std::vector>();
} }
BadSectorsState combineRecordAndSectors(TrackFlux& trackFlux, struct CombinationResult
{
BadSectorsState result;
std::vector<std::shared_ptr<const Sector>> sectors;
};
static CombinationResult combineRecordAndSectors(
std::vector<std::shared_ptr<const TrackDataFlux>>& fluxes,
Decoder& decoder, Decoder& decoder,
std::shared_ptr<const TrackInfo>& trackLayout) std::shared_ptr<const TrackInfo>& trackLayout)
{ {
std::set<std::shared_ptr<const Sector>> track_sectors; CombinationResult cr = {HAS_NO_BAD_SECTORS};
std::vector<std::shared_ptr<const Sector>> track_sectors;
/* Add the sectors which were there. */ /* Add the sectors which were there. */
for (auto& trackdataflux : trackFlux.trackDatas) for (auto& trackdataflux : fluxes)
track_sectors.insert( for (auto& sector : trackdataflux->sectors)
trackdataflux->sectors.begin(), trackdataflux->sectors.end()); track_sectors.push_back(sector);
/* Add the sectors which should be there. */ /* Add the sectors which should be there. */
@@ -307,19 +313,19 @@ BadSectorsState combineRecordAndSectors(TrackFlux& trackFlux,
sectorId}); sectorId});
sector->status = Sector::MISSING; sector->status = Sector::MISSING;
track_sectors.insert(sector); track_sectors.push_back(sector);
} }
/* Deduplicate. */ /* Deduplicate. */
trackFlux.sectors = collectSectors(track_sectors); cr.sectors = collectSectors(track_sectors);
if (trackFlux.sectors.empty()) if (cr.sectors.empty())
return HAS_BAD_SECTORS; cr.result = HAS_BAD_SECTORS;
for (const auto& sector : trackFlux.sectors) for (const auto& sector : cr.sectors)
if (sector->status != Sector::OK) if (sector->status != Sector::OK)
return HAS_BAD_SECTORS; cr.result = HAS_BAD_SECTORS;
return HAS_NO_BAD_SECTORS; return cr;
} }
static void adjustTrackOnError(FluxSource& fluxSource, int baseTrack) static void adjustTrackOnError(FluxSource& fluxSource, int baseTrack)
@@ -342,16 +348,25 @@ static void adjustTrackOnError(FluxSource& fluxSource, int baseTrack)
} }
} }
ReadResult readGroup(FluxSourceIteratorHolder& fluxSourceIteratorHolder, struct ReadGroupResult
{
ReadResult result;
std::vector<std::shared_ptr<const Sector>> sectors;
};
static ReadGroupResult readGroup(
FluxSourceIteratorHolder& fluxSourceIteratorHolder,
std::shared_ptr<const TrackInfo>& trackInfo, std::shared_ptr<const TrackInfo>& trackInfo,
TrackFlux& trackFlux, std::vector<std::shared_ptr<const TrackDataFlux>>& fluxes,
Decoder& decoder) Decoder& decoder)
{ {
ReadResult result = BAD_AND_CAN_NOT_RETRY; ReadGroupResult rgr = {BAD_AND_CAN_NOT_RETRY};
for (unsigned offset = 0; offset < trackInfo->groupSize; for (unsigned offset = 0; offset < trackInfo->groupSize;
offset += Layout::getHeadWidth()) offset += Layout::getHeadWidth())
{ {
/* Do the physical read. */
log(BeginReadOperationLogMessage{ log(BeginReadOperationLogMessage{
trackInfo->physicalCylinder + offset, trackInfo->physicalHead}); trackInfo->physicalCylinder + offset, trackInfo->physicalHead});
@@ -360,28 +375,36 @@ ReadResult readGroup(FluxSourceIteratorHolder& fluxSourceIteratorHolder,
if (!fluxSourceIterator.hasNext()) if (!fluxSourceIterator.hasNext())
continue; continue;
std::shared_ptr<const Fluxmap> fluxmap = fluxSourceIterator.next(); auto fluxmap = fluxSourceIterator.next();
// ->rescale(
// 1.0 / globalConfig()->flux_source().rescale());
log(EndReadOperationLogMessage()); log(EndReadOperationLogMessage());
log("{0} ms in {1} bytes", log("{0} ms in {1} bytes",
(int)(fluxmap->duration() / 1e6), (int)(fluxmap->duration() / 1e6),
fluxmap->bytes()); fluxmap->bytes());
auto trackdataflux = decoder.decodeToSectors(fluxmap, trackInfo); auto flux = decoder.decodeToSectors(std::move(fluxmap), trackInfo);
trackFlux.trackDatas.push_back(trackdataflux); fluxes.push_back(flux);
if (combineRecordAndSectors(trackFlux, decoder, trackInfo) ==
HAS_NO_BAD_SECTORS) /* Decode what we've got so far. */
auto [result, sectors] =
combineRecordAndSectors(fluxes, decoder, trackInfo);
rgr.sectors = sectors;
if (result == HAS_NO_BAD_SECTORS)
{ {
result = GOOD_READ; /* We have all necessary sectors, so can stop here. */
rgr.result = GOOD_READ;
if (globalConfig()->decoder().skip_unnecessary_tracks()) if (globalConfig()->decoder().skip_unnecessary_tracks())
return result; break;
} }
else if (fluxSourceIterator.hasNext()) else if (fluxSourceIterator.hasNext())
result = BAD_AND_CAN_RETRY; {
/* The flux source claims it can do more reads, so mark this group
* as being retryable. */
rgr.result = BAD_AND_CAN_RETRY;
}
} }
return result; return rgr;
} }
void writeTracks(FluxSink& fluxSink, void writeTracks(FluxSink& fluxSink,
@@ -490,12 +513,11 @@ void writeTracksAndVerify(FluxSink& fluxSink,
}, },
[&](std::shared_ptr<const TrackInfo>& trackInfo) [&](std::shared_ptr<const TrackInfo>& trackInfo)
{ {
auto trackFlux = std::make_shared<TrackFlux>();
trackFlux->trackInfo = trackInfo;
FluxSourceIteratorHolder fluxSourceIteratorHolder(fluxSource); FluxSourceIteratorHolder fluxSourceIteratorHolder(fluxSource);
auto result = readGroup( std::vector<std::shared_ptr<const TrackDataFlux>> fluxes;
fluxSourceIteratorHolder, trackInfo, *trackFlux, decoder); auto [result, sectors] =
log(TrackReadLogMessage{trackFlux}); readGroup(fluxSourceIteratorHolder, trackInfo, fluxes, decoder);
log(TrackReadLogMessage{fluxes, sectors});
if (result != GOOD_READ) if (result != GOOD_READ)
{ {
@@ -512,7 +534,7 @@ void writeTracksAndVerify(FluxSink& fluxSink,
sector->logicalSector) sector->logicalSector)
->data = sector->data; ->data = sector->data;
for (const auto& sector : trackFlux->sectors) for (const auto& sector : sectors)
{ {
const auto s = wanted.get(sector->logicalCylinder, const auto s = wanted.get(sector->logicalCylinder,
sector->logicalHead, sector->logicalHead,
@@ -585,12 +607,11 @@ void writeRawDiskCommand(FluxSource& fluxSource, FluxSink& fluxSink)
trackinfos); trackinfos);
} }
std::shared_ptr<TrackFlux> readAndDecodeTrack(FluxSource& fluxSource, FluxAndSectors readAndDecodeTrack(FluxSource& fluxSource,
Decoder& decoder, Decoder& decoder,
std::shared_ptr<const TrackInfo>& trackInfo) std::shared_ptr<const TrackInfo>& trackInfo)
{ {
auto trackFlux = std::make_shared<TrackFlux>(); FluxAndSectors fas;
trackFlux->trackInfo = trackInfo;
if (fluxSource.isHardware()) if (fluxSource.isHardware())
measureDiskRotation(); measureDiskRotation();
@@ -599,8 +620,10 @@ std::shared_ptr<TrackFlux> readAndDecodeTrack(FluxSource& fluxSource,
int retriesRemaining = globalConfig()->decoder().retries(); int retriesRemaining = globalConfig()->decoder().retries();
for (;;) for (;;)
{ {
auto result = auto [result, sectors] =
readGroup(fluxSourceIteratorHolder, trackInfo, *trackFlux, decoder); readGroup(fluxSourceIteratorHolder, trackInfo, fas.fluxes, decoder);
std::copy(
sectors.begin(), sectors.end(), std::back_inserter(fas.sectors));
if (result == GOOD_READ) if (result == GOOD_READ)
break; break;
if (result == BAD_AND_CAN_NOT_RETRY) if (result == BAD_AND_CAN_NOT_RETRY)
@@ -623,24 +646,24 @@ std::shared_ptr<TrackFlux> readAndDecodeTrack(FluxSource& fluxSource,
} }
} }
return trackFlux; return fas;
} }
std::shared_ptr<const DiskFlux> readDiskCommand( void readDiskCommand(
FluxSource& fluxSource, Decoder& decoder) FluxSource& fluxSource, Decoder& decoder, DiskFlux& diskflux)
{ {
std::unique_ptr<FluxSink> outputFluxSink; std::unique_ptr<FluxSink> outputFluxSink;
if (globalConfig()->decoder().has_copy_flux_to()) if (globalConfig()->decoder().has_copy_flux_to())
outputFluxSink = outputFluxSink =
FluxSink::create(globalConfig()->decoder().copy_flux_to()); FluxSink::create(globalConfig()->decoder().copy_flux_to());
auto diskflux = std::make_shared<DiskFlux>(); if (!diskflux.layout)
diskflux->layout = createDiskLayout(); diskflux.layout = createDiskLayout();
log(BeginOperationLogMessage{"Reading and decoding disk"}); log(BeginOperationLogMessage{"Reading and decoding disk"});
auto physicalLocations = Layout::computePhysicalLocations(); auto physicalLocations = Layout::computePhysicalLocations();
unsigned index = 0; unsigned index = 0;
for (auto& physicalLocation : physicalLocations) for (auto physicalLocation : physicalLocations)
{ {
auto trackInfo = Layout::getLayoutOfTrackPhysical( auto trackInfo = Layout::getLayoutOfTrackPhysical(
physicalLocation.cylinder, physicalLocation.head); physicalLocation.cylinder, physicalLocation.head);
@@ -651,12 +674,16 @@ std::shared_ptr<const DiskFlux> readDiskCommand(
testForEmergencyStop(); testForEmergencyStop();
auto trackFlux = readAndDecodeTrack(fluxSource, decoder, trackInfo); auto [trackFluxes, trackSectors] =
diskflux->tracks.push_back(trackFlux); readAndDecodeTrack(fluxSource, decoder, trackInfo);
for (const auto& flux : trackFluxes)
diskflux.fluxesByTrack.insert(std::pair{physicalLocation, flux});
for (const auto& sector : trackSectors)
diskflux.sectorsByTrack.insert(std::pair{physicalLocation, sector});
if (outputFluxSink) if (outputFluxSink)
{ {
for (const auto& data : trackFlux->trackDatas) for (const auto& data : trackFluxes)
outputFluxSink->writeFlux(trackInfo->physicalCylinder, outputFluxSink->writeFlux(trackInfo->physicalCylinder,
trackInfo->physicalHead, trackInfo->physicalHead,
*data->fluxmap); *data->fluxmap);
@@ -666,7 +693,7 @@ std::shared_ptr<const DiskFlux> readDiskCommand(
{ {
std::vector<std::shared_ptr<const Record>> sorted_records; std::vector<std::shared_ptr<const Record>> sorted_records;
for (const auto& data : trackFlux->trackDatas) for (const auto& data : trackFluxes)
sorted_records.insert(sorted_records.end(), sorted_records.insert(sorted_records.end(),
data->records.begin(), data->records.begin(),
data->records.end()); data->records.end());
@@ -691,18 +718,15 @@ std::shared_ptr<const DiskFlux> readDiskCommand(
if (globalConfig()->decoder().dump_sectors()) if (globalConfig()->decoder().dump_sectors())
{ {
auto collected_sectors = collectSectors(trackFlux->sectors, false); auto sectors = collectSectors(trackSectors, false);
std::vector<std::shared_ptr<const Sector>> sorted_sectors( std::ranges::sort(sectors,
collected_sectors.begin(), collected_sectors.end());
std::sort(sorted_sectors.begin(),
sorted_sectors.end(),
[](const auto& o1, const auto& o2) [](const auto& o1, const auto& o2)
{ {
return *o1 < *o2; return *o1 < *o2;
}); });
std::cout << "\nDecoded sectors follow:\n\n"; std::cout << "\nDecoded sectors follow:\n\n";
for (const auto& sector : sorted_sectors) for (const auto& sector : sectors)
{ {
std::cout << fmt::format( std::cout << fmt::format(
"{}.{:02}.{:02}: I+{:.2f}us with {:.2f}us clock: " "{}.{:02}.{:02}: I+{:.2f}us with {:.2f}us clock: "
@@ -719,36 +743,34 @@ std::shared_ptr<const DiskFlux> readDiskCommand(
} }
/* track can't be modified below this point. */ /* track can't be modified below this point. */
log(TrackReadLogMessage{trackFlux}); log(TrackReadLogMessage{trackFluxes, trackSectors});
std::set<std::shared_ptr<const Sector>> all_sectors; std::vector<std::shared_ptr<const Sector>> all_sectors;
for (auto& track : diskflux->tracks) for (auto& [ch, sector] : diskflux.sectorsByTrack)
for (auto& sector : track->sectors) all_sectors.push_back(sector);
all_sectors.insert(sector);
all_sectors = collectSectors(all_sectors); all_sectors = collectSectors(all_sectors);
diskflux->image = std::make_shared<Image>(all_sectors); diskflux.image = std::make_shared<Image>(all_sectors);
/* Log a _copy_ of the diskflux structure so that the logger doesn't see /* Log a _copy_ of the diskflux structure so that the logger doesn't see
* the diskflux get mutated in subsequent reads. */ * the diskflux get mutated in subsequent reads. */
log(DiskReadLogMessage{std::make_shared<DiskFlux>(*diskflux)}); log(DiskReadLogMessage{std::make_shared<DiskFlux>(diskflux)});
} }
if (!diskflux->image) if (!diskflux.image)
diskflux->image = std::make_shared<Image>(); diskflux.image = std::make_shared<Image>();
/* diskflux can't be modified below this point. */
log(EndOperationLogMessage{"Read complete"}); log(EndOperationLogMessage{"Read complete"});
return diskflux;
} }
void readDiskCommand( void readDiskCommand(
FluxSource& fluxsource, Decoder& decoder, ImageWriter& writer) FluxSource& fluxsource, Decoder& decoder, ImageWriter& writer)
{ {
auto diskflux = readDiskCommand(fluxsource, decoder); DiskFlux diskflux;
readDiskCommand(fluxsource, decoder, diskflux);
writer.printMap(*diskflux->image); writer.printMap(*diskflux.image);
if (globalConfig()->decoder().has_write_csv_to()) if (globalConfig()->decoder().has_write_csv_to())
writer.writeCsv( writer.writeCsv(
*diskflux->image, globalConfig()->decoder().write_csv_to()); *diskflux.image, globalConfig()->decoder().write_csv_to());
writer.writeImage(*diskflux->image); writer.writeImage(*diskflux.image);
} }

View File

@@ -14,7 +14,6 @@ class Image;
class ImageReader; class ImageReader;
class ImageWriter; class ImageWriter;
class TrackInfo; class TrackInfo;
class TrackFlux;
class TrackDataFlux; class TrackDataFlux;
class Sector; class Sector;
@@ -29,7 +28,8 @@ struct EndSpeedOperationLogMessage
struct TrackReadLogMessage struct TrackReadLogMessage
{ {
std::shared_ptr<const TrackFlux> track; std::vector<std::shared_ptr<const TrackDataFlux>> fluxes;
std::vector<std::shared_ptr<const Sector>> sectors;
}; };
struct DiskReadLogMessage struct DiskReadLogMessage
@@ -103,12 +103,18 @@ extern void writeDiskCommand(const Image& image,
extern void writeRawDiskCommand(FluxSource& fluxSource, FluxSink& fluxSink); extern void writeRawDiskCommand(FluxSource& fluxSource, FluxSink& fluxSink);
extern std::shared_ptr<TrackFlux> readAndDecodeTrack(FluxSource& fluxSource, struct FluxAndSectors
{
std::vector<std::shared_ptr<const TrackDataFlux>> fluxes;
std::vector<std::shared_ptr<const Sector>> sectors;
};
extern FluxAndSectors readAndDecodeTrack(FluxSource& fluxSource,
Decoder& decoder, Decoder& decoder,
std::shared_ptr<const TrackInfo>& layout); std::shared_ptr<const TrackInfo>& layout);
extern std::shared_ptr<const DiskFlux> readDiskCommand( extern void readDiskCommand(
FluxSource& fluxsource, Decoder& decoder); FluxSource& fluxsource, Decoder& decoder, DiskFlux& diskflux);
extern void readDiskCommand( extern void readDiskCommand(
FluxSource& source, Decoder& decoder, ImageWriter& writer); FluxSource& source, Decoder& decoder, ImageWriter& writer);

View File

@@ -6,7 +6,6 @@
class DiskFlux; class DiskFlux;
class TrackDataFlux; class TrackDataFlux;
class TrackFlux;
class Sector; class Sector;
class LogRenderer; class LogRenderer;

View File

@@ -2,6 +2,7 @@
#define FLUX_H #define FLUX_H
#include "lib/core/bytes.h" #include "lib/core/bytes.h"
#include "lib/data/locations.h"
class Fluxmap; class Fluxmap;
class Sector; class Sector;
@@ -26,16 +27,13 @@ struct TrackDataFlux
std::vector<std::shared_ptr<const Sector>> sectors; std::vector<std::shared_ptr<const Sector>> sectors;
}; };
struct TrackFlux
{
std::shared_ptr<const TrackInfo> trackInfo;
std::vector<std::shared_ptr<TrackDataFlux>> trackDatas;
std::set<std::shared_ptr<const Sector>> sectors;
};
struct DiskFlux struct DiskFlux
{ {
std::vector<std::shared_ptr<TrackFlux>> tracks; DiskFlux& operator=(const DiskFlux& other) = default;
std::multimap<CylinderHead, std::shared_ptr<const TrackDataFlux>>
fluxesByTrack;
std::multimap<CylinderHead, std::shared_ptr<const Sector>> sectorsByTrack;
std::shared_ptr<const Image> image; std::shared_ptr<const Image> image;
std::shared_ptr<const DiskLayout> layout; std::shared_ptr<const DiskLayout> layout;
}; };

View File

@@ -6,7 +6,7 @@
Image::Image() {} Image::Image() {}
Image::Image(std::set<std::shared_ptr<const Sector>>& sectors): Image::Image(std::vector<std::shared_ptr<const Sector>>& sectors):
_filesystemOrder(Layout::computeFilesystemLogicalOrdering()) _filesystemOrder(Layout::computeFilesystemLogicalOrdering())
{ {
for (auto& sector : sectors) for (auto& sector : sectors)

View File

@@ -20,7 +20,7 @@ class Image
{ {
public: public:
Image(); Image();
Image(std::set<std::shared_ptr<const Sector>>& sectors); Image(std::vector<std::shared_ptr<const Sector>>& sectors);
public: public:
class const_iterator class const_iterator

View File

@@ -8,24 +8,32 @@
class MemoryFluxSourceIterator : public FluxSourceIterator class MemoryFluxSourceIterator : public FluxSourceIterator
{ {
using multimap =
std::multimap<CylinderHead, std::shared_ptr<const TrackDataFlux>>;
public: public:
MemoryFluxSourceIterator(const TrackFlux& track): _track(track) {} MemoryFluxSourceIterator(
multimap::const_iterator startIt, multimap::const_iterator endIt):
_startIt(startIt),
_endIt(endIt)
{
}
bool hasNext() const override bool hasNext() const override
{ {
return _count < _track.trackDatas.size(); return _startIt != _endIt;
} }
std::unique_ptr<const Fluxmap> next() override std::unique_ptr<const Fluxmap> next() override
{ {
auto bytes = _track.trackDatas[_count]->fluxmap->rawBytes(); auto bytes = _startIt->second->fluxmap->rawBytes();
_count++; _startIt++;
return std::make_unique<Fluxmap>(bytes); return std::make_unique<Fluxmap>(bytes);
} }
private: private:
const TrackFlux& _track; multimap::const_iterator _startIt;
int _count = 0; multimap::const_iterator _endIt;
}; };
class MemoryFluxSource : public FluxSource class MemoryFluxSource : public FluxSource
@@ -33,25 +41,21 @@ class MemoryFluxSource : public FluxSource
public: public:
MemoryFluxSource(const DiskFlux& flux): _flux(flux) MemoryFluxSource(const DiskFlux& flux): _flux(flux)
{ {
std::vector<CylinderHead> chs; std::set<CylinderHead> chs;
for (const auto& trackFlux : flux.tracks) for (auto& [ch, trackDataFlux] : flux.fluxesByTrack)
chs.push_back( chs.insert(ch);
CylinderHead{(unsigned)trackFlux->trackInfo->physicalCylinder,
(unsigned)trackFlux->trackInfo->logicalCylinder});
_extraConfig.mutable_drive()->set_tracks( _extraConfig.mutable_drive()->set_tracks(
convertCylinderHeadsToString(chs)); convertCylinderHeadsToString(std::vector(chs.begin(), chs.end())));
} }
public: public:
std::unique_ptr<FluxSourceIterator> readFlux( std::unique_ptr<FluxSourceIterator> readFlux(
int physicalCylinder, int physicalHead) override int physicalCylinder, int physicalHead) override
{ {
for (const auto& trackFlux : _flux.tracks) auto [startIt, endIt] = _flux.fluxesByTrack.equal_range(
{ {(unsigned)physicalCylinder, (unsigned)physicalHead});
if ((trackFlux->trackInfo->physicalCylinder == physicalCylinder) && if (startIt != _flux.fluxesByTrack.end())
(trackFlux->trackInfo->physicalHead == physicalHead)) return std::make_unique<MemoryFluxSourceIterator>(startIt, endIt);
return std::make_unique<MemoryFluxSourceIterator>(*trackFlux);
}
return std::make_unique<EmptyFluxSourceIterator>(); return std::make_unique<EmptyFluxSourceIterator>();
} }

View File

@@ -132,7 +132,7 @@ private:
auto trackInfo = Layout::getLayoutOfTrack(track, side); auto trackInfo = Layout::getLayoutOfTrack(track, side);
auto trackdata = readAndDecodeTrack(*_fluxSource, *_decoder, trackInfo); auto trackdata = readAndDecodeTrack(*_fluxSource, *_decoder, trackInfo);
for (const auto& sector : trackdata->sectors) for (const auto& sector : trackdata.sectors)
*_loadedSectors.put(track, side, sector->logicalSector) = *sector; *_loadedSectors.put(track, side, sector->logicalSector) = *sector;
_loadedTracks.insert(trackid_t(track, side)); _loadedTracks.insert(trackid_t(track, side));
} }

View File

@@ -276,16 +276,15 @@ static void rebuildDiskFluxIndices()
sectorByLogicalLocation.clear(); sectorByLogicalLocation.clear();
if (diskFlux) if (diskFlux)
{ {
for (const auto& track : diskFlux->tracks) for (const auto& [ch, sector] : diskFlux->sectorsByTrack)
for (const auto& sector : track->sectors) {
{ sectorByPhysicalLocation[{sector->physicalCylinder,
sectorByPhysicalLocation[{sector->physicalCylinder, sector->physicalHead,
sector->physicalHead, sector->logicalSector}] = sector;
sector->logicalSector}] = sector; sectorByLogicalLocation[{sector->logicalCylinder,
sectorByLogicalLocation[{sector->logicalCylinder, sector->logicalHead,
sector->logicalHead, sector->logicalSector}] = sector;
sector->logicalSector}] = sector; }
}
} }
} }
@@ -526,7 +525,8 @@ void Datastore::beginRead(void)
wtRebuildConfiguration(); wtRebuildConfiguration();
auto fluxSource = FluxSource::create(globalConfig()); auto fluxSource = FluxSource::create(globalConfig());
auto decoder = Arch::createDecoder(globalConfig()); auto decoder = Arch::createDecoder(globalConfig());
auto diskflux = readDiskCommand(*fluxSource, *decoder); auto diskflux = std::make_shared<DiskFlux>();
readDiskCommand(*fluxSource, *decoder, *diskflux);
}); });
} }

View File

@@ -25,18 +25,22 @@ SummaryView::SummaryView():
{ {
} }
static std::optional<std::set<std::shared_ptr<const Sector>>> findSectors( static std::set<std::shared_ptr<const Sector>> findSectors(
std::shared_ptr<const DiskFlux>& diskFlux, int cylinder, int head) std::shared_ptr<const DiskFlux>& diskFlux,
unsigned physicalCylinder,
unsigned physicalHead)
{ {
if (diskFlux) std::set<std::shared_ptr<const Sector>> sectors;
for (auto& it : diskFlux->tracks)
{
if ((it->trackInfo->physicalCylinder == cylinder) &&
(it->trackInfo->physicalHead == head))
return std::make_optional(it->sectors);
}
return {}; if (diskFlux)
{
auto [startIt, endIt] = diskFlux->sectorsByTrack.equal_range(
{physicalCylinder, physicalHead});
for (auto it = startIt; it != endIt; it++)
sectors.insert(it->second);
}
return sectors;
} }
struct TrackAnalysis struct TrackAnalysis
@@ -53,10 +57,10 @@ TrackAnalysis analyseTrack(std::shared_ptr<const DiskFlux>& diskFlux,
auto sectors = findSectors(diskFlux, physicalCylinder, physicalHead); auto sectors = findSectors(diskFlux, physicalCylinder, physicalHead);
result.colour = ImGui::GetColorU32(ImGuiCol_TextDisabled); result.colour = ImGui::GetColorU32(ImGuiCol_TextDisabled);
result.tooltip = "No data"; result.tooltip = "No data";
if (sectors.has_value()) if (!sectors.empty())
{ {
unsigned totalSectors = sectors->size(); unsigned totalSectors = sectors.size();
unsigned goodSectors = std::ranges::count_if(*sectors, unsigned goodSectors = std::ranges::count_if(sectors,
[](auto& e) [](auto& e)
{ {
return e->status == Sector::OK; return e->status == Sector::OK;