163 lines
5.0 KiB
C++
163 lines
5.0 KiB
C++
|
|
#include "base_generator.h"
|
||
|
|
|
||
|
|
#include <QElapsedTimer>
|
||
|
|
#include <QVariant>
|
||
|
|
|
||
|
|
BaseGenerator::ShouldLogSuccess
|
||
|
|
BaseGenerator::shouldLogAllSuccesses() const noexcept {
|
||
|
|
return [this]() { return true; };
|
||
|
|
}
|
||
|
|
|
||
|
|
BaseGenerator::ShouldLogSuccess
|
||
|
|
BaseGenerator::shouldLogEveryNPercent(int percent) const noexcept {
|
||
|
|
if (percent <= 0) {
|
||
|
|
return [this]() { return false; };
|
||
|
|
}
|
||
|
|
|
||
|
|
int oldLastPercentage = 0;
|
||
|
|
return [this, percent, oldLastPercentage]() mutable {
|
||
|
|
if (oldLastPercentage == lastPercentage_) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
oldLastPercentage = lastPercentage_;
|
||
|
|
return !bool(lastPercentage_ % percent);
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
BaseGenerator::ShouldLogSuccess
|
||
|
|
BaseGenerator::shouldLogFirstAndLastPercent() const noexcept {
|
||
|
|
return [this]() { return createdRecords_ == 1 || lastPercentage_ == 100; };
|
||
|
|
}
|
||
|
|
|
||
|
|
BaseGenerator::ShouldLogSuccess BaseGenerator::shouldLogEveryNSeconds(
|
||
|
|
int seconds, const ShouldLogSuccess &performOtherwise) const noexcept {
|
||
|
|
QElapsedTimer timer;
|
||
|
|
timer.start();
|
||
|
|
|
||
|
|
return [this, timer, seconds, performOtherwise]() mutable {
|
||
|
|
if (timer.elapsed() >= seconds * 1000) {
|
||
|
|
timer.restart();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return performOtherwise();
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
BaseGenerator::ShouldLogSuccess
|
||
|
|
BaseGenerator::defaultShouldLog(int percent, int seconds) const noexcept {
|
||
|
|
ShouldLogSuccess first =
|
||
|
|
shouldLogEveryNSeconds(seconds, shouldLogFirstAndLastPercent());
|
||
|
|
ShouldLogSuccess second = shouldLogEveryNPercent(percent);
|
||
|
|
|
||
|
|
return [first, second]() { return first() || second(); };
|
||
|
|
}
|
||
|
|
|
||
|
|
void BaseGenerator::generateAll(const ShouldLogSuccess &shouldLogSuccess) {
|
||
|
|
auto withoutLimit = []() { return true; };
|
||
|
|
|
||
|
|
generateImplementation(withoutLimit, shouldLogSuccess);
|
||
|
|
}
|
||
|
|
|
||
|
|
void BaseGenerator::generateByFillRatio(
|
||
|
|
double fillRatio, const ShouldLogSuccess &shouldLogSuccess) {
|
||
|
|
fillRatio >= 1.0 ? fillRatio = 1.0 : fillRatio;
|
||
|
|
|
||
|
|
qInfo() << "Limit fill ratio of records to create: " << fillRatio;
|
||
|
|
|
||
|
|
auto shouldContinue = [this, fillRatio]() -> bool {
|
||
|
|
double currentFillRatio = lastPercentage_ / 100.0;
|
||
|
|
bool shouldContinue = currentFillRatio < fillRatio;
|
||
|
|
if (!shouldContinue) {
|
||
|
|
qInfo() << "Limit of records to create reached";
|
||
|
|
}
|
||
|
|
return shouldContinue;
|
||
|
|
};
|
||
|
|
|
||
|
|
generateImplementation(shouldContinue, shouldLogSuccess);
|
||
|
|
};
|
||
|
|
|
||
|
|
void BaseGenerator::generateByRecordCount(
|
||
|
|
qsizetype totalRecordsToCreate, const ShouldLogSuccess &shouldLogSuccess) {
|
||
|
|
int limit = std::min(totalRecordsToCreate, calculateRemainingCapacity());
|
||
|
|
|
||
|
|
qInfo() << "Limit of records to create: " << limit;
|
||
|
|
|
||
|
|
auto shouldContinue = [this, limit]() -> bool {
|
||
|
|
bool shouldContinue = createdRecords_ < limit;
|
||
|
|
if (!shouldContinue) {
|
||
|
|
qInfo() << "Limit of records to create reached";
|
||
|
|
}
|
||
|
|
return shouldContinue;
|
||
|
|
};
|
||
|
|
|
||
|
|
generateImplementation(shouldContinue, shouldLogSuccess);
|
||
|
|
};
|
||
|
|
|
||
|
|
void BaseGenerator::generateImplementation(
|
||
|
|
std::function<bool()> shouldContinue,
|
||
|
|
std::function<bool()> shouldLogSuccess) {
|
||
|
|
maximumRecords_ = calculateRemainingCapacity();
|
||
|
|
qInfo() << "The number of records available for creation:" << maximumRecords_;
|
||
|
|
|
||
|
|
qInfo().noquote() << createTemplateMessage() << "Started";
|
||
|
|
|
||
|
|
while (shouldContinue() && prepareData()) {
|
||
|
|
bool success;
|
||
|
|
RepositoryResult result = createRecord();
|
||
|
|
|
||
|
|
if (!result.success) {
|
||
|
|
qWarning().noquote() << createTemplateMessage()
|
||
|
|
<< createFailureMessage(result.errorMessage);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
++createdRecords_;
|
||
|
|
updatePercentage();
|
||
|
|
|
||
|
|
if (shouldLogSuccess()) {
|
||
|
|
qInfo().noquote() << createTemplateMessage() << createSuccessMessage();
|
||
|
|
}
|
||
|
|
|
||
|
|
clearStaleData();
|
||
|
|
}
|
||
|
|
|
||
|
|
qInfo().noquote() << createTemplateMessage() << "Completed";
|
||
|
|
}
|
||
|
|
|
||
|
|
void BaseGenerator::updatePercentage() {
|
||
|
|
int numerator = maximumRecords_ - calculateRemainingCapacity();
|
||
|
|
int newPercentage = std::floor(numerator * 100.0 / maximumRecords_);
|
||
|
|
lastPercentage_ = std::max(newPercentage, lastPercentage_);
|
||
|
|
}
|
||
|
|
|
||
|
|
QString BaseGenerator::createFailureMessage(const QString &errorMessage) const {
|
||
|
|
QString failureMessage = "Failure: Error message:\n\t%1";
|
||
|
|
return failureMessage.arg(errorMessage);
|
||
|
|
}
|
||
|
|
|
||
|
|
QString BaseGenerator::createSuccessMessage() const { return "Success"; }
|
||
|
|
|
||
|
|
QString BaseGenerator::createTemplateMessage() const {
|
||
|
|
auto digitCount = [](int number) {
|
||
|
|
if (number == 0) {
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
return static_cast<int>(std::log10(std::abs(number))) + 1;
|
||
|
|
};
|
||
|
|
|
||
|
|
int maximumRecordsValue = calculateRemainingCapacity();
|
||
|
|
int newFieldWidth =
|
||
|
|
std::max(digitCount(createdRecords_), digitCount(maximumRecordsValue));
|
||
|
|
fieldWidth_ = std::max(fieldWidth_, newFieldWidth);
|
||
|
|
|
||
|
|
static constexpr int progressBarSize = 25;
|
||
|
|
static constexpr int progressBarStep = 100 / progressBarSize;
|
||
|
|
const QString progressBar(lastPercentage_ / progressBarStep, QChar('#'));
|
||
|
|
|
||
|
|
return QString("Creating records of entity %1 [ %2 <~ %3] [%4]:")
|
||
|
|
.arg(entityName_)
|
||
|
|
.arg(createdRecords_, fieldWidth_, 10, QChar(' '))
|
||
|
|
.arg(maximumRecordsValue, fieldWidth_, 10, QChar(' '))
|
||
|
|
.arg(progressBar.leftJustified(progressBarSize, QChar(' ')));
|
||
|
|
};
|