forked from qt-creator/qt-creator
CtfVisualizer: Fix computation of nesting level
The computed nesting level (which row an event to show in) was solely based on begin+end events and "complete" events were ignored. Compute the rows afterwards, similar to the "parent" computation that the timeline model already does. Find the first row that is free, and use that for the row of the item. Change-Id: I890138c10f5038508da9b286b35d7bcfdf0ab64d Reviewed-by: Alessandro Portale <alessandro.portale@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
@@ -83,6 +83,54 @@ void TimelineModel::computeNesting()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Compute all ranges' nesting level. Sort them into rows by finding the
|
||||||
|
first row that has "an open spot".
|
||||||
|
*/
|
||||||
|
QList<int> TimelineModel::computeRows(int *maxlevel) const
|
||||||
|
{
|
||||||
|
*maxlevel = 0;
|
||||||
|
std::list<int> rows;
|
||||||
|
QList<int> levels;
|
||||||
|
levels.reserve(d->ranges.count());
|
||||||
|
for (int range = 0; range != count(); ++range) {
|
||||||
|
TimelineModelPrivate::Range ¤t = d->ranges[range];
|
||||||
|
// find first row for inserting
|
||||||
|
int level = 0;
|
||||||
|
auto rowIt = rows.begin();
|
||||||
|
forever {
|
||||||
|
if (rowIt == rows.end()) {
|
||||||
|
// didn't find a row, insert new one
|
||||||
|
rows.push_back(range);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
TimelineModelPrivate::Range &rowItem = d->ranges[*rowIt];
|
||||||
|
if (rowItem.start + rowItem.duration < current.start) {
|
||||||
|
// We've completely passed the item
|
||||||
|
// Use this row for the range
|
||||||
|
*rowIt = range;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++rowIt;
|
||||||
|
++level;
|
||||||
|
}
|
||||||
|
levels.append(level);
|
||||||
|
if (level > *maxlevel)
|
||||||
|
*maxlevel = level;
|
||||||
|
// remove other rows that we passed
|
||||||
|
while (rowIt != rows.end()) {
|
||||||
|
TimelineModelPrivate::Range &rowItem = d->ranges[*rowIt];
|
||||||
|
if (rowItem.start + rowItem.duration < current.start) {
|
||||||
|
// We've completely passed the item, remove
|
||||||
|
rowIt = rows.erase(rowIt);
|
||||||
|
} else {
|
||||||
|
++rowIt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return levels;
|
||||||
|
}
|
||||||
|
|
||||||
int TimelineModel::collapsedRowCount() const
|
int TimelineModel::collapsedRowCount() const
|
||||||
{
|
{
|
||||||
return d->collapsedRowCount;
|
return d->collapsedRowCount;
|
||||||
|
@@ -133,6 +133,7 @@ protected:
|
|||||||
int insertStart(qint64 startTime, int selectionId);
|
int insertStart(qint64 startTime, int selectionId);
|
||||||
void insertEnd(int index, qint64 duration);
|
void insertEnd(int index, qint64 duration);
|
||||||
void computeNesting();
|
void computeNesting();
|
||||||
|
QList<int> computeRows(int *maxlevel) const;
|
||||||
|
|
||||||
void setCollapsedRowCount(int rows);
|
void setCollapsedRowCount(int rows);
|
||||||
void setExpandedRowCount(int rows);
|
void setExpandedRowCount(int rows);
|
||||||
|
@@ -105,7 +105,7 @@ int CtfTimelineModel::expandedRow(int index) const
|
|||||||
if (counterIdx > 0) {
|
if (counterIdx > 0) {
|
||||||
return m_counterIndexToRow[counterIdx - 1] + 1;
|
return m_counterIndexToRow[counterIdx - 1] + 1;
|
||||||
}
|
}
|
||||||
return m_nestingLevels.value(index) + m_counterData.size() + 1;
|
return m_rows.value(index) + m_counterData.size() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CtfTimelineModel::collapsedRow(int index) const
|
int CtfTimelineModel::collapsedRow(int index) const
|
||||||
@@ -187,6 +187,8 @@ void CtfTimelineModel::finalize(double traceBegin, double traceEnd, const QStrin
|
|||||||
m_details[index].insert(6, {reuse(Tr::tr("Unfinished")), reuse(Tr::tr("true"))});
|
m_details[index].insert(6, {reuse(Tr::tr("Unfinished")), reuse(Tr::tr("true"))});
|
||||||
}
|
}
|
||||||
computeNesting();
|
computeNesting();
|
||||||
|
m_rows = computeRows(&m_maxStackSize);
|
||||||
|
++m_maxStackSize; // index -> count
|
||||||
|
|
||||||
QVector<std::string> sortedCounterNames = m_counterNames;
|
QVector<std::string> sortedCounterNames = m_counterNames;
|
||||||
std::sort(sortedCounterNames.begin(), sortedCounterNames.end());
|
std::sort(sortedCounterNames.begin(), sortedCounterNames.end());
|
||||||
@@ -233,8 +235,6 @@ qint64 CtfTimelineModel::newStackEvent(const json &event, qint64 normalizedTime,
|
|||||||
const std::string &eventPhase, const std::string &name,
|
const std::string &eventPhase, const std::string &name,
|
||||||
int selectionId)
|
int selectionId)
|
||||||
{
|
{
|
||||||
int nestingLevel = m_openEventIds.size();
|
|
||||||
m_maxStackSize = std::max(qsizetype(m_maxStackSize), qsizetype(m_openEventIds.size() + 1));
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
qint64 duration = -1;
|
qint64 duration = -1;
|
||||||
if (eventPhase == CtfEventTypeBegin) {
|
if (eventPhase == CtfEventTypeBegin) {
|
||||||
@@ -250,29 +250,21 @@ qint64 CtfTimelineModel::newStackEvent(const json &event, qint64 normalizedTime,
|
|||||||
duration = qint64(event[CtfDurationKey]) * 1000;
|
duration = qint64(event[CtfDurationKey]) * 1000;
|
||||||
index = insert(normalizedTime, duration, selectionId);
|
index = insert(normalizedTime, duration, selectionId);
|
||||||
for (int i = m_openEventIds.size() - 1; i >= 0; --i) {
|
for (int i = m_openEventIds.size() - 1; i >= 0; --i) {
|
||||||
if (m_openEventIds[i] >= index) {
|
if (m_openEventIds[i] >= index)
|
||||||
++m_openEventIds[i];
|
++m_openEventIds[i];
|
||||||
// if the event is before an open event, the nesting level decreases:
|
|
||||||
--nestingLevel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
index = insert(normalizedTime, 0, selectionId);
|
index = insert(normalizedTime, 0, selectionId);
|
||||||
for (int i = m_openEventIds.size() - 1; i >= 0; --i) {
|
for (int i = m_openEventIds.size() - 1; i >= 0; --i) {
|
||||||
if (m_openEventIds[i] >= index) {
|
if (m_openEventIds[i] >= index)
|
||||||
++m_openEventIds[i];
|
++m_openEventIds[i];
|
||||||
--nestingLevel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index >= m_details.size()) {
|
if (index >= m_details.size()) {
|
||||||
m_details.resize(index + 1);
|
m_details.resize(index + 1);
|
||||||
m_details[index] = QMap<int, QPair<QString, QString>>();
|
m_details[index] = QMap<int, QPair<QString, QString>>();
|
||||||
m_nestingLevels.resize(index + 1);
|
|
||||||
m_nestingLevels[index] = nestingLevel;
|
|
||||||
} else {
|
} else {
|
||||||
m_details.insert(index, QMap<int, QPair<QString, QString>>());
|
m_details.insert(index, QMap<int, QPair<QString, QString>>());
|
||||||
m_nestingLevels.insert(index, nestingLevel);
|
|
||||||
}
|
}
|
||||||
if (m_counterValues.size() > index) {
|
if (m_counterValues.size() > index) {
|
||||||
// if the event was inserted before any counter, we need
|
// if the event was inserted before any counter, we need
|
||||||
|
@@ -73,7 +73,7 @@ protected:
|
|||||||
QString m_processName;
|
QString m_processName;
|
||||||
|
|
||||||
int m_maxStackSize = 0;
|
int m_maxStackSize = 0;
|
||||||
QVector<int> m_nestingLevels;
|
QVector<int> m_rows;
|
||||||
QVector<QMap<int, QPair<QString, QString>>> m_details;
|
QVector<QMap<int, QPair<QString, QString>>> m_details;
|
||||||
QSet<int> m_handledTypeIds;
|
QSet<int> m_handledTypeIds;
|
||||||
QStack<int> m_openEventIds;
|
QStack<int> m_openEventIds;
|
||||||
|
@@ -57,6 +57,7 @@ private slots:
|
|||||||
void rowCount();
|
void rowCount();
|
||||||
void prevNext();
|
void prevNext();
|
||||||
void parentingOfEqualStarts();
|
void parentingOfEqualStarts();
|
||||||
|
void rows();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TimelineModelAggregator aggregator;
|
TimelineModelAggregator aggregator;
|
||||||
@@ -463,6 +464,18 @@ void tst_TimelineModel::parentingOfEqualStarts()
|
|||||||
QCOMPARE(dummy.lastIndex(2), 1);
|
QCOMPARE(dummy.lastIndex(2), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_TimelineModel::rows()
|
||||||
|
{
|
||||||
|
DummyModel dummy(&aggregator);
|
||||||
|
dummy.loadData();
|
||||||
|
int maxlevel;
|
||||||
|
const QList<int> levels = dummy.computeRows(&maxlevel);
|
||||||
|
QCOMPARE(levels.at(0), 0);
|
||||||
|
QCOMPARE(levels.at(7), 7);
|
||||||
|
QCOMPARE(levels.at(10), 2);
|
||||||
|
QCOMPARE(maxlevel, 15);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(tst_TimelineModel)
|
QTEST_GUILESS_MAIN(tst_TimelineModel)
|
||||||
|
|
||||||
#include "tst_timelinemodel.moc"
|
#include "tst_timelinemodel.moc"
|
||||||
|
Reference in New Issue
Block a user