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 transformWindow();
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)
, settings("qdiskinfo", "qdiskinfo")
, initializing(true)
, mbSymbol("MB"), gbSymbol("GB"), tbSymbol("TB"), pbSymbol("PB")
{
ui->setupUi(this);
@@ -145,6 +146,11 @@ MainWindow::MainWindow(QWidget *parent)
delete temperatureValueHorizontal;
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()
@@ -184,6 +190,11 @@ void MainWindow::updateNavigationButtons(qsizetype currentIndex)
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;
bool firstTime = true;
@@ -238,17 +249,10 @@ void MainWindow::updateUI(const QString &currentDeviceName)
QString health;
QColor healthColor;
double diskCapacityGB = localObj.value("user_capacity").toObject().value("bytes").toDouble() / 1e9;
QString gbSymbol = locale.formattedDataSize(1 << 30, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
QString tbSymbol = locale.formattedDataSize(qint64(1) << 40, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
QString diskCapacityString;
int diskCapacityGbInt = static_cast<int>(diskCapacityGB);
double diskCapacityMB = localObj.value("user_capacity").toObject().value("bytes").toDouble() / 1e6;
int64_t diskCapacityMbI64 = static_cast<int64_t>(diskCapacityMB);
bool useGB = ui->actionUse_GB_instead_of_TB->isChecked();
if (diskCapacityGbInt < 1000 || useGB) {
diskCapacityString = locale.toString(diskCapacityGB, 'f', 1) + " " + gbSymbol;
} else {
diskCapacityString = QString::number(diskCapacityGbInt/1000) + " " + tbSymbol;
}
QString diskCapacityString = getMbToPrettyString(diskCapacityMbI64, 0, useGB);
QJsonObject temperatureObj = localObj["temperature"].toObject();
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();
QString modelName = localObj["model_name"].toString();
QString firmwareVersion = localObj["firmware_version"].toString("----");
double diskCapacityGB = localObj.value("user_capacity").toObject().value("bytes").toDouble() / 1e9;
int diskCapacityGbInt = static_cast<int>(diskCapacityGB);
double diskCapacityMB = localObj.value("user_capacity").toObject().value("bytes").toDouble() / 1e6;
int64_t diskCapacityMbI64 = static_cast<int64_t>(diskCapacityMB);
int powerCycleCountInt = localObj["power_cycle_count"].toInt(-1);
QJsonObject temperatureObj = localObj["temperature"].toObject();
int temperatureInt = temperatureObj["current"].toInt();
int totalWritesInt = 0;
int totalReadsInt = 0;
int64_t totalMbWritesI64 = 0;
int64_t totalMbReadsI64 = 0;
bool useGB = ui->actionUse_GB_instead_of_TB->isChecked();
QString gbSymbol = locale.formattedDataSize(1 << 30, 1, QLocale::DataSizeTraditionalFormat).split(' ')[1];
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 diskCapacityString = getMbToPrettyString(diskCapacityMbI64, 0, useGB);
QString totalReads;
QString totalWrites;
@@ -474,8 +471,8 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal
modelName = localObj["scsi_model_name"].toString();
powerCycleCountInt = localObj["scsi_start_stop_cycle_counter"].toObject().value("accumulated_load_unload_cycles").toInt();
firmwareVersion = localObj["scsi_revision"].toString("----");
totalReadsInt = scsiErrorCounterLog.value("read").toObject().value("gigabytes_processed").toString().split(",").first().toInt();
totalWritesInt = scsiErrorCounterLog.value("write").toObject().value("gigabytes_processed").toString().split(",").first().toInt();
totalMbReadsI64 = scsiErrorCounterLog.value("read").toObject().value("gigabytes_processed").toString().split(",").first().toInt() * 1000;
totalMbWritesI64 = scsiErrorCounterLog.value("write").toObject().value("gigabytes_processed").toString().split(",").first().toInt() * 1000;
}
bool nvmeHasSelfTest = false;
@@ -591,6 +588,7 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal
powerOnHoursLineEdit->setText(powerOnTime);
powerOnHoursLineEdit->setAlignment(Qt::AlignRight);
int logicalBlockSize = localObj["logical_block_size"].toInt();
if (!isNvme) {
for (const QJsonValue &attr : std::as_const(attributes)) {
QJsonObject attrObj = attr.toObject();
@@ -602,57 +600,46 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal
} else if (attrObj["id"] == 241) {
if (attrObj["name"] == "Total_Writes_GB") {
int gigabytes = attrObj["raw"].toObject()["value"].toInt();
totalWritesInt = gigabytes;
totalMbWritesI64 = gigabytes * 1000;
} else if (attrObj["name"] == "Host_Writes_32MiB") {
double gigabytes = (attrObj["raw"].toObject()["value"].toInt() * 32 * 1024.0 * 1024.0) / 1e9;
totalWritesInt = static_cast<int>(gigabytes);
double megabytes = (attrObj["raw"].toObject()["value"].toInt() * 32 * 1024.0 * 1024.0) / 1e6;
totalMbWritesI64 = static_cast<int64_t>(megabytes);
} else if (attrObj["name"] == "Total_LBAs_Written") {
int logicalBlockSize = localObj["logical_block_size"].toInt();
qlonglong lbaWritten = attrObj["raw"].toObject()["value"].toVariant().toLongLong();
qlonglong gigabytes = (lbaWritten * logicalBlockSize) / 1e9;
int gigabytesInt = static_cast<int>(gigabytes);
if (!gigabytesInt) {
gigabytesInt = static_cast<int>(lbaWritten);
}
totalWritesInt = gigabytesInt;
double megabytes = double(lbaWritten * logicalBlockSize) / 1e6;
totalMbWritesI64 = static_cast<int64_t>(megabytes);
} else if (attrObj["name"] == "Host_Writes_GiB" || attrObj["name"] == "Lifetime_Writes_GiB") {
double gibibytes = attrObj["raw"].toObject()["value"].toDouble();
double bytesPerGiB = static_cast<double>(1ULL << 30);
double bytesPerGB = 1e9;
double conversionFactor = bytesPerGiB / bytesPerGB;
double gigabytes = gibibytes * conversionFactor;
totalWritesInt = static_cast<int>(gigabytes);
double bytesPerMB = 1e6;
double conversionFactor = bytesPerGiB / bytesPerMB;
double megabytes = gibibytes * conversionFactor;
totalMbWritesI64 = static_cast<int64_t>(megabytes);
}
} else if (attrObj["id"] == 242) {
if (attrObj["name"] == "Total_Reads_GB") {
int gigabytes = attrObj["raw"].toObject()["value"].toInt();
totalReadsInt = gigabytes;
totalMbReadsI64 = gigabytes * 1000;
} else if (attrObj["name"] == "Host_Reads_32MiB") {
double gigabytes = (attrObj["raw"].toObject()["value"].toInt() * 32 * 1024.0 * 1024.0) / 1e9;
totalReadsInt = static_cast<int>(gigabytes);
double megabytes = (attrObj["raw"].toObject()["value"].toInt() * 32 * 1024 * 1024) / 1e6;
totalMbReadsI64 = static_cast<int64_t>(megabytes);
} else if (attrObj["name"] == "Total_LBAs_Read") {
int logicalBlockSize = localObj["logical_block_size"].toInt();
qlonglong lbaRead = attrObj["raw"].toObject()["value"].toVariant().toLongLong();
qlonglong gigabytes = (lbaRead * logicalBlockSize) / 1e9;
int gigabytesInt = static_cast<int>(gigabytes);
if (!gigabytesInt) {
gigabytesInt = static_cast<int>(lbaRead);
}
totalReadsInt = gigabytesInt;
double megabytes = double(lbaRead * logicalBlockSize) / 1e6;
totalMbReadsI64 = static_cast<int64_t>(megabytes);
} else if (attrObj["name"] == "Host_Reads_GiB" || attrObj["name"] == "Lifetime_Reads_GiB") {
double gibibytes = attrObj["raw"].toObject()["value"].toDouble();
double bytesPerGiB = static_cast<double>(1ULL << 30);
double bytesPerGB = 1e9;
double conversionFactor = bytesPerGiB / bytesPerGB;
double gigabytes = gibibytes * conversionFactor;
totalReadsInt = static_cast<int>(gigabytes);
double bytesPerMB = 1e6;
double conversionFactor = bytesPerGiB / bytesPerMB;
double megabytes = gibibytes * conversionFactor;
totalMbReadsI64 = static_cast<int64_t>(megabytes);
}
} else if (attrObj["id"] == 246) { // MX500
if (attrObj["name"] == "Total_LBAs_Written") {
int logicalBlockSize = localObj["logical_block_size"].toInt();
qlonglong lbaWritten = attrObj["raw"].toObject()["value"].toVariant().toLongLong();
qlonglong gigabytes = (lbaWritten * logicalBlockSize) / 1e9;
totalWritesInt = static_cast<int>(gigabytes);
double megabytes = double(lbaWritten * logicalBlockSize) / 1e6;
totalMbWritesI64 = static_cast<int64_t>(megabytes);
}
} else if (attrObj["name"] == "Remaining_Lifetime_Perc") {
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) {
QString key = smartItem.key();
QJsonValue value = smartItem.value();
// it appears that NVME drives report data_units as logical_block_size*1000 bytes
if (key == "data_units_written") {
double dataUnitsWritten = value.toDouble();
double gigabytes = (dataUnitsWritten * 512) / 1'000'000;
totalWritesInt = static_cast<int>(gigabytes);
double megabytes = (dataUnitsWritten * logicalBlockSize) / 1000;
totalMbWritesI64 = static_cast<int64_t>(megabytes);
} else if (key == "data_units_read") {
double dataUnitsRead = value.toDouble();
double gigabytes = (dataUnitsRead * 512) / 1'000'000;
totalReadsInt = static_cast<int>(gigabytes);
double megabytes = (dataUnitsRead * logicalBlockSize) / 1000;
totalMbReadsI64 = static_cast<int64_t>(megabytes);
} else if (key == "percentage_used") {
int percentageUsed = 100 - value.toInt();
percentage = QString::number(percentageUsed) + " %";
@@ -697,25 +685,8 @@ void MainWindow::populateWindow(const QJsonObject &localObj, const QString &heal
}
}
if (totalReadsInt) {
if (totalReadsInt < 1000 || 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 = "----";
}
totalReads = getMbToPrettyString(totalMbReadsI64, 1, useGB);
totalWrites = getMbToPrettyString(totalMbWritesI64, 1, useGB);
totalReadsLineEdit->setText(totalReads);
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)")));
}
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;
}