File: SpanningTree.h

package info (click to toggle)
webkit2gtk 2.48.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 429,620 kB
  • sloc: cpp: 3,696,936; javascript: 194,444; ansic: 169,997; python: 46,499; asm: 19,276; ruby: 18,528; perl: 16,602; xml: 4,650; yacc: 2,360; sh: 2,098; java: 1,993; lex: 1,327; pascal: 366; makefile: 298
file content (86 lines) | stat: -rw-r--r-- 3,480 bytes parent folder | download | duplicates (14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
 * Copyright (C) 2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#pragma once

#include <wtf/GraphNodeWorklist.h>

template<typename Graph>
class SpanningTree {
    WTF_MAKE_FAST_ALLOCATED;
public:
    SpanningTree(Graph& graph)
        : m_graph(graph)
        , m_data(graph.template newMap<Data>())
    {
        ExtendedGraphNodeWorklist<typename Graph::Node, unsigned, typename Graph::Set> worklist;
        worklist.push(m_graph.root(), 0);
    
        size_t number = 0;

        while (GraphNodeWith<typename Graph::Node, unsigned> item = worklist.pop()) {
            typename Graph::Node block = item.node;
            unsigned successorIndex = item.data;
        
            // We initially push with successorIndex = 0 regardless of whether or not we have any
            // successors. This is so that we can assign our prenumber. Subsequently we get pushed
            // with higher successorIndex values. We finally push successorIndex == # successors
            // to calculate our post number.
            ASSERT(!successorIndex || successorIndex <= m_graph.successors(block).size());

            if (!successorIndex)
                m_data[block].pre = number++;
        
            if (successorIndex < m_graph.successors(block).size()) {
                unsigned nextSuccessorIndex = successorIndex + 1;
                // We need to push this even if this is out of bounds so we can compute
                // the post number.
                worklist.forcePush(block, nextSuccessorIndex);

                typename Graph::Node successorBlock = m_graph.successors(block)[successorIndex];
                worklist.push(successorBlock, 0);
            } else
                m_data[block].post = number++;
        }
    }

    // Returns true if a is a descendent of b.
    // Note a is a descendent of b if they're equal.
    bool isDescendent(typename Graph::Node a, typename Graph::Node b)
    {
        return m_data[b].pre <= m_data[a].pre
            && m_data[b].post >= m_data[a].post;
    }

private:
    struct Data {
        WTF_MAKE_STRUCT_FAST_ALLOCATED;
        size_t pre;
        size_t post;
    };

    Graph& m_graph;
    typename Graph::template Map<Data> m_data;
};