aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp')
-rw-r--r--plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp479
1 files changed, 0 insertions, 479 deletions
diff --git a/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp b/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp
deleted file mode 100644
index d1be7cfdb3..0000000000
--- a/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp
+++ /dev/null
@@ -1,479 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "qmlprofilereventsmodelproxy.h"
-#include "qmlprofilermodelmanager.h"
-#include "qmlprofilersimplemodel.h"
-
-#include <utils/qtcassert.h>
-
-#include <QVector>
-#include <QHash>
-#include <QUrl>
-#include <QString>
-#include <QStack>
-#include <QElapsedTimer>
-
-#include <QDebug>
-
-namespace QmlProfiler {
-namespace Internal {
-
-class QmlProfilerEventsModelProxy::QmlProfilerEventsModelProxyPrivate
-{
-public:
- QmlProfilerEventsModelProxyPrivate(QmlProfilerEventsModelProxy *qq) : q(qq) {}
- ~QmlProfilerEventsModelProxyPrivate() {}
-
- QHash<QString, QmlProfilerEventsModelProxy::QmlEventStats> data;
-
- QmlProfilerModelManager *modelManager;
- QmlProfilerEventsModelProxy *q;
-
- int modelId;
-
- QVector<int> acceptedTypes;
- QSet<QString> eventsInBindingLoop;
-};
-
-QmlProfilerEventsModelProxy::QmlProfilerEventsModelProxy(QmlProfilerModelManager *modelManager, QObject *parent)
- : QObject(parent), d(new QmlProfilerEventsModelProxyPrivate(this))
-{
- d->modelManager = modelManager;
- connect(modelManager->simpleModel(), SIGNAL(changed()), this, SLOT(dataChanged()));
- d->modelId = modelManager->registerModelProxy();
-
- d->acceptedTypes << QmlDebug::Compiling << QmlDebug::Creating << QmlDebug::Binding << QmlDebug::HandlingSignal;
-}
-
-QmlProfilerEventsModelProxy::~QmlProfilerEventsModelProxy()
-{
- delete d;
-}
-
-const QList<QmlProfilerEventsModelProxy::QmlEventStats> QmlProfilerEventsModelProxy::getData() const
-{
- return d->data.values();
-}
-
-void QmlProfilerEventsModelProxy::clear()
-{
- d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1);
- d->data.clear();
- d->eventsInBindingLoop.clear();
-}
-
-void QmlProfilerEventsModelProxy::limitToRange(qint64 rangeStart, qint64 rangeEnd)
-{
- loadData(rangeStart, rangeEnd);
-}
-
-void QmlProfilerEventsModelProxy::dataChanged()
-{
- if (d->modelManager->state() == QmlProfilerDataState::ProcessingData)
- loadData();
-
- if (d->modelManager->state() == QmlProfilerDataState::Empty)
- clear();
-}
-
-QSet<QString> QmlProfilerEventsModelProxy::eventsInBindingLoop() const
-{
- return d->eventsInBindingLoop;
-}
-
-void QmlProfilerEventsModelProxy::loadData(qint64 rangeStart, qint64 rangeEnd)
-{
- clear();
-
- qint64 qmlTime = 0;
- qint64 lastEndTime = 0;
- QHash <QString, QVector<qint64> > durations;
-
- const bool checkRanges = (rangeStart != -1) && (rangeEnd != -1);
-
- const QVector<QmlProfilerSimpleModel::QmlEventData> eventList
- = d->modelManager->simpleModel()->getEvents();
-
- // used by binding loop detection
- typedef QPair<QString, const QmlProfilerSimpleModel::QmlEventData*> CallStackEntry;
- QStack<CallStackEntry> callStack;
- callStack.push(CallStackEntry(QString(), 0)); // artificial root
-
- for (int i = 0; i < eventList.size(); ++i) {
- const QmlProfilerSimpleModel::QmlEventData *event = &eventList[i];
-
- if (!d->acceptedTypes.contains(event->eventType))
- continue;
-
- if (checkRanges) {
- if ((event->startTime + event->duration < rangeStart)
- || (event->startTime > rangeEnd))
- continue;
- }
-
- // put event in hash
- QString hash = QmlProfilerSimpleModel::getHashString(*event);
- if (!d->data.contains(hash)) {
- QmlEventStats stats = {
- event->displayName,
- hash,
- event->data.join(QLatin1String(" ")),
- event->location,
- event->eventType,
- event->bindingType,
- event->duration,
- 1, //calls
- event->duration, //minTime
- event->duration, // maxTime
- 0, //timePerCall
- 0, //percentOfTime
- 0, //medianTime
- false //isBindingLoop
- };
-
- d->data.insert(hash, stats);
-
- // for median computing
- durations.insert(hash, QVector<qint64>());
- durations[hash].append(event->duration);
- } else {
- // update stats
- QmlEventStats *stats = &d->data[hash];
-
- stats->duration += event->duration;
- if (event->duration < stats->minTime)
- stats->minTime = event->duration;
- if (event->duration > stats->maxTime)
- stats->maxTime = event->duration;
- stats->calls++;
-
- // for median computing
- durations[hash].append(event->duration);
- }
-
- // qml time computation
- if (event->startTime > lastEndTime) { // assume parent event if starts before last end
- qmlTime += event->duration;
- lastEndTime = event->startTime + event->duration;
- }
-
-
- //
- // binding loop detection
- //
- const QmlProfilerSimpleModel::QmlEventData *potentialParent = callStack.top().second;
- while (potentialParent
- && !(potentialParent->startTime + potentialParent->duration > event->startTime)) {
- callStack.pop();
- potentialParent = callStack.top().second;
- }
-
- // check whether event is already in stack
- bool inLoop = false;
- for (int ii = 1; ii < callStack.size(); ++ii) {
- if (callStack.at(ii).first == hash)
- inLoop = true;
- if (inLoop)
- d->eventsInBindingLoop.insert(hash);
- }
-
-
- CallStackEntry newEntry(hash, event);
- callStack.push(newEntry);
-
- d->modelManager->modelProxyCountUpdated(d->modelId, i, eventList.count()*2);
- }
-
- // post-process: calc mean time, median time, percentoftime
- foreach (const QString &hash, d->data.keys()) {
- QmlEventStats* stats = &d->data[hash];
- if (stats->calls > 0)
- stats->timePerCall = stats->duration / (double)stats->calls;
-
- QVector<qint64> eventDurations = durations.value(hash);
- if (!eventDurations.isEmpty()) {
- qSort(eventDurations);
- stats->medianTime = eventDurations.at(eventDurations.count()/2);
- }
-
- stats->percentOfTime = stats->duration * 100.0 / qmlTime;
- }
-
- // set binding loop flag
- foreach (const QString &eventHash, d->eventsInBindingLoop)
- d->data[eventHash].isBindingLoop = true;
-
- QString rootEventName = tr("<program>");
- QmlDebug::QmlEventLocation rootEventLocation(rootEventName, 1, 1);
-
- // insert root event
- QmlEventStats rootEvent = {
- rootEventName, //event.displayName,
- rootEventName, // hash
- tr("Main Program"), //event.details,
- rootEventLocation, // location
- (int)QmlDebug::Binding, // event type
- 0, // binding type
- qmlTime + 1,
- 1, //calls
- qmlTime + 1, //minTime
- qmlTime + 1, // maxTime
- qmlTime + 1, //timePerCall
- 100.0, //percentOfTime
- qmlTime + 1, //medianTime;
- false
- };
-
- d->data.insert(rootEventName, rootEvent);
-
- d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1);
- emit dataAvailable();
-}
-
-int QmlProfilerEventsModelProxy::count() const
-{
- return d->data.count();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-QmlProfilerEventRelativesModelProxy::QmlProfilerEventRelativesModelProxy(QmlProfilerModelManager *modelManager,
- QmlProfilerEventsModelProxy *eventsModel,
- QObject *parent)
- : QObject(parent)
-{
- QTC_CHECK(modelManager);
- m_modelManager = modelManager;
- connect(modelManager->simpleModel(), SIGNAL(changed()), this, SLOT(dataChanged()));
-
- QTC_CHECK(eventsModel);
- m_eventsModel = eventsModel;
-
- m_acceptedTypes << QmlDebug::Compiling << QmlDebug::Creating << QmlDebug::Binding << QmlDebug::HandlingSignal;
-}
-
-QmlProfilerEventRelativesModelProxy::~QmlProfilerEventRelativesModelProxy()
-{
-}
-
-const QmlProfilerEventRelativesModelProxy::QmlEventRelativesMap QmlProfilerEventRelativesModelProxy::getData(const QString &hash) const
-{
- if (m_data.contains(hash))
- return m_data[hash];
- return QmlEventRelativesMap();
-}
-
-int QmlProfilerEventRelativesModelProxy::count() const
-{
- return m_data.count();
-}
-
-void QmlProfilerEventRelativesModelProxy::clear()
-{
- m_data.clear();
-}
-
-void QmlProfilerEventRelativesModelProxy::dataChanged()
-{
- loadData();
-
- emit dataAvailable();
-}
-
-
-//////////////////////////////////////////////////////////////////////////////////
-QmlProfilerEventParentsModelProxy::QmlProfilerEventParentsModelProxy(QmlProfilerModelManager *modelManager,
- QmlProfilerEventsModelProxy *eventsModel,
- QObject *parent)
- : QmlProfilerEventRelativesModelProxy(modelManager, eventsModel, parent)
-{}
-
-QmlProfilerEventParentsModelProxy::~QmlProfilerEventParentsModelProxy()
-{}
-
-void QmlProfilerEventParentsModelProxy::loadData()
-{
- clear();
- QmlProfilerSimpleModel *simpleModel = m_modelManager->simpleModel();
- if (simpleModel->isEmpty())
- return;
-
- QHash<QString, QmlProfilerSimpleModel::QmlEventData> cachedEvents;
- QString rootEventName = tr("<program>");
- QmlProfilerSimpleModel::QmlEventData rootEvent = {
- rootEventName,
- QmlDebug::Binding,
- 0,
- 0,
- 0,
- QStringList() << tr("Main Program"),
- QmlDebug::QmlEventLocation(rootEventName, 0, 0),
- 0,0,0,0,0 // numericData fields
- };
- cachedEvents.insert(rootEventName, rootEvent);
-
- // for level computation
- QHash<int, qint64> endtimesPerLevel;
- int level = QmlDebug::Constants::QML_MIN_LEVEL;
- endtimesPerLevel[0] = 0;
-
- const QSet<QString> eventsInBindingLoop = m_eventsModel->eventsInBindingLoop();
-
- // compute parent-child relationship and call count
- QHash<int, QString> lastParent;
- //for (int index = fromIndex; index <= toIndex; index++) {
- const QVector<QmlProfilerSimpleModel::QmlEventData> eventList = simpleModel->getEvents();
- foreach (const QmlProfilerSimpleModel::QmlEventData &event, eventList) {
- // whitelist
- if (!m_acceptedTypes.contains(event.eventType))
- continue;
-
- // level computation
- if (endtimesPerLevel[level] > event.startTime) {
- level++;
- } else {
- while (level > QmlDebug::Constants::QML_MIN_LEVEL && endtimesPerLevel[level-1] <= event.startTime)
- level--;
- }
- endtimesPerLevel[level] = event.startTime + event.duration;
-
-
- QString parentHash = rootEventName;
- QString eventHash = QmlProfilerSimpleModel::getHashString(event);
-
- // save in cache
- if (!cachedEvents.contains(eventHash))
- cachedEvents.insert(eventHash, event);
-
- if (level > QmlDebug::Constants::QML_MIN_LEVEL && lastParent.contains(level-1))
- parentHash = lastParent[level-1];
-
- QmlProfilerSimpleModel::QmlEventData *parentEvent = &(cachedEvents[parentHash]);
-
- // generate placeholder if needed
- if (!m_data.contains(eventHash))
- m_data.insert(eventHash, QmlEventRelativesMap());
-
- if (m_data[eventHash].contains(parentHash)) {
- QmlEventRelativesData *parent = &(m_data[eventHash][parentHash]);
- parent->calls++;
- parent->duration += event.duration;
- } else {
- m_data[eventHash].insert(parentHash, QmlEventRelativesData());
- QmlEventRelativesData *parent = &(m_data[eventHash][parentHash]);
- parent->displayName = parentEvent->displayName;
- parent->eventType = parentEvent->eventType;
- parent->duration = event.duration;
- parent->calls = 1;
- parent->details = parentEvent->data.join(QLatin1String(""));
- parent->isBindingLoop = eventsInBindingLoop.contains(parentHash);
- }
-
- // now lastparent is a string with the hash
- lastParent[level] = eventHash;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-QmlProfilerEventChildrenModelProxy::QmlProfilerEventChildrenModelProxy(QmlProfilerModelManager *modelManager,
- QmlProfilerEventsModelProxy *eventsModel,
- QObject *parent)
- : QmlProfilerEventRelativesModelProxy(modelManager, eventsModel, parent)
-{}
-
-QmlProfilerEventChildrenModelProxy::~QmlProfilerEventChildrenModelProxy()
-{}
-
-void QmlProfilerEventChildrenModelProxy::loadData()
-{
- clear();
- QmlProfilerSimpleModel *simpleModel = m_modelManager->simpleModel();
- if (simpleModel->isEmpty())
- return;
-
- QString rootEventName = tr("<program>");
-
- // for level computation
- QHash<int, qint64> endtimesPerLevel;
- int level = QmlDebug::Constants::QML_MIN_LEVEL;
- endtimesPerLevel[0] = 0;
-
- const QSet<QString> eventsInBindingLoop = m_eventsModel->eventsInBindingLoop();
-
- // compute parent-child relationship and call count
- QHash<int, QString> lastParent;
- const QVector<QmlProfilerSimpleModel::QmlEventData> eventList = simpleModel->getEvents();
- foreach (const QmlProfilerSimpleModel::QmlEventData &event, eventList) {
- // whitelist
- if (!m_acceptedTypes.contains(event.eventType))
- continue;
-
- // level computation
- if (endtimesPerLevel[level] > event.startTime) {
- level++;
- } else {
- while (level > QmlDebug::Constants::QML_MIN_LEVEL && endtimesPerLevel[level-1] <= event.startTime)
- level--;
- }
- endtimesPerLevel[level] = event.startTime + event.duration;
-
- QString parentHash = rootEventName;
- QString eventHash = QmlProfilerSimpleModel::getHashString(event);
-
- if (level > QmlDebug::Constants::QML_MIN_LEVEL && lastParent.contains(level-1))
- parentHash = lastParent[level-1];
-
- // generate placeholder if needed
- if (!m_data.contains(parentHash))
- m_data.insert(parentHash, QmlEventRelativesMap());
-
- if (m_data[parentHash].contains(eventHash)) {
- QmlEventRelativesData *child = &(m_data[parentHash][eventHash]);
- child->calls++;
- child->duration += event.duration;
- } else {
- m_data[parentHash].insert(eventHash, QmlEventRelativesData());
- QmlEventRelativesData *child = &(m_data[parentHash][eventHash]);
- child->displayName = event.displayName;
- child->eventType = event.eventType;
- child->duration = event.duration;
- child->calls = 1;
- child->details = event.data.join(QLatin1String(""));
- child->isBindingLoop = eventsInBindingLoop.contains(parentHash);
- }
-
- // now lastparent is a string with the hash
- lastParent[level] = eventHash;
- }
-}
-
-
-
-}
-}