Performance tuning
This commit is contained in:
parent
417edc4e58
commit
973d3f1a4e
@ -159,6 +159,7 @@ void LogsModel::setTypeIds(const QStringList &typeIds)
|
|||||||
beginResetModel();
|
beginResetModel();
|
||||||
qDeleteAll(m_list);
|
qDeleteAll(m_list);
|
||||||
m_list.clear();
|
m_list.clear();
|
||||||
|
m_generatedEntries = 0;
|
||||||
endResetModel();
|
endResetModel();
|
||||||
fetchMore();
|
fetchMore();
|
||||||
}
|
}
|
||||||
@ -256,7 +257,7 @@ LogEntry *LogsModel::findClosest(const QDateTime &dateTime)
|
|||||||
|
|
||||||
void LogsModel::logsReply(int /*commandId*/, const QVariantMap &data)
|
void LogsModel::logsReply(int /*commandId*/, const QVariantMap &data)
|
||||||
{
|
{
|
||||||
int offset = data.value("offset").toInt();
|
int offset = data.value("offset").toInt() + m_generatedEntries;
|
||||||
int count = data.value("count").toInt();
|
int count = data.value("count").toInt();
|
||||||
|
|
||||||
// qDebug() << qUtf8Printable(QJsonDocument::fromVariant(data).toJson());
|
// qDebug() << qUtf8Printable(QJsonDocument::fromVariant(data).toJson());
|
||||||
@ -266,9 +267,6 @@ void LogsModel::logsReply(int /*commandId*/, const QVariantMap &data)
|
|||||||
foreach (const QVariant &logEntryVariant, logEntries) {
|
foreach (const QVariant &logEntryVariant, logEntries) {
|
||||||
QVariantMap entryMap = logEntryVariant.toMap();
|
QVariantMap entryMap = logEntryVariant.toMap();
|
||||||
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
|
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
|
||||||
if (!m_viewStartTime.isNull() && timeStamp < m_viewStartTime) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
QString thingId = entryMap.value("thingId").toString();
|
QString thingId = entryMap.value("thingId").toString();
|
||||||
QString typeId = entryMap.value("typeId").toString();
|
QString typeId = entryMap.value("typeId").toString();
|
||||||
QMetaEnum sourceEnum = QMetaEnum::fromType<LogEntry::LoggingSource>();
|
QMetaEnum sourceEnum = QMetaEnum::fromType<LogEntry::LoggingSource>();
|
||||||
@ -277,8 +275,19 @@ void LogsModel::logsReply(int /*commandId*/, const QVariantMap &data)
|
|||||||
LogEntry::LoggingEventType loggingEventType = static_cast<LogEntry::LoggingEventType>(loggingEventTypeEnum.keyToValue(entryMap.value("eventType").toByteArray()));
|
LogEntry::LoggingEventType loggingEventType = static_cast<LogEntry::LoggingEventType>(loggingEventTypeEnum.keyToValue(entryMap.value("eventType").toByteArray()));
|
||||||
QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value");
|
QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value");
|
||||||
QString errorCode = entryMap.value("errorCode").toString();
|
QString errorCode = entryMap.value("errorCode").toString();
|
||||||
|
|
||||||
|
bool stopProcessing = false;
|
||||||
|
if (m_viewStartTime.isValid() && timeStamp.addSecs(-60) < m_viewStartTime) {
|
||||||
|
timeStamp = m_viewStartTime.addSecs(-60);
|
||||||
|
stopProcessing = true;
|
||||||
|
m_generatedEntries++;
|
||||||
|
}
|
||||||
LogEntry *entry = new LogEntry(timeStamp, value, thingId, typeId, loggingSource, loggingEventType, errorCode, this);
|
LogEntry *entry = new LogEntry(timeStamp, value, thingId, typeId, loggingSource, loggingEventType, errorCode, this);
|
||||||
newBlock.append(entry);
|
newBlock.append(entry);
|
||||||
|
// qCDebug(dcLogEngine()) << objectName() << "adding entry at" << timeStamp << m_viewStartTime;
|
||||||
|
if (stopProcessing) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// qCDebug(dcLogEngine()) << objectName() << "Received logs from" << offset << "to" << offset + count << "Actual count:" << newBlock.count();
|
// qCDebug(dcLogEngine()) << objectName() << "Received logs from" << offset << "to" << offset + count << "Actual count:" << newBlock.count();
|
||||||
@ -363,7 +372,7 @@ void LogsModel::fetchMore(const QModelIndex &parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
params.insert("limit", m_blockSize);
|
params.insert("limit", m_blockSize);
|
||||||
params.insert("offset", m_list.count());
|
params.insert("offset", m_list.count() - m_generatedEntries);
|
||||||
|
|
||||||
// qDebug() << "Fetching logs from" << m_startTime.toString() << "to" << m_endTime.toString() << "with offset" << m_list.count() << "and limit" << m_blockSize;
|
// qDebug() << "Fetching logs from" << m_startTime.toString() << "to" << m_endTime.toString() << "with offset" << m_list.count() << "and limit" << m_blockSize;
|
||||||
|
|
||||||
|
|||||||
@ -133,6 +133,8 @@ protected:
|
|||||||
|
|
||||||
bool m_canFetchMore = true;
|
bool m_canFetchMore = true;
|
||||||
|
|
||||||
|
int m_generatedEntries = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LOGSMODEL_H
|
#endif // LOGSMODEL_H
|
||||||
|
|||||||
@ -163,12 +163,21 @@ void XYSeriesAdapter::logEntryAdded(LogEntry *entry)
|
|||||||
|
|
||||||
int idx = entry->timestamp().secsTo(m_newestSample) / m_sampleRate;
|
int idx = entry->timestamp().secsTo(m_newestSample) / m_sampleRate;
|
||||||
if (idx > m_samples.count()) {
|
if (idx > m_samples.count()) {
|
||||||
qCWarning(dcLogEngine) << "Overflowing integer size for XYSeriesAdapter!";
|
qCWarning(dcLogEngine) << objectName() << "Overflowing integer size for XYSeriesAdapter!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Sample *sample = m_samples.at(static_cast<int>(idx));
|
// qCDebug(dcLogEngine()) << objectName() << "Inserting sample at:" << idx << entry->timestamp();
|
||||||
LogEntry *oldLast = sample->entries.count() > 0 ? sample->entries.last() : nullptr;
|
Sample *sample = m_samples.at(idx);
|
||||||
sample->entries.append(entry);
|
LogEntry *oldLast = nullptr;
|
||||||
|
// In theory we'd need to insert sorted, but only the last one actually matters for subsequent samples
|
||||||
|
// For the current sample we're calculating the median anyways, so just append/prepend t be a bit faster
|
||||||
|
if (sample->entries.count() > 0 && sample->entries.last()->timestamp() < entry->timestamp()) {
|
||||||
|
oldLast = sample->entries.last();
|
||||||
|
sample->entries.append(entry);
|
||||||
|
} else {
|
||||||
|
sample->entries.prepend(entry);
|
||||||
|
}
|
||||||
|
LogEntry *newLast = sample->entries.last();
|
||||||
|
|
||||||
qreal value = calculateSampleValue(idx);
|
qreal value = calculateSampleValue(idx);
|
||||||
m_series->replace(idx, sample->timestamp.toMSecsSinceEpoch(), value);
|
m_series->replace(idx, sample->timestamp.toMSecsSinceEpoch(), value);
|
||||||
@ -189,7 +198,7 @@ void XYSeriesAdapter::logEntryAdded(LogEntry *entry)
|
|||||||
for (int i = idx - 1; i >= 0; i--) {
|
for (int i = idx - 1; i >= 0; i--) {
|
||||||
Sample *nextSample = m_samples.at(i);
|
Sample *nextSample = m_samples.at(i);
|
||||||
if (nextSample->startingPoint == oldLast) {
|
if (nextSample->startingPoint == oldLast) {
|
||||||
nextSample->startingPoint = entry;
|
nextSample->startingPoint = newLast;
|
||||||
qreal value = calculateSampleValue(i);
|
qreal value = calculateSampleValue(i);
|
||||||
// qWarning() << "Updating" << i << value;
|
// qWarning() << "Updating" << i << value;
|
||||||
m_series->replace(i, nextSample->timestamp.toMSecsSinceEpoch(), value);
|
m_series->replace(i, nextSample->timestamp.toMSecsSinceEpoch(), value);
|
||||||
|
|||||||
@ -69,8 +69,8 @@ private:
|
|||||||
class Sample {
|
class Sample {
|
||||||
public:
|
public:
|
||||||
QDateTime timestamp; // The timestamp where this sample *ends*
|
QDateTime timestamp; // The timestamp where this sample *ends*
|
||||||
QList<LogEntry*> entries; // all log entries in this sample, that is, from timestamp - m_sampleRate
|
QList<LogEntry*> entries; // all log entries in this sample, that is, from timestamp - smaple size to timestamp
|
||||||
LogEntry *startingPoint = nullptr; // the starting point for the same. Normally the last entry of the previous sample
|
LogEntry *startingPoint = nullptr; // the starting point for the sample. Normally the last entry of the previous sample
|
||||||
};
|
};
|
||||||
LogsModel* m_model = nullptr;
|
LogsModel* m_model = nullptr;
|
||||||
QtCharts::QXYSeries* m_series = nullptr;
|
QtCharts::QXYSeries* m_series = nullptr;
|
||||||
|
|||||||
@ -48,8 +48,9 @@ ChartView {
|
|||||||
property Thing rootMeter: null
|
property Thing rootMeter: null
|
||||||
property ThingsProxy meters: null
|
property ThingsProxy meters: null
|
||||||
property int multiplier: 1
|
property int multiplier: 1
|
||||||
|
property string stateName: "totalEnergyConsumed"
|
||||||
|
|
||||||
readonly property State rootMeterTotalConsumedEnergyState: rootMeter ? rootMeter.stateByName("totalEnergyConsumed") : null
|
readonly property State rootMeterTotalEnergyState: rootMeter ? rootMeter.stateByName(stateName) : null
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: meters
|
target: meters
|
||||||
@ -69,29 +70,14 @@ ChartView {
|
|||||||
pieSeries.clear();
|
pieSeries.clear();
|
||||||
d.sliceMap = {}
|
d.sliceMap = {}
|
||||||
|
|
||||||
var unknownConsumerEnergy = 0;
|
var unknownEnergy = rootMeterTotalEnergyState ? rootMeterTotalEnergyState.value : 0
|
||||||
if (rootMeter) {
|
|
||||||
unknownConsumerEnergy = rootMeter.stateByName("totalEnergyConsumed").value
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rootMeter) {
|
|
||||||
var slice = pieSeries.append(qsTr("Unknown"), unknownConsumerEnergy)
|
|
||||||
slice.color = Style.accentColor
|
|
||||||
d.sliceMap[slice] = rootMeter
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < meters.count; i++) {
|
for (var i = 0; i < meters.count; i++) {
|
||||||
var thing = meters.get(i);
|
var thing = meters.get(i);
|
||||||
var value = 0;
|
var value = 0;
|
||||||
var totalConsumedStateType = thing.thingClass.stateTypes.findByName("totalEnergyConsumed")
|
var energyState = thing.stateByName(root.stateName)
|
||||||
if (totalConsumedStateType) {
|
if (energyState) {
|
||||||
var totalConsumedState = thing.states.getState(totalConsumedStateType.id)
|
value += energyState.value
|
||||||
value = value + (totalConsumedState.value * root.multiplier)
|
|
||||||
}
|
|
||||||
var totalProducedStateType = thing.thingClass.stateTypes.findByName("totalEnergyProduced")
|
|
||||||
if (totalProducedStateType) {
|
|
||||||
var totalProducedState = thing.states.getState(totalProducedStateType.id)
|
|
||||||
value = value - (totalProducedState.value * root.multiplier)
|
|
||||||
}
|
}
|
||||||
var slice = pieSeries.append(thing.name, Math.max(0, value))
|
var slice = pieSeries.append(thing.name, Math.max(0, value))
|
||||||
var color = Style.accentColor
|
var color = Style.accentColor
|
||||||
@ -104,7 +90,13 @@ ChartView {
|
|||||||
}
|
}
|
||||||
slice.color = color
|
slice.color = color
|
||||||
d.sliceMap[slice] = thing
|
d.sliceMap[slice] = thing
|
||||||
unknownConsumerEnergy -= value
|
unknownEnergy -= value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unknownEnergy > 0) {
|
||||||
|
var slice = pieSeries.append(qsTr("Unknown"), unknownEnergy)
|
||||||
|
slice.color = Style.accentColor
|
||||||
|
d.sliceMap[slice] = rootMeter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,8 +120,8 @@ ChartView {
|
|||||||
font.pixelSize: app.largeFont
|
font.pixelSize: app.largeFont
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
text: root.rootMeterTotalConsumedEnergyState
|
text: root.rootMeterTotalEnergyState
|
||||||
? root.rootMeterTotalConsumedEnergyState.value.toFixed(2)
|
? root.rootMeterTotalEnergyState.value.toFixed(2)
|
||||||
: Math.round(pieSeries.sum * 1000) / 1000
|
: Math.round(pieSeries.sum * 1000) / 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -124,6 +124,7 @@ MainViewBase {
|
|||||||
}
|
}
|
||||||
XYSeriesAdapter {
|
XYSeriesAdapter {
|
||||||
id: rootMeterSeriesAdapter
|
id: rootMeterSeriesAdapter
|
||||||
|
objectName: "Root meter adapter"
|
||||||
logsModel: rootMeterLogsModel
|
logsModel: rootMeterLogsModel
|
||||||
sampleRate: chartView.sampleRate
|
sampleRate: chartView.sampleRate
|
||||||
xySeries: rootMeterSeries
|
xySeries: rootMeterSeries
|
||||||
@ -197,6 +198,7 @@ MainViewBase {
|
|||||||
}
|
}
|
||||||
property XYSeriesAdapter adapter: XYSeriesAdapter {
|
property XYSeriesAdapter adapter: XYSeriesAdapter {
|
||||||
id: seriesAdapter
|
id: seriesAdapter
|
||||||
|
objectName: consumer.thing.name + " adapter"
|
||||||
logsModel: logsModel
|
logsModel: logsModel
|
||||||
sampleRate: chartView.sampleRate
|
sampleRate: chartView.sampleRate
|
||||||
xySeries: upperSeries
|
xySeries: upperSeries
|
||||||
@ -441,8 +443,8 @@ MainViewBase {
|
|||||||
rootMeter: root.rootMeter
|
rootMeter: root.rootMeter
|
||||||
meters: producers
|
meters: producers
|
||||||
title: qsTr("Total produced energy")
|
title: qsTr("Total produced energy")
|
||||||
|
stateName: "totalEnergyProduced"
|
||||||
visible: root.rootMeter || producers.count > 0
|
visible: root.rootMeter || producers.count > 0
|
||||||
multiplier: -1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user