Use megabytes instead of gigabytes for size calculations internally. Change variable types to "int64_t" for megabyte calc.

Add function "getSizeTextFromMegabytes" for generating size strings where it was repeated code.
Optimize code to do less reading of reusable locale strings and read "logicalBlockSize" before reading other size parameters.
This commit is contained in:
Johnny Silverman
2025-11-03 21:54:40 +02:00
parent db93fb1194
commit 702b9c8415
2 changed files with 71 additions and 78 deletions

View File

@@ -95,4 +95,11 @@ private:
void addSmartAttributesTable(const QJsonArray &attributes); void addSmartAttributesTable(const QJsonArray &attributes);
void transformWindow(); void transformWindow();
void mousePressEvent(QMouseEvent*); void mousePressEvent(QMouseEvent*);
private:
QString mbSymbol;
QString gbSymbol;
QString tbSymbol;
QString pbSymbol;
QString getMbToPrettyString(const int64_t &sizeInMbI64, const int &precisionInt, const bool &useGbBool);
}; };

View File

@@ -18,6 +18,7 @@ MainWindow::MainWindow(QWidget *parent)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
, settings("qdiskinfo", "qdiskinfo") , settings("qdiskinfo", "qdiskinfo")
, initializing(true) , initializing(true)
, mbSymbol("MB"), gbSymbol("GB"), tbSymbol("TB"), pbSymbol("PB")
{ {
ui->setupUi(this); ui->setupUi(this);
@@ -145,6 +146,11 @@ MainWindow::MainWindow(QWidget *parent)
delete temperatureValueHorizontal; delete temperatureValueHorizontal;
delete healthStatusValueHorizontal; delete healthStatusValueHorizontal;
} }
mbSymbol = locale.formattedDataSize(1 << 20, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
gbSymbol = locale.formattedDataSize(1 << 30, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
tbSymbol = locale.formattedDataSize(qint64(1) << 40, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
pbSymbol = locale.formattedDataSize(qint64(1) << 50, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@@ -184,6 +190,11 @@ void MainWindow::updateNavigationButtons(qsizetype currentIndex)
void MainWindow::updateUI(const QString &currentDeviceName) void MainWindow::updateUI(const QString &currentDeviceName)
{ {
mbSymbol = locale.formattedDataSize(1 << 20, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
gbSymbol = locale.formattedDataSize(1 << 30, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
tbSymbol = locale.formattedDataSize(qint64(1) << 40, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
pbSymbol = locale.formattedDataSize(qint64(1) << 50, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
QVector<DiskItem> diskItems; QVector<DiskItem> diskItems;
bool firstTime = true; bool firstTime = true;
@@ -238,17 +249,10 @@ void MainWindow::updateUI(const QString &currentDeviceName)
QString health; QString health;
QColor healthColor; QColor healthColor;
double diskCapacityGB = localObj.value("user_capacity").toObject().value("bytes").toDouble() / 1e9; double diskCapacityMB = localObj.value("user_capacity").toObject().value("bytes").toDouble() / 1e6;
QString gbSymbol = locale.formattedDataSize(1 << 30, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1]; int64_t diskCapacityMbI64 = static_cast<int64_t>(diskCapacityMB);
QString tbSymbol = locale.formattedDataSize(qint64(1) << 40, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
QString diskCapacityString;
int diskCapacityGbInt = static_cast<int>(diskCapacityGB);
bool useGB = ui->actionUse_GB_instead_of_TB->isChecked(); bool useGB = ui->actionUse_GB_instead_of_TB->isChecked();
if (diskCapacityGbInt < 1000 || useGB) { QString diskCapacityString = getMbToPrettyString(diskCapacityMbI64, 0, useGB);
diskCapacityString = locale.toString(diskCapacityGB, 'f', 1) + " " + gbSymbol;
} else {
diskCapacityString = QString::number(diskCapacityGbInt/1000) + " " + tbSymbol;
}
QJsonObject temperatureObj = localObj["temperature"].toObject(); QJsonObject temperatureObj = localObj["temperature"].toObject();
int temperatureInt = temperatureObj["current"].toInt(); int temperatureInt = temperatureObj["current"].toInt();
@@ -433,23 +437,16 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal
QJsonObject nvmeLog = localObj["nvme_smart_health_information_log"].toObject(); QJsonObject nvmeLog = localObj["nvme_smart_health_information_log"].toObject();
QString modelName = localObj["model_name"].toString(); QString modelName = localObj["model_name"].toString();
QString firmwareVersion = localObj["firmware_version"].toString("----"); QString firmwareVersion = localObj["firmware_version"].toString("----");
double diskCapacityGB = localObj.value("user_capacity").toObject().value("bytes").toDouble() / 1e9; double diskCapacityMB = localObj.value("user_capacity").toObject().value("bytes").toDouble() / 1e6;
int diskCapacityGbInt = static_cast<int>(diskCapacityGB); int64_t diskCapacityMbI64 = static_cast<int64_t>(diskCapacityMB);
int powerCycleCountInt = localObj["power_cycle_count"].toInt(-1); int powerCycleCountInt = localObj["power_cycle_count"].toInt(-1);
QJsonObject temperatureObj = localObj["temperature"].toObject(); QJsonObject temperatureObj = localObj["temperature"].toObject();
int temperatureInt = temperatureObj["current"].toInt(); int temperatureInt = temperatureObj["current"].toInt();
int totalWritesInt = 0; int64_t totalMbWritesI64 = 0;
int totalReadsInt = 0; int64_t totalMbReadsI64 = 0;
bool useGB = ui->actionUse_GB_instead_of_TB->isChecked(); bool useGB = ui->actionUse_GB_instead_of_TB->isChecked();
QString gbSymbol = locale.formattedDataSize(1 << 30, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1]; QString diskCapacityString = getMbToPrettyString(diskCapacityMbI64, 0, useGB);
QString tbSymbol = locale.formattedDataSize(qint64(1) << 40, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
QString diskCapacityString;
if (diskCapacityGbInt < 1000 || useGB) {
diskCapacityString = locale.toString(diskCapacityGB, 'f', 1) + " " + gbSymbol;
} else {
diskCapacityString = QString::number(diskCapacityGbInt/1000) + " " + tbSymbol;
}
QString totalReads; QString totalReads;
QString totalWrites; QString totalWrites;
@@ -474,8 +471,8 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal
modelName = localObj["scsi_model_name"].toString(); modelName = localObj["scsi_model_name"].toString();
powerCycleCountInt = localObj["scsi_start_stop_cycle_counter"].toObject().value("accumulated_load_unload_cycles").toInt(); powerCycleCountInt = localObj["scsi_start_stop_cycle_counter"].toObject().value("accumulated_load_unload_cycles").toInt();
firmwareVersion = localObj["scsi_revision"].toString("----"); firmwareVersion = localObj["scsi_revision"].toString("----");
totalReadsInt = scsiErrorCounterLog.value("read").toObject().value("gigabytes_processed").toString().split(",").first().toInt(); totalMbReadsI64 = scsiErrorCounterLog.value("read").toObject().value("gigabytes_processed").toString().split(",").first().toInt() * 1000;
totalWritesInt = scsiErrorCounterLog.value("write").toObject().value("gigabytes_processed").toString().split(",").first().toInt(); totalMbWritesI64 = scsiErrorCounterLog.value("write").toObject().value("gigabytes_processed").toString().split(",").first().toInt() * 1000;
} }
bool nvmeHasSelfTest = false; bool nvmeHasSelfTest = false;
@@ -591,6 +588,7 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal
powerOnHoursLineEdit->setText(powerOnTime); powerOnHoursLineEdit->setText(powerOnTime);
powerOnHoursLineEdit->setAlignment(Qt::AlignRight); powerOnHoursLineEdit->setAlignment(Qt::AlignRight);
int logicalBlockSize = localObj["logical_block_size"].toInt();
if (!isNvme) { if (!isNvme) {
for (const QJsonValue &attr : std::as_const(attributes)) { for (const QJsonValue &attr : std::as_const(attributes)) {
QJsonObject attrObj = attr.toObject(); QJsonObject attrObj = attr.toObject();
@@ -602,57 +600,46 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal
} else if (attrObj["id"] == 241) { } else if (attrObj["id"] == 241) {
if (attrObj["name"] == "Total_Writes_GB") { if (attrObj["name"] == "Total_Writes_GB") {
int gigabytes = attrObj["raw"].toObject()["value"].toInt(); int gigabytes = attrObj["raw"].toObject()["value"].toInt();
totalWritesInt = gigabytes; totalMbWritesI64 = gigabytes * 1000;
} else if (attrObj["name"] == "Host_Writes_32MiB") { } else if (attrObj["name"] == "Host_Writes_32MiB") {
double gigabytes = (attrObj["raw"].toObject()["value"].toInt() * 32 * 1024.0 * 1024.0) / 1e9; double megabytes = (attrObj["raw"].toObject()["value"].toInt() * 32 * 1024.0 * 1024.0) / 1e6;
totalWritesInt = static_cast<int>(gigabytes); totalMbWritesI64 = static_cast<int64_t>(megabytes);
} else if (attrObj["name"] == "Total_LBAs_Written") { } else if (attrObj["name"] == "Total_LBAs_Written") {
int logicalBlockSize = localObj["logical_block_size"].toInt();
qlonglong lbaWritten = attrObj["raw"].toObject()["value"].toVariant().toLongLong(); qlonglong lbaWritten = attrObj["raw"].toObject()["value"].toVariant().toLongLong();
qlonglong gigabytes = (lbaWritten * logicalBlockSize) / 1e9; double megabytes = double(lbaWritten * logicalBlockSize) / 1e6;
int gigabytesInt = static_cast<int>(gigabytes); totalMbWritesI64 = static_cast<int64_t>(megabytes);
if (!gigabytesInt) {
gigabytesInt = static_cast<int>(lbaWritten);
}
totalWritesInt = gigabytesInt;
} else if (attrObj["name"] == "Host_Writes_GiB" || attrObj["name"] == "Lifetime_Writes_GiB") { } else if (attrObj["name"] == "Host_Writes_GiB" || attrObj["name"] == "Lifetime_Writes_GiB") {
double gibibytes = attrObj["raw"].toObject()["value"].toDouble(); double gibibytes = attrObj["raw"].toObject()["value"].toDouble();
double bytesPerGiB = static_cast<double>(1ULL << 30); double bytesPerGiB = static_cast<double>(1ULL << 30);
double bytesPerGB = 1e9; double bytesPerMB = 1e6;
double conversionFactor = bytesPerGiB / bytesPerGB; double conversionFactor = bytesPerGiB / bytesPerMB;
double gigabytes = gibibytes * conversionFactor; double megabytes = gibibytes * conversionFactor;
totalWritesInt = static_cast<int>(gigabytes); totalMbWritesI64 = static_cast<int64_t>(megabytes);
} }
} else if (attrObj["id"] == 242) { } else if (attrObj["id"] == 242) {
if (attrObj["name"] == "Total_Reads_GB") { if (attrObj["name"] == "Total_Reads_GB") {
int gigabytes = attrObj["raw"].toObject()["value"].toInt(); int gigabytes = attrObj["raw"].toObject()["value"].toInt();
totalReadsInt = gigabytes; totalMbReadsI64 = gigabytes * 1000;
} else if (attrObj["name"] == "Host_Reads_32MiB") { } else if (attrObj["name"] == "Host_Reads_32MiB") {
double gigabytes = (attrObj["raw"].toObject()["value"].toInt() * 32 * 1024.0 * 1024.0) / 1e9; double megabytes = (attrObj["raw"].toObject()["value"].toInt() * 32 * 1024 * 1024) / 1e6;
totalReadsInt = static_cast<int>(gigabytes); totalMbReadsI64 = static_cast<int64_t>(megabytes);
} else if (attrObj["name"] == "Total_LBAs_Read") { } else if (attrObj["name"] == "Total_LBAs_Read") {
int logicalBlockSize = localObj["logical_block_size"].toInt();
qlonglong lbaRead = attrObj["raw"].toObject()["value"].toVariant().toLongLong(); qlonglong lbaRead = attrObj["raw"].toObject()["value"].toVariant().toLongLong();
qlonglong gigabytes = (lbaRead * logicalBlockSize) / 1e9; double megabytes = double(lbaRead * logicalBlockSize) / 1e6;
int gigabytesInt = static_cast<int>(gigabytes); totalMbReadsI64 = static_cast<int64_t>(megabytes);
if (!gigabytesInt) {
gigabytesInt = static_cast<int>(lbaRead);
}
totalReadsInt = gigabytesInt;
} else if (attrObj["name"] == "Host_Reads_GiB" || attrObj["name"] == "Lifetime_Reads_GiB") { } else if (attrObj["name"] == "Host_Reads_GiB" || attrObj["name"] == "Lifetime_Reads_GiB") {
double gibibytes = attrObj["raw"].toObject()["value"].toDouble(); double gibibytes = attrObj["raw"].toObject()["value"].toDouble();
double bytesPerGiB = static_cast<double>(1ULL << 30); double bytesPerGiB = static_cast<double>(1ULL << 30);
double bytesPerGB = 1e9; double bytesPerMB = 1e6;
double conversionFactor = bytesPerGiB / bytesPerGB; double conversionFactor = bytesPerGiB / bytesPerMB;
double gigabytes = gibibytes * conversionFactor; double megabytes = gibibytes * conversionFactor;
totalReadsInt = static_cast<int>(gigabytes); totalMbReadsI64 = static_cast<int64_t>(megabytes);
} }
} else if (attrObj["id"] == 246) { // MX500 } else if (attrObj["id"] == 246) { // MX500
if (attrObj["name"] == "Total_LBAs_Written") { if (attrObj["name"] == "Total_LBAs_Written") {
int logicalBlockSize = localObj["logical_block_size"].toInt();
qlonglong lbaWritten = attrObj["raw"].toObject()["value"].toVariant().toLongLong(); qlonglong lbaWritten = attrObj["raw"].toObject()["value"].toVariant().toLongLong();
qlonglong gigabytes = (lbaWritten * logicalBlockSize) / 1e9; double megabytes = double(lbaWritten * logicalBlockSize) / 1e6;
totalWritesInt = static_cast<int>(gigabytes); totalMbWritesI64 = static_cast<int64_t>(megabytes);
} }
} else if (attrObj["name"] == "Remaining_Lifetime_Perc") { } else if (attrObj["name"] == "Remaining_Lifetime_Perc") {
int percentageUsed = attrObj["raw"].toObject()["value"].toInt(); int percentageUsed = attrObj["raw"].toObject()["value"].toInt();
@@ -682,14 +669,15 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal
for (auto smartItem = nvmeLog.begin(); smartItem != nvmeLog.end(); ++smartItem) { for (auto smartItem = nvmeLog.begin(); smartItem != nvmeLog.end(); ++smartItem) {
QString key = smartItem.key(); QString key = smartItem.key();
QJsonValue value = smartItem.value(); QJsonValue value = smartItem.value();
// it appears that NVME drives report data_units as logical_block_size*1000 bytes
if (key == "data_units_written") { if (key == "data_units_written") {
double dataUnitsWritten = value.toDouble(); double dataUnitsWritten = value.toDouble();
double gigabytes = (dataUnitsWritten * 512) / 1'000'000; double megabytes = (dataUnitsWritten * logicalBlockSize) / 1000;
totalWritesInt = static_cast<int>(gigabytes); totalMbWritesI64 = static_cast<int64_t>(megabytes);
} else if (key == "data_units_read") { } else if (key == "data_units_read") {
double dataUnitsRead = value.toDouble(); double dataUnitsRead = value.toDouble();
double gigabytes = (dataUnitsRead * 512) / 1'000'000; double megabytes = (dataUnitsRead * logicalBlockSize) / 1000;
totalReadsInt = static_cast<int>(gigabytes); totalMbReadsI64 = static_cast<int64_t>(megabytes);
} else if (key == "percentage_used") { } else if (key == "percentage_used") {
int percentageUsed = 100 - value.toInt(); int percentageUsed = 100 - value.toInt();
percentage = QString::number(percentageUsed) + " %"; percentage = QString::number(percentageUsed) + " %";
@@ -697,25 +685,8 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal
} }
} }
if (totalReadsInt) { totalReads = getMbToPrettyString(totalMbReadsI64, 1, useGB);
if (totalReadsInt < 1000 || useGB) { totalWrites = getMbToPrettyString(totalMbWritesI64, 1, useGB);
totalReads = QString::number(totalReadsInt) + " " + gbSymbol;
} else {
totalReads = QString::number(totalReadsInt/1000.0, 'f', 1) + " " + tbSymbol;
}
} else {
totalReads = "----";
}
if (totalWritesInt) {
if (totalWritesInt < 1000 || useGB) {
totalWrites = QString::number(totalWritesInt) + " " + gbSymbol;
} else {
totalWrites = QString::number(totalWritesInt/1000.0, 'f', 1) + " " + tbSymbol;
}
} else {
totalWrites = "----";
}
totalReadsLineEdit->setText(totalReads); totalReadsLineEdit->setText(totalReads);
totalReadsLineEdit->setAlignment(Qt::AlignRight); totalReadsLineEdit->setAlignment(Qt::AlignRight);
@@ -1480,3 +1451,18 @@ void MainWindow::on_actionSave_Image_triggered()
screenshot.save(QFileDialog::getSaveFileName(this, tr("Save Image"), "QDiskInfo_" + deviceNodeLineEdit->text().section('/', -1) + ".png", tr("PNG Files (*.png)"))); screenshot.save(QFileDialog::getSaveFileName(this, tr("Save Image"), "QDiskInfo_" + deviceNodeLineEdit->text().section('/', -1) + ".png", tr("PNG Files (*.png)")));
} }
QString MainWindow::getMbToPrettyString(const int64_t &sizeInMbI64, const int &precisionInt, const bool &useGbBool)
{
if (!sizeInMbI64)
return "----";
int precision = precisionInt ? (useGbBool ? 1 : precisionInt) : 0;
double sizeInMB = double(sizeInMbI64);
if (sizeInMbI64 < 1000)
return QString::number(sizeInMbI64) + " " + mbSymbol;
else if (sizeInMbI64 < 1000000 || useGbBool)
return QString::number(sizeInMB/1e3, 'f', precision) + " " + gbSymbol;
else if (sizeInMbI64 < 1000000000)
return QString::number(sizeInMB/1e6, 'f', precision) + " " + tbSymbol;
return QString::number(sizeInMB/1e9, 'f', precision) + " " + pbSymbol;
}