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 QmlProfilerStatisticsRelativesModel::loadEvent(const QmlEvent &event)
{
    // level computation
    switch (event.rangeStage()) {
    case RangeStart:
        // now lastparent is the new type
        ++m_level;
        m_typesPerLevel[m_level] = event.typeIndex();
        m_startTimesPerLevel[m_level] = event.timestamp();
        break;
    case RangeEnd: {
        int parentTypeIndex = -1;
        if (m_level > Constants::QML_MIN_LEVEL && m_typesPerLevel.contains(m_level-1))
            parentTypeIndex = m_typesPerLevel[m_level-1];

        int relativeTypeIndex = (m_relation == QmlProfilerStatisticsParents) ? parentTypeIndex :
                                                                               event.typeIndex();
        int selfTypeIndex = (m_relation == QmlProfilerStatisticsParents) ? event.typeIndex() :
                                                                           parentTypeIndex;

        QmlStatisticsRelativesMap &relativesMap = m_data[selfTypeIndex];
        QmlStatisticsRelativesMap::Iterator it = relativesMap.find(relativeTypeIndex);
        if (it != relativesMap.end()) {
            it.value().calls++;
            it.value().duration += event.timestamp() - m_startTimesPerLevel[m_level];
        } else {
            QmlStatisticsRelativesData relative = {
                event.timestamp() - m_startTimesPerLevel[m_level],
                1,
                false
            };
            relativesMap.insert(relativeTypeIndex, relative);
        }
        --m_level;
        break;
    }
    default:
        break;
    }
}