From 5cb60cdcf2300667a97d86a4c76439f6e80ce473 Mon Sep 17 00:00:00 2001 From: Aliqyan-21 Date: Thu, 23 Oct 2025 18:20:32 +0530 Subject: [PATCH 1/9] add(MIGRTraversal): layer-agnostic traversal --- include/migr_traversal.h | 52 ++++++++++++++++++++++++++++++++++++++++ src/migr_traversal.cpp | 6 +++++ 2 files changed, 58 insertions(+) create mode 100644 include/migr_traversal.h create mode 100644 src/migr_traversal.cpp diff --git a/include/migr_traversal.h b/include/migr_traversal.h new file mode 100644 index 0000000..0ceb741 --- /dev/null +++ b/include/migr_traversal.h @@ -0,0 +1,52 @@ +#ifndef MIGR_TRAVERSAL_H +#define MIGR_TRAVERSAL_H + +#include "migr.h" +#include "migr_semantic.h" + +/* +Rules: +- class and struct will be named in PascalCase +- class member functions and members will be named in snake_case +*/ + +enum class TraversalType { + DFS, + BFS, +}; + +enum class TraversalDirection { + FORWARD, // structural: children, semantic: outgoing edges + BACKWARD, // structural: parent, semantic: incoming edges + BIDIRECTIONAL, // both +}; + +/* + * A struct to represent path between any two connected nodes + * with full edge context + */ +struct TraversalPath { + std::vector> nodes; + std::vector edges; + int total_depth; + double path_weight; // NOTE: will not implemented in this iteration; for + // future weighted traversals (heuristics) + + TraversalPath() : total_depth(0), path_weight(0.0) {} +}; + +/* + * A layer-agnostic traversal implementation interface + * for all MIGRGraphLayer interface. + * Currently proviedes DFS/BFS with filtering, visiting and transformation + * capabilities meanwhile maintaining MIGR's pure IR nature. + */ +class MIGRTraversal { +public: + explicit MIGRTraversal(MIGRGraphLayer &layer); + +private: + MIGRGraphLayer &layer_; +}; + +#endif //! MIGR_TRAVERSAL_H diff --git a/src/migr_traversal.cpp b/src/migr_traversal.cpp new file mode 100644 index 0000000..768e33c --- /dev/null +++ b/src/migr_traversal.cpp @@ -0,0 +1,6 @@ +#include "migr_traversal.h" +#include "globals.h" + +MIGRTraversal::MIGRTraversal(MIGRGraphLayer &layer) : layer_(layer) { + _V_ << " [MigrTraversal] Traversal Interface Initialized." << std::endl; +} From a2761e2cda034001302d15b6bdac0c5192917be0 Mon Sep 17 00:00:00 2001 From: Aliqyan-21 Date: Thu, 23 Oct 2025 22:10:27 +0530 Subject: [PATCH 2/9] feat(MIGRTraversal): dfs collect engine --- include/migr_traversal.h | 10 +++++++ src/migr_traversal.cpp | 58 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/include/migr_traversal.h b/include/migr_traversal.h index 0ceb741..428f753 100644 --- a/include/migr_traversal.h +++ b/include/migr_traversal.h @@ -47,6 +47,16 @@ class MIGRTraversal { private: MIGRGraphLayer &layer_; + + /* Internal traversal engines */ + std::vector> + dfs_collect(const std::vector> &starts, + std::function predicate, int max_depth, + TraversalDirection direction) const; + + std::vector> + get_neighbours(const std::shared_ptr &node, + TraversalDirection direction) const; }; #endif //! MIGR_TRAVERSAL_H diff --git a/src/migr_traversal.cpp b/src/migr_traversal.cpp index 768e33c..61f143c 100644 --- a/src/migr_traversal.cpp +++ b/src/migr_traversal.cpp @@ -1,6 +1,62 @@ #include "migr_traversal.h" #include "globals.h" +#include MIGRTraversal::MIGRTraversal(MIGRGraphLayer &layer) : layer_(layer) { - _V_ << " [MigrTraversal] Traversal Interface Initialized." << std::endl; + _V_ << " [MIGRTraversal] Traversal Interface Initialized." << std::endl; +} + +/* + * Iterative dfs engine for collect + */ +std::vector> +MIGRTraversal::dfs_collect(const std::vector> &starts, + std::function predicate, + int max_depth, TraversalDirection direction) const { + std::vector> results; + std::unordered_set visited; + std::stack, int>> st; // [node : depth] + + // stack -> start nodes, with depth 0 + for (const auto &start : starts) { + if (start) { + st.push({start, 0}); + } + } + + while (!st.empty()) { + auto [node, depth] = st.top(); + st.pop(); + + if (!node || visited.count(node->id_)) { + continue; + } + + if (max_depth >= 0 && depth > max_depth) { + continue; + } + + visited.insert(node->id_); + + if (predicate(*node)) { + results.push_back(node); + } + + /* pushing neighbours (in reverse order) */ + auto neighbours = get_neighbours(node, direction); + for (auto it = neighbours.rbegin(); it != neighbours.rend(); ++it) { + if (*it && !visited.count((*it)->id_)) { + st.push({*it, depth + 1}); + } + } + } + _V_ << " [MIGRTraversal] DFS collected " << results.size() << " nodes" + << std::endl; + return results; +} + +std::vector> +MIGRTraversal::get_neighbours(const std::shared_ptr &node, + TraversalDirection direction) const { + // TODO: implement } From 0cba9365b381ddb6ada4907c780e53d9fb8b1d63 Mon Sep 17 00:00:00 2001 From: Aliqyan-21 Date: Thu, 23 Oct 2025 22:45:00 +0530 Subject: [PATCH 3/9] feat(MIGRTraversal): get neighbours implementation --- include/migr_traversal.h | 6 ++++++ src/migr_traversal.cpp | 44 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/migr_traversal.h b/include/migr_traversal.h index 428f753..bb14e95 100644 --- a/include/migr_traversal.h +++ b/include/migr_traversal.h @@ -57,6 +57,12 @@ class MIGRTraversal { std::vector> get_neighbours(const std::shared_ptr &node, TraversalDirection direction) const; + + std::vector> + get_forward_neighbours(const std::shared_ptr &node) const; + + std::vector> + get_backward_neighbours(const std::shared_ptr &node) const; }; #endif //! MIGR_TRAVERSAL_H diff --git a/src/migr_traversal.cpp b/src/migr_traversal.cpp index 61f143c..41d3302 100644 --- a/src/migr_traversal.cpp +++ b/src/migr_traversal.cpp @@ -58,5 +58,47 @@ MIGRTraversal::dfs_collect(const std::vector> &starts, std::vector> MIGRTraversal::get_neighbours(const std::shared_ptr &node, TraversalDirection direction) const { - // TODO: implement + if (!node) { + return {}; + } + + if (direction == TraversalDirection::FORWARD) { + return get_forward_neighbours(node); + } else if (direction == TraversalDirection::BACKWARD) { + return get_backward_neighbours(node); + } else { + // both.., + auto forward = get_forward_neighbours(node); + auto backward = get_backward_neighbours(node); + forward.insert(forward.end(), backward.begin(), backward.end()); + return forward; + } +} + +std::vector> MIGRTraversal::get_forward_neighbours( + const std::shared_ptr &node) const { + /* seeing if semantic layer */ + if (SemanticLayer *semantic = dynamic_cast(&layer_)) { + return semantic->get_semantic_targets(node->id_); + } + + /* otherwise return structural children */ + return node->children_; +} + +std::vector> MIGRTraversal::get_backward_neighbours( + const std::shared_ptr &node) const { + std::vector> neighbours; + + /* seeing if semantic layer */ + if (SemanticLayer *semantic = dynamic_cast(&layer_)) { + return semantic->get_semantic_sources(node->id_); + } + + /* if structural get parent if there */ + if (auto parent = node->parent_.lock()) { + neighbours.push_back(parent); + } + + return neighbours; } From 1fa4ff041bdceda10d76b8f53b7a4ac261f1755a Mon Sep 17 00:00:00 2001 From: Aliqyan-21 Date: Thu, 23 Oct 2025 23:02:03 +0530 Subject: [PATCH 4/9] feat(MIGRTraversal): dfs visit traversal engine --- include/migr_traversal.h | 4 +++ src/migr_traversal.cpp | 53 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/include/migr_traversal.h b/include/migr_traversal.h index bb14e95..c8837b3 100644 --- a/include/migr_traversal.h +++ b/include/migr_traversal.h @@ -54,6 +54,10 @@ class MIGRTraversal { std::function predicate, int max_depth, TraversalDirection direction) const; + bool dfs_visit(const std::vector> &starts, + std::function, int depth)> visitor, int max_depth, + TraversalDirection direction) const; + std::vector> get_neighbours(const std::shared_ptr &node, TraversalDirection direction) const; diff --git a/src/migr_traversal.cpp b/src/migr_traversal.cpp index 41d3302..4435b59 100644 --- a/src/migr_traversal.cpp +++ b/src/migr_traversal.cpp @@ -6,8 +6,12 @@ MIGRTraversal::MIGRTraversal(MIGRGraphLayer &layer) : layer_(layer) { _V_ << " [MIGRTraversal] Traversal Interface Initialized." << std::endl; } +//-----------------------------------// +// Internal Traversal Engines // +//-----------------------------------// + /* - * Iterative dfs engine for collect + * Iterative DFS engine for collect */ std::vector> MIGRTraversal::dfs_collect(const std::vector> &starts, @@ -55,6 +59,53 @@ MIGRTraversal::dfs_collect(const std::vector> &starts, return results; } +/* + * Iterative DFS engine for visit + */ +bool MIGRTraversal::dfs_visit( + const std::vector> &starts, + std::function, int depth)> visitor, + int max_depth, TraversalDirection direction) const { + std::unordered_set visited; + std::stack, int>> st; + + for (const auto &start : starts) { + if (start) { + st.push({start, 0}); + } + } + + while (!st.empty()) { + auto [node, depth] = st.top(); + st.pop(); + + if (!node || visited.count(node->id_)) { + continue; + } + + if (max_depth >= 0 && depth > max_depth) { + continue; + } + + visited.insert(node->id_); + + if (!visitor(node, depth)) { + _V_ << " [MIGRTraversal] DFS visit terminated early by visitor" + << std::endl; + return false; + } + + auto neighbours = get_neighbours(node, direction); + for (auto it = neighbours.rbegin(); it != neighbours.rend(); ++it) { + if (*it && !visited.count((*it)->id_)) { + st.push({*it, depth + 1}); + } + } + } + + return true; +} + std::vector> MIGRTraversal::get_neighbours(const std::shared_ptr &node, TraversalDirection direction) const { From 2533c8e7db0f0c72b9502ba1bd65efbd12dd4a9e Mon Sep 17 00:00:00 2001 From: Aliqyan-21 Date: Thu, 23 Oct 2025 23:10:11 +0530 Subject: [PATCH 5/9] feat(MIGRTraversal): dfs tranformer engine --- include/migr_traversal.h | 17 ++++++++++--- src/migr_traversal.cpp | 53 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/include/migr_traversal.h b/include/migr_traversal.h index c8837b3..ca579dd 100644 --- a/include/migr_traversal.h +++ b/include/migr_traversal.h @@ -48,15 +48,24 @@ class MIGRTraversal { private: MIGRGraphLayer &layer_; - /* Internal traversal engines */ + /* Internal Traversal Engines */ std::vector> dfs_collect(const std::vector> &starts, std::function predicate, int max_depth, TraversalDirection direction) const; - bool dfs_visit(const std::vector> &starts, - std::function, int depth)> visitor, int max_depth, - TraversalDirection direction) const; + bool + dfs_visit(const std::vector> &starts, + std::function, int depth)> visitor, + int max_depth, TraversalDirection direction) const; + + /* Internal Transform Engine */ + std::vector> dfs_transform( + const std::vector> &starts, + std::function(std::shared_ptr, + int depth)> + transformer, + int max_depth, TraversalDirection direction) const; std::vector> get_neighbours(const std::shared_ptr &node, diff --git a/src/migr_traversal.cpp b/src/migr_traversal.cpp index 4435b59..76dff6c 100644 --- a/src/migr_traversal.cpp +++ b/src/migr_traversal.cpp @@ -106,6 +106,59 @@ bool MIGRTraversal::dfs_visit( return true; } +//-----------------------------// +// Internal Transform Engine // +//-----------------------------// + +/* + * Iterative DFS engine for transform + */ +std::vector> MIGRTraversal::dfs_transform( + const std::vector> &starts, + std::function(std::shared_ptr, + int depth)> + transformer, + int max_depth, TraversalDirection direction) const { + std::vector> results; + std::unordered_set visited; + std::stack, int>> st; + + for (const auto &start : starts) { + if (start) { + st.push({start, 0}); + } + } + + while (!st.empty()) { + auto [node, depth] = st.top(); + st.pop(); + + if (!node || visited.count(node->id_)) { + continue; + } + + if (max_depth >= 0 && depth > max_depth) { + continue; + } + + visited.insert(node->id_); + + auto transformed = transformer(node, depth); + if (transformed) { + results.push_back(transformed); + } + auto neighbors = get_neighbours(node, direction); + for (auto it = neighbors.rbegin(); it != neighbors.rend(); ++it) { + if (*it && !visited.count((*it)->id_)) { + st.push({*it, depth + 1}); + } + } + } + _V_ << " [MIGRTraversal] DFS transformed " << results.size() << " nodes" + << std::endl; + return results; +} + std::vector> MIGRTraversal::get_neighbours(const std::shared_ptr &node, TraversalDirection direction) const { From c10f4f11990102676fcbfd5d34cf4449c862a717 Mon Sep 17 00:00:00 2001 From: Aliqyan-21 Date: Fri, 24 Oct 2025 10:08:32 +0530 Subject: [PATCH 6/9] chore(MIGRTraversal): comments --- include/migr_traversal.h | 1 + src/migr_traversal.cpp | 43 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/include/migr_traversal.h b/include/migr_traversal.h index ca579dd..6c0e9e9 100644 --- a/include/migr_traversal.h +++ b/include/migr_traversal.h @@ -67,6 +67,7 @@ class MIGRTraversal { transformer, int max_depth, TraversalDirection direction) const; + /* Neighbour Helpers */ std::vector> get_neighbours(const std::shared_ptr &node, TraversalDirection direction) const; diff --git a/src/migr_traversal.cpp b/src/migr_traversal.cpp index 76dff6c..e0fb12b 100644 --- a/src/migr_traversal.cpp +++ b/src/migr_traversal.cpp @@ -11,7 +11,14 @@ MIGRTraversal::MIGRTraversal(MIGRGraphLayer &layer) : layer_(layer) { //-----------------------------------// /* - * Iterative DFS engine for collect + * Performs a depth-first search (DFS) to collect nodes starting from the + * given start nodes. + * Nodes are visited iteratively using a stack. + * The traversal respects a max depth and traversal + * direction (forward, backward, or bidirectional). + * + * Each visited node is tested against the provided predicate function; if + * the predicate returns true, the node is added to result vector. */ std::vector> MIGRTraversal::dfs_collect(const std::vector> &starts, @@ -60,7 +67,13 @@ MIGRTraversal::dfs_collect(const std::vector> &starts, } /* - * Iterative DFS engine for visit + * Performs an iterative depth-first search (DFS) traversal to visit nodes + * according to the visitor function Starting from the provided nodes and + * max depth. + * + * If visitor returns false at some point, then it's early termination and it + * returns false in that case, otherwise if traversal completes then returns + * true. */ bool MIGRTraversal::dfs_visit( const std::vector> &starts, @@ -111,7 +124,13 @@ bool MIGRTraversal::dfs_visit( //-----------------------------// /* - * Iterative DFS engine for transform + * Performs a depth-first search (DFS) traversal and applies the transformation + * function to each visited node. The transformer function receives the + * current node and depth, and returns a possibly transformed node according to + * the tranformer function to be include in results vector. + * + * traversal respects max depth and direction. Transformed + * nodes are collected into a result vector. */ std::vector> MIGRTraversal::dfs_transform( const std::vector> &starts, @@ -159,6 +178,14 @@ std::vector> MIGRTraversal::dfs_transform( return results; } +//----------------------// +// Neighbour Helpers // +//----------------------// + +/* + * Returns neighbors of a node based on the specified traversal direction. + * (forward, backward, or bidirectional) + */ std::vector> MIGRTraversal::get_neighbours(const std::shared_ptr &node, TraversalDirection direction) const { @@ -179,6 +206,11 @@ MIGRTraversal::get_neighbours(const std::shared_ptr &node, } } +/* + * Gets forward neighbors of a node. + * - for semantic layers, returns outgoing semantic targets. + * - for structural layers, returns children nodes. + */ std::vector> MIGRTraversal::get_forward_neighbours( const std::shared_ptr &node) const { /* seeing if semantic layer */ @@ -190,6 +222,11 @@ std::vector> MIGRTraversal::get_forward_neighbours( return node->children_; } +/* + * Gets backward neighbors of a node. + * - for semantic layers, returns incoming semantic sources. + * - for structural layers, returns the parent node if present. + */ std::vector> MIGRTraversal::get_backward_neighbours( const std::shared_ptr &node) const { std::vector> neighbours; From 639e1e705fc90227a5391cd4af6abc55c6875eef Mon Sep 17 00:00:00 2001 From: Aliqyan-21 Date: Fri, 24 Oct 2025 10:30:46 +0530 Subject: [PATCH 7/9] feat(MIGRTraversal): bfs collect engine --- include/migr_traversal.h | 17 ++++++++ src/migr_traversal.cpp | 93 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/include/migr_traversal.h b/include/migr_traversal.h index 6c0e9e9..b01ef46 100644 --- a/include/migr_traversal.h +++ b/include/migr_traversal.h @@ -54,11 +54,21 @@ class MIGRTraversal { std::function predicate, int max_depth, TraversalDirection direction) const; + std::vector> + bfs_collect(const std::vector> &starts, + std::function predicate, int max_depth, + TraversalDirection direction) const; + bool dfs_visit(const std::vector> &starts, std::function, int depth)> visitor, int max_depth, TraversalDirection direction) const; + bool + bfs_visit(const std::vector> &starts, + std::function, int depth)> visitor, + int max_depth, TraversalDirection direction) const; + /* Internal Transform Engine */ std::vector> dfs_transform( const std::vector> &starts, @@ -67,6 +77,13 @@ class MIGRTraversal { transformer, int max_depth, TraversalDirection direction) const; + std::vector> bfs_transform( + const std::vector> &starts, + std::function(std::shared_ptr, + int depth)> + transformer, + int max_depth, TraversalDirection direction) const; + /* Neighbour Helpers */ std::vector> get_neighbours(const std::shared_ptr &node, diff --git a/src/migr_traversal.cpp b/src/migr_traversal.cpp index e0fb12b..bd29c97 100644 --- a/src/migr_traversal.cpp +++ b/src/migr_traversal.cpp @@ -1,5 +1,6 @@ #include "migr_traversal.h" #include "globals.h" +#include #include MIGRTraversal::MIGRTraversal(MIGRGraphLayer &layer) : layer_(layer) { @@ -66,6 +67,60 @@ MIGRTraversal::dfs_collect(const std::vector> &starts, return results; } +/* + * Performs a breadth-first search (BFS) to collect nodes starting from the + * given start nodes. + * Nodes are visited iteratively using a queue. + * The traversal respects a max depth and traversal + * direction (forward, backward, or bidirectional). + * + * Each visited node is tested against the provided predicate function; if + * the predicate returns true, the node is added to result vector. + */ +std::vector> +MIGRTraversal::bfs_collect(const std::vector> &starts, + std::function predicate, + int max_depth, TraversalDirection direction) const { + std::vector> results; + std::unordered_set visited; + std::queue, int>> qu; // [node : depth] + + for (const auto &start : starts) { + if (start) { + qu.push({start, 0}); + } + } + + while (!qu.empty()) { + auto [node, depth] = qu.front(); + qu.pop(); + + if (!node || visited.count(node->id_)) { + continue; + } + + if (max_depth >= 0 && depth > max_depth) { + continue; + } + + visited.insert(node->id_); + + if (predicate(*node)) { + results.push_back(node); + } + + auto neighbours = get_neighbours(node, direction); + for (const auto &neighbour : neighbours) { + if (neighbour && !visited.count(neighbour->id_)) { + qu.push({neighbour, depth + 1}); + } + } + } + _V_ << " [MIGRTraversal] BFS collected " << results.size() << " nodes" + << std::endl; + return results; +} + /* * Performs an iterative depth-first search (DFS) traversal to visit nodes * according to the visitor function Starting from the provided nodes and @@ -119,6 +174,22 @@ bool MIGRTraversal::dfs_visit( return true; } +/* + * Performs an iterative breadth-first search (BFS) traversal to visit nodes + * according to the visitor function Starting from the provided nodes and + * max depth. + * + * If visitor returns false at some point, then it's early termination and it + * returns false in that case, otherwise if traversal completes then returns + * true. + */ +bool MIGRTraversal::bfs_visit( + const std::vector> &starts, + std::function, int depth)> visitor, + int max_depth, TraversalDirection direction) const { + // TODO: implement +} + //-----------------------------// // Internal Transform Engine // //-----------------------------// @@ -166,8 +237,8 @@ std::vector> MIGRTraversal::dfs_transform( if (transformed) { results.push_back(transformed); } - auto neighbors = get_neighbours(node, direction); - for (auto it = neighbors.rbegin(); it != neighbors.rend(); ++it) { + auto neighbours = get_neighbours(node, direction); + for (auto it = neighbours.rbegin(); it != neighbours.rend(); ++it) { if (*it && !visited.count((*it)->id_)) { st.push({*it, depth + 1}); } @@ -178,6 +249,24 @@ std::vector> MIGRTraversal::dfs_transform( return results; } +/* + * Performs a breadth-first search (BFS) traversal and applies the transformation + * function to each visited node. The transformer function receives the + * current node and depth, and returns a possibly transformed node according to + * the tranformer function to be include in results vector. + * + * traversal respects max depth and direction. Transformed + * nodes are collected into a result vector. + */ +std::vector> MIGRTraversal::bfs_transform( + const std::vector> &starts, + std::function(std::shared_ptr, + int depth)> + transformer, + int max_depth, TraversalDirection direction) const { + // TODO: implement +} + //----------------------// // Neighbour Helpers // //----------------------// From 074485e3c99d2397945b2efdf23478f5f5d5c50f Mon Sep 17 00:00:00 2001 From: Aliqyan-21 Date: Fri, 24 Oct 2025 10:34:51 +0530 Subject: [PATCH 8/9] feat(MIGRTraversal): bfs visit engine --- src/migr_traversal.cpp | 46 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/migr_traversal.cpp b/src/migr_traversal.cpp index bd29c97..d89b3e6 100644 --- a/src/migr_traversal.cpp +++ b/src/migr_traversal.cpp @@ -187,7 +187,43 @@ bool MIGRTraversal::bfs_visit( const std::vector> &starts, std::function, int depth)> visitor, int max_depth, TraversalDirection direction) const { - // TODO: implement + std::unordered_set visited; + std::queue, int>> qu; + + for (const auto &start : starts) { + if (start) { + qu.push({start, 0}); + } + } + + while (!qu.empty()) { + auto [node, depth] = qu.front(); + qu.pop(); + + if (!node || visited.count(node->id_)) { + continue; + } + + if (max_depth >= 0 && depth > max_depth) { + continue; + } + + visited.insert(node->id_); + + if (!visitor(node, depth)) { + _V_ << " [MIGRTraversal] BFS visit terminated early by visitor" + << std::endl; + return false; + } + + auto neighbours = get_neighbours(node, direction); + for (const auto &neighbour : neighbours) { + if (neighbour && !visited.count(neighbour->id_)) { + qu.push({neighbour, depth + 1}); + } + } + } + return true; } //-----------------------------// @@ -250,10 +286,10 @@ std::vector> MIGRTraversal::dfs_transform( } /* - * Performs a breadth-first search (BFS) traversal and applies the transformation - * function to each visited node. The transformer function receives the - * current node and depth, and returns a possibly transformed node according to - * the tranformer function to be include in results vector. + * Performs a breadth-first search (BFS) traversal and applies the + * transformation function to each visited node. The transformer function + * receives the current node and depth, and returns a possibly transformed node + * according to the tranformer function to be include in results vector. * * traversal respects max depth and direction. Transformed * nodes are collected into a result vector. From 383a684bd1373ef8806a4e7534ef1f01bb8f3a67 Mon Sep 17 00:00:00 2001 From: Aliqyan-21 Date: Fri, 24 Oct 2025 10:37:48 +0530 Subject: [PATCH 9/9] feat(MIGRTraversal): bfs transform engine --- src/migr_traversal.cpp | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/migr_traversal.cpp b/src/migr_traversal.cpp index d89b3e6..5377c70 100644 --- a/src/migr_traversal.cpp +++ b/src/migr_traversal.cpp @@ -300,7 +300,45 @@ std::vector> MIGRTraversal::bfs_transform( int depth)> transformer, int max_depth, TraversalDirection direction) const { - // TODO: implement + std::vector> results; + std::unordered_set visited; + std::queue, int>> qu; + + for (const auto &start : starts) { + if (start) { + qu.push({start, 0}); + } + } + + while (!qu.empty()) { + auto [node, depth] = qu.front(); + qu.pop(); + + if (!node || visited.count(node->id_)) { + continue; + } + + if (max_depth >= 0 && depth > max_depth) { + continue; + } + + visited.insert(node->id_); + + auto transformed = transformer(node, depth); + if (transformed) { + results.push_back(transformed); + } + + auto neighbours = get_neighbours(node, direction); + for (const auto &neighbour : neighbours) { + if (neighbour && !visited.count(neighbour->id_)) { + qu.push({neighbour, depth + 1}); + } + } + } + _V_ << " [MIGRTraversal] BFS transformed " << results.size() << " nodes" + << std::endl; + return results; } //----------------------//