void QmlProfilerStatisticsChildrenModel::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_statisticsModel->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_statisticsModel->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 parentId = -1;

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

        QmlStatisticsRelativesMap &relativesMap = m_data[parentId];
        QmlStatisticsRelativesMap::Iterator it = relativesMap.find(event.typeIndex());
        if (it != relativesMap.end()) {
            it.value().calls++;
            it.value().duration += event.duration();
        } else {
            QmlStatisticsRelativesData child = {
                event.duration(),
                1,
                eventsInBindingLoop.contains(parentId)
            };
            relativesMap.insert(event.typeIndex(), child);
        }

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