void QmlProfilerEventParentsModelProxy::loadData()
{
    clear();
    QmlProfilerDataModel *simpleModel = m_modelManager->qmlModel();
    if (simpleModel->isEmpty())
        return;

    // for level computation
    QHash<int, qint64> endtimesPerLevel;
    int level = QmlDebug::Constants::QML_MIN_LEVEL;
    endtimesPerLevel[0] = 0;

    const QSet<int> &eventsInBindingLoop = m_eventsModel->eventsInBindingLoop();

    // compute parent-child relationship and call count
    QHash<int, int> lastParent;
    const QVector<QmlProfilerDataModel::QmlEventData> eventList = simpleModel->getEvents();
    const QVector<QmlProfilerDataModel::QmlEventTypeData> typesList = simpleModel->getEventTypes();
    foreach (const QmlProfilerDataModel::QmlEventData &event, eventList) {
        // whitelist
        if (!m_eventsModel->eventTypeAccepted(typesList[event.typeIndex].rangeType))
            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;

        int parentTypeIndex = -1;
        if (level > QmlDebug::Constants::QML_MIN_LEVEL && lastParent.contains(level-1))
            parentTypeIndex = lastParent[level-1];

        QmlEventRelativesMap &relativesMap = m_data[event.typeIndex];
        QmlEventRelativesMap::Iterator it = relativesMap.find(parentTypeIndex);
        if (it != relativesMap.end()) {
            it.value().calls++;
            it.value().duration += event.duration;
        } else {
            QmlEventRelativesData parent = {
                event.duration,
                1,
                eventsInBindingLoop.contains(parentTypeIndex)
            };
            relativesMap.insert(parentTypeIndex, parent);
        }

        // now lastparent is the new type
        lastParent[level] = event.typeIndex;
    }
}
void QmlProfilerEventChildrenModelProxy::loadData()
{
    clear();
    QmlProfilerDataModel *simpleModel = m_modelManager->qmlModel();
    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<QmlProfilerDataModel::QmlEventData> eventList = simpleModel->getEvents();
    foreach (const QmlProfilerDataModel::QmlEventData &event, eventList) {
        // whitelist
        if (!m_eventsModel->eventTypeAccepted((QmlDebug::QmlEventType)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 = QmlProfilerDataModel::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;
    }
}