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;
    }
}
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;
    }
}