Performance tuning
parent
417edc4e58
commit
973d3f1a4e
|
|
@ -159,6 +159,7 @@ void LogsModel::setTypeIds(const QStringList &typeIds)
|
|||
beginResetModel();
|
||||
qDeleteAll(m_list);
|
||||
m_list.clear();
|
||||
m_generatedEntries = 0;
|
||||
endResetModel();
|
||||
fetchMore();
|
||||
}
|
||||
|
|
@ -256,7 +257,7 @@ LogEntry *LogsModel::findClosest(const QDateTime &dateTime)
|
|||
|
||||
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();
|
||||
|
||||
// qDebug() << qUtf8Printable(QJsonDocument::fromVariant(data).toJson());
|
||||
|
|
@ -266,9 +267,6 @@ void LogsModel::logsReply(int /*commandId*/, const QVariantMap &data)
|
|||
foreach (const QVariant &logEntryVariant, logEntries) {
|
||||
QVariantMap entryMap = logEntryVariant.toMap();
|
||||
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
|
||||
if (!m_viewStartTime.isNull() && timeStamp < m_viewStartTime) {
|
||||
continue;
|
||||
}
|
||||
QString thingId = entryMap.value("thingId").toString();
|
||||
QString typeId = entryMap.value("typeId").toString();
|
||||
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()));
|
||||
QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value");
|
||||
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);
|
||||
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();
|
||||
|
|
@ -363,7 +372,7 @@ void LogsModel::fetchMore(const QModelIndex &parent)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,8 @@ protected:
|
|||
|
||||
bool m_canFetchMore = true;
|
||||
|
||||
int m_generatedEntries = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // LOGSMODEL_H
|
||||
|
|
|
|||
|
|
@ -163,12 +163,21 @@ void XYSeriesAdapter::logEntryAdded(LogEntry *entry)
|
|||
|
||||
int idx = entry->timestamp().secsTo(m_newestSample) / m_sampleRate;
|
||||
if (idx > m_samples.count()) {
|
||||
qCWarning(dcLogEngine) << "Overflowing integer size for XYSeriesAdapter!";
|
||||
qCWarning(dcLogEngine) << objectName() << "Overflowing integer size for XYSeriesAdapter!";
|
||||
return;
|
||||
}
|
||||
Sample *sample = m_samples.at(static_cast<int>(idx));
|
||||
LogEntry *oldLast = sample->entries.count() > 0 ? sample->entries.last() : nullptr;
|
||||
sample->entries.append(entry);
|
||||
// qCDebug(dcLogEngine()) << objectName() << "Inserting sample at:" << idx << entry->timestamp();
|
||||
Sample *sample = m_samples.at(idx);
|
||||
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);
|
||||
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--) {
|
||||
Sample *nextSample = m_samples.at(i);
|
||||
if (nextSample->startingPoint == oldLast) {
|
||||
nextSample->startingPoint = entry;
|
||||
nextSample->startingPoint = newLast;
|
||||
qreal value = calculateSampleValue(i);
|
||||
// qWarning() << "Updating" << i << value;
|
||||
m_series->replace(i, nextSample->timestamp.toMSecsSinceEpoch(), value);
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ private:
|
|||
class Sample {
|
||||
public:
|
||||
QDateTime timestamp; // The timestamp where this sample *ends*
|
||||
QList<LogEntry*> entries; // all log entries in this sample, that is, from timestamp - m_sampleRate
|
||||
LogEntry *startingPoint = nullptr; // the starting point for the same. Normally the last entry of the previous sample
|
||||
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 sample. Normally the last entry of the previous sample
|
||||
};
|
||||
LogsModel* m_model = nullptr;
|
||||
QtCharts::QXYSeries* m_series = nullptr;
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@ ChartView {
|
|||
property Thing rootMeter: null
|
||||
property ThingsProxy meters: null
|
||||
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 {
|
||||
target: meters
|
||||
|
|
@ -69,29 +70,14 @@ ChartView {
|
|||
pieSeries.clear();
|
||||
d.sliceMap = {}
|
||||
|
||||
var unknownConsumerEnergy = 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
|
||||
}
|
||||
var unknownEnergy = rootMeterTotalEnergyState ? rootMeterTotalEnergyState.value : 0
|
||||
|
||||
for (var i = 0; i < meters.count; i++) {
|
||||
var thing = meters.get(i);
|
||||
var value = 0;
|
||||
var totalConsumedStateType = thing.thingClass.stateTypes.findByName("totalEnergyConsumed")
|
||||
if (totalConsumedStateType) {
|
||||
var totalConsumedState = thing.states.getState(totalConsumedStateType.id)
|
||||
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 energyState = thing.stateByName(root.stateName)
|
||||
if (energyState) {
|
||||
value += energyState.value
|
||||
}
|
||||
var slice = pieSeries.append(thing.name, Math.max(0, value))
|
||||
var color = Style.accentColor
|
||||
|
|
@ -104,7 +90,13 @@ ChartView {
|
|||
}
|
||||
slice.color = color
|
||||
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
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: root.rootMeterTotalConsumedEnergyState
|
||||
? root.rootMeterTotalConsumedEnergyState.value.toFixed(2)
|
||||
text: root.rootMeterTotalEnergyState
|
||||
? root.rootMeterTotalEnergyState.value.toFixed(2)
|
||||
: Math.round(pieSeries.sum * 1000) / 1000
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ MainViewBase {
|
|||
}
|
||||
XYSeriesAdapter {
|
||||
id: rootMeterSeriesAdapter
|
||||
objectName: "Root meter adapter"
|
||||
logsModel: rootMeterLogsModel
|
||||
sampleRate: chartView.sampleRate
|
||||
xySeries: rootMeterSeries
|
||||
|
|
@ -197,6 +198,7 @@ MainViewBase {
|
|||
}
|
||||
property XYSeriesAdapter adapter: XYSeriesAdapter {
|
||||
id: seriesAdapter
|
||||
objectName: consumer.thing.name + " adapter"
|
||||
logsModel: logsModel
|
||||
sampleRate: chartView.sampleRate
|
||||
xySeries: upperSeries
|
||||
|
|
@ -441,8 +443,8 @@ MainViewBase {
|
|||
rootMeter: root.rootMeter
|
||||
meters: producers
|
||||
title: qsTr("Total produced energy")
|
||||
stateName: "totalEnergyProduced"
|
||||
visible: root.rootMeter || producers.count > 0
|
||||
multiplier: -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue