<commit_before>#pragma once
#include "tatum/graph_walkers/TimingGraphWalker.hpp"
#include "tatum/TimingGraph.hpp"
#include "tatum/delay_calc/DelayCalculator.hpp"
#include "tatum/graph_visitors/GraphVisitor.hpp"

namespace tatum {

/**
 * A simple serial graph walker which traverses the timing graph in a levelized
 * manner.
 */
class SerialIncrWalker : public TimingGraphWalker {
    protected:
        void do_arrival_pre_traversal_impl(const TimingGraph& tg, const TimingConstraints& tc, GraphVisitor& visitor) override {
            size_t num_unconstrained = 0;

            LevelId first_level = *tg.levels().begin();
            for(NodeId node_id : tg.level_nodes(first_level)) {
                bool constrained = visitor.do_arrival_pre_traverse_node(tg, tc, node_id);

                if(!constrained) {
                    ++num_unconstrained;
                }
            }

            num_unconstrained_startpoints_ = num_unconstrained;
        }

        void do_required_pre_traversal_impl(const TimingGraph& tg, const TimingConstraints& tc, GraphVisitor& visitor) override {
            size_t num_unconstrained = 0;

            for(NodeId node_id : tg.logical_outputs()) {
                bool constrained = visitor.do_required_pre_traverse_node(tg, tc, node_id);

                if(!constrained) {
                    ++num_unconstrained;
                }
            }

            num_unconstrained_endpoints_ = num_unconstrained;
        }

        void do_arrival_traversal_impl(const TimingGraph& tg, const TimingConstraints& tc, const DelayCalculator& dc, GraphVisitor& visitor) override {
            const auto& levels = tg.levels();
            auto level_itr = levels.begin() + 1;

            for(NodeId node_id : tg.level_nodes(*level_itr)) {
                next_level_nodes_to_process_->push_back(node_id);
            }

            while(prepare_to_traverse_next_level()) {
                TATUM_ASSERT(level_itr != levels.end());
                LevelId level_id = *level_itr++;

                std::cout << "Processing Arr Level " << size_t(level_id) << ": " << level_nodes_to_process_->size() << " nodes\n";

                for (NodeId node : *level_nodes_to_process_) {

                    bool node_updated = visitor.do_arrival_traverse_node(tg, tc, dc, node);

                    if (node_updated) {

                        //Record that this node was updated, for later efficient slack update
                        nodes_to_update_slack_.emplace_back(node);

                        //Queue this node's downstream dependencies for updating
                        for (EdgeId out_edge : tg.node_out_edges(node)) {
                            NodeId snk_node = tg.edge_sink_node(out_edge);
                            next_level_nodes_to_process_->push_back(snk_node);
                        }
                    }
                }
            }
        }

        void do_required_traversal_impl(const TimingGraph& tg, const TimingConstraints& tc, const DelayCalculator& dc, GraphVisitor& visitor) override {
            /*
             *for(LevelId level_id : tg.reversed_levels()) {
             *    for(NodeId node_id : tg.level_nodes(level_id)) {
             *        visitor.do_required_traverse_node(tg, tc, dc, node_id);
             *    }
             *}
             */

            const auto& rev_levels = tg.reversed_levels();
            auto rev_level_itr = rev_levels.begin() + 1;

            for(NodeId node_id : tg.level_nodes(*rev_level_itr)) {
                next_level_nodes_to_process_->push_back(node_id);
            }

            while(prepare_to_traverse_next_level()) {
                TATUM_ASSERT(rev_level_itr != rev_levels.end());
                LevelId level_id = *rev_level_itr++;

                std::cout << "Processing Req Level " << size_t(level_id) << ": " << level_nodes_to_process_->size() << " nodes\n";


                for (NodeId node : *level_nodes_to_process_) {

                    bool node_updated = visitor.do_required_traverse_node(tg, tc, dc, node);

                    if (node_updated) {

                        //Record that this node was updated, for later efficient slack update
                        nodes_to_update_slack_.emplace_back(node);

                        //Queue this node's downstream dependencies for updating
                        for (EdgeId in_edge : tg.node_in_edges(node)) {
                            NodeId src_node = tg.edge_src_node(in_edge);<commit_msg>Fix incremental required time update<commit_after>#pragma once
#include "tatum/graph_walkers/TimingGraphWalker.hpp"
#include "tatum/TimingGraph.hpp"
#include "tatum/delay_calc/DelayCalculator.hpp"
#include "tatum/graph_visitors/GraphVisitor.hpp"

namespace tatum {

/**
 * A simple serial graph walker which traverses the timing graph in a levelized
 * manner.
 */
class SerialIncrWalker : public TimingGraphWalker {
    protected:
        void do_arrival_pre_traversal_impl(const TimingGraph& tg, const TimingConstraints& tc, GraphVisitor& visitor) override {
            size_t num_unconstrained = 0;

            LevelId first_level = *tg.levels().begin();
            for(NodeId node_id : tg.level_nodes(first_level)) {
                bool constrained = visitor.do_arrival_pre_traverse_node(tg, tc, node_id);

                if(!constrained) {
                    ++num_unconstrained;
                }
            }

            num_unconstrained_startpoints_ = num_unconstrained;
        }

        void do_required_pre_traversal_impl(const TimingGraph& tg, const TimingConstraints& tc, GraphVisitor& visitor) override {
            size_t num_unconstrained = 0;

            for(NodeId node_id : tg.logical_outputs()) {
                bool constrained = visitor.do_required_pre_traverse_node(tg, tc, node_id);

                if(!constrained) {
                    ++num_unconstrained;
                }
            }

            num_unconstrained_endpoints_ = num_unconstrained;
        }

        void do_arrival_traversal_impl(const TimingGraph& tg, const TimingConstraints& tc, const DelayCalculator& dc, GraphVisitor& visitor) override {
            const auto& levels = tg.levels();
            auto level_itr = levels.begin() + 1;

            for(NodeId node_id : tg.level_nodes(*level_itr)) {
                next_level_nodes_to_process_->push_back(node_id);
            }

            while(prepare_to_traverse_next_level()) {
                TATUM_ASSERT(level_itr != levels.end());
                LevelId level_id = *level_itr++;

                std::cout << "Processing Arr Level " << size_t(level_id) << ": " << level_nodes_to_process_->size() << " nodes\n";

                for (NodeId node : *level_nodes_to_process_) {

                    bool node_updated = visitor.do_arrival_traverse_node(tg, tc, dc, node);

                    if (node_updated) {

                        //Record that this node was updated, for later efficient slack update
                        nodes_to_update_slack_.emplace_back(node);

                        //Queue this node's downstream dependencies for updating
                        for (EdgeId out_edge : tg.node_out_edges(node)) {
                            NodeId snk_node = tg.edge_sink_node(out_edge);
                            next_level_nodes_to_process_->push_back(snk_node);
                        }
                    }
                }
            }
        }

        void do_required_traversal_impl(const TimingGraph& tg, const TimingConstraints& tc, const DelayCalculator& dc, GraphVisitor& visitor) override {
            /*
             *for(LevelId level_id : tg.reversed_levels()) {
             *    for(NodeId node_id : tg.level_nodes(level_id)) {
             *        visitor.do_required_traverse_node(tg, tc, dc, node_id);
             *    }
             *}
             */

            const auto& rev_levels = tg.reversed_levels();
            auto rev_level_itr = rev_levels.begin();

            for(NodeId node_id : tg.level_nodes(*rev_level_itr)) {
                next_level_nodes_to_process_->push_back(node_id);
            }

            while(prepare_to_traverse_next_level()) {
                TATUM_ASSERT(rev_level_itr != rev_levels.end());
                LevelId level_id = *rev_level_itr++;

                std::cout << "Processing Req Level " << size_t(level_id) << ": " << level_nodes_to_process_->size() << " nodes\n";


                for (NodeId node : *level_nodes_to_process_) {

                    bool node_updated = visitor.do_required_traverse_node(tg, tc, dc, node);

                    if (node_updated) {

                        //Record that this node was updated, for later efficient slack update
                        nodes_to_update_slack_.emplace_back(node);
                    }

                    if (node_updated || level_id == *rev_levels.begin()) {
                        //Queue this node's downstream dependencies for updating
                        for (EdgeId in_edge : tg.node_in_edges(node)) {
                            NodeId src_node = tg.edge_src_node(in_edge);
{'fraction_non_alphanumeric': 0.08878913947887015, 'fraction_numerical': 0.0007663674184366105, 'mean_word_length': 1.9073838319541694, 'pattern_counts': {'":': 4, '<': 43, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4733384', 'n_tokens_mistral': 2728, 'n_tokens_neox': 2528, 'n_words': 500}