bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(Element& element, RecursionData& recursionData)
{
    bool thisElementNeedsStyleRecalc = false;
    ASSERT(!recursionData.wholeSubtreeInvalid());

    unsigned index = 0;
    while (index < m_invalidationEntries.size()) {
        if (m_elementIndex > m_invalidationEntries[index].m_invalidationLimit) {
            // m_invalidationEntries[index] only applies to earlier siblings. Remove it.
            m_invalidationEntries[index] = m_invalidationEntries.last();
            m_invalidationEntries.removeLast();
            continue;
        }

        const SiblingInvalidationSet& invalidationSet = *m_invalidationEntries[index].m_invalidationSet;
        ++index;
        if (!invalidationSet.invalidatesElement(element))
            continue;

        if (invalidationSet.invalidatesSelf())
            thisElementNeedsStyleRecalc = true;

        if (const DescendantInvalidationSet* descendants = invalidationSet.siblingDescendants()) {
            if (descendants->wholeSubtreeInvalid()) {
                element.setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator));
                return true;
            }

            if (!descendants->isEmpty())
                recursionData.pushInvalidationSet(*descendants);
        }

    }
    return thisElementNeedsStyleRecalc;
}
void StyleInvalidator::pushInvalidationSetsForElement(Element& element, RecursionData& recursionData, SiblingData& siblingData)
{
    PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&element);
    ASSERT(pendingInvalidations);

    for (const auto& invalidationSet : pendingInvalidations->siblings())
        siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSet));

    if (!pendingInvalidations->descendants().isEmpty()) {
        for (const auto& invalidationSet : pendingInvalidations->descendants())
            recursionData.pushInvalidationSet(toDescendantInvalidationSet(*invalidationSet));
        if (UNLIKELY(*s_tracingEnabled)) {
            TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"),
                "StyleInvalidatorInvalidationTracking",
                TRACE_EVENT_SCOPE_THREAD,
                "data", InspectorStyleInvalidatorInvalidateEvent::invalidationList(element, pendingInvalidations->descendants()));
        }
    }
}
bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(Element& element, RecursionData& recursionData) const
{
    bool thisElementNeedsStyleRecalc = false;
    ASSERT(!recursionData.wholeSubtreeInvalid());

    unsigned index = 0;
    while (index < m_invalidationEntries.size()) {
        if (m_elementIndex > m_invalidationEntries[index].m_invalidationLimit) {
            // m_invalidationEntries[index] only applies to earlier siblings. Remove it.
            m_invalidationEntries[index] = m_invalidationEntries.last();
            m_invalidationEntries.removeLast();
            continue;
        }

        const SiblingInvalidationSet& invalidationSet = *m_invalidationEntries[index].m_invalidationSet;

        if (invalidationSet.invalidatesElement(element)) {
            const DescendantInvalidationSet& descendants = invalidationSet.descendants();
            if (descendants.wholeSubtreeInvalid()) {
                // Avoid directly setting SubtreeStyleChange on element, or ContainerNode::checkForChildrenAdjacentRuleChanges()
                // may propagate the SubtreeStyleChange to our own siblings' subtrees.

                for (Element* child = ElementTraversal::firstChild(element); child; child = ElementTraversal::nextSibling(*child)) {
                    child->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::SiblingSelector));
                }
                return true;
            }

            if (descendants.invalidatesSelf())
                thisElementNeedsStyleRecalc = true;

            if (!descendants.isEmpty())
                recursionData.pushInvalidationSet(descendants);
        }

        ++index;
    }
    return thisElementNeedsStyleRecalc;
}
void StyleInvalidator::pushInvalidationSetsForContainerNode(ContainerNode& node, RecursionData& recursionData, SiblingData& siblingData)
{
    PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&node);
    ASSERT(pendingInvalidations);

    for (const auto& invalidationSet : pendingInvalidations->siblings())
        siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSet));

    if (node.getStyleChangeType() >= SubtreeStyleChange)
        return;

    if (!pendingInvalidations->descendants().isEmpty()) {
        for (const auto& invalidationSet : pendingInvalidations->descendants())
            recursionData.pushInvalidationSet(*invalidationSet);
        if (UNLIKELY(*s_tracingEnabled)) {
            TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"),
                "StyleInvalidatorInvalidationTracking",
                TRACE_EVENT_SCOPE_THREAD,
                "data", InspectorStyleInvalidatorInvalidateEvent::invalidationList(node, pendingInvalidations->descendants()));
        }
    }
}