Skip to content

Commit

Permalink
Switch vertex stack with edge stack
Browse files Browse the repository at this point in the history
It's a little simpler.
  • Loading branch information
Ortham committed Nov 16, 2024
1 parent fa08c02 commit 883b006
Showing 1 changed file with 26 additions and 40 deletions.
66 changes: 26 additions & 40 deletions src/api/sorting/plugin_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,18 +137,13 @@ class GroupsVisitor : public boost::dfs_visitor<> {
vertexToIgnoreAsSource_(vertexToIgnoreAsSource),
logger_(getLogger()) {}

void start_vertex(GroupGraphVertex vertex, const GroupGraph&) {
pathStack_.push_back(vertex);
}

void tree_edge(GroupGraphEdge edge, const GroupGraph& graph) {
const auto source = boost::source(edge, graph);
const auto target = boost::target(edge, graph);

// Add the target group to the path stack so that edges can
// take into account whether its edge to the source group
// involves user metadata.
pathStack_.push_back(target);
// Add the edge to the stack so that adding edges can take into account
// whether its edge to the source group involves user metadata.
edgeStack_.push_back(edge);

// Find the plugins in the target group.
const auto targetPlugins = FindPluginsInGroup(target, graph);
Expand All @@ -160,24 +155,30 @@ class GroupsVisitor : public boost::dfs_visitor<> {
// Function to add edges from all the given plugins to all the target group
// plugins, and record any plugins that have edges added or at least one
// edge skipped.
const auto addEdges = [&](const std::vector<vertex_t>& fromPlugins) {
const auto addEdges = [&](const std::vector<vertex_t>& fromPlugins,
const size_t sourceGroupEdgeStackIndex) {
const auto groupPathInvolvesUserMetadata =
PathToGroupInvolvesUserMetadata(sourceGroupEdgeStackIndex, graph);
for (const auto& plugin : fromPlugins) {
AddEdges(plugin, targetPlugins, graph);
AddEdges(plugin, targetPlugins, groupPathInvolvesUserMetadata);
}
};

// Add edges for plugins buffered when adding edges from the previous
// groups in the path being walked.
for (const auto& fromPlugins : pluginsBuffers_) {
addEdges(fromPlugins);
for (size_t i = 0; i < pluginsBuffers_.size(); i += 1) {
// Each plugins buffer holds the plugins in the source group for the edge
// at the same index.
addEdges(pluginsBuffers_[i], i);
}

// For each source plugin, add an edge to each target plugin, unless the
// source group should be ignored (i.e. because the visitor has been
// configured to ignore the default group's plugins as sources).
if (source != vertexToIgnoreAsSource_) {
newBuffer = FindPluginsInGroup(source, graph);
addEdges(newBuffer);
// Current edge is the last one in the stack.
addEdges(newBuffer, edgeStack_.size() - 1);
}

// Add the new buffer to the stack.
Expand All @@ -195,37 +196,24 @@ class GroupsVisitor : public boost::dfs_visitor<> {
void finish_vertex(GroupGraphVertex, const GroupGraph&) { PopStacks(); }

private:
bool PathToGroupInvolvesUserMetadata(const std::string& fromGroupName,
bool PathToGroupInvolvesUserMetadata(const size_t sourceGroupEdgeStackIndex,
const GroupGraph& graph) const {
// The path involves user metadata if any edge between two groups in the
// path came from user metadata.

const auto fromGroupIt =
std::find_if(pathStack_.begin(),
pathStack_.end(),
[&](const GroupGraphVertex& vertex) {
return graph[vertex] == fromGroupName;
});

if (fromGroupIt == pathStack_.end()) {
if (sourceGroupEdgeStackIndex >= edgeStack_.size()) {
// Can't find group, this should be impossible.
throw std::logic_error("Cannot find group \"" + fromGroupName +
"\" in path stack");
throw std::logic_error("Given index is past the end of the path stack");
}

// The target group is always the most recent group in the stack, so we
// don't need to look for it.

if (pathStack_.size() < 2) {
return false;
}

bool pathInvolvesUserMetadata = false;

for (auto it = fromGroupIt; it != std::prev(pathStack_.end()); ++it) {
const auto edge = boost::edge(*it, *std::next(it), graph);
const auto begin = std::next(edgeStack_.begin(), sourceGroupEdgeStackIndex);

pathInvolvesUserMetadata |= graph[edge.first] == EdgeType::userLoadAfter;
// The path involves user metadata if any edge between two groups in the
// path came from user metadata.
for (auto it = begin; it != edgeStack_.end(); ++it) {
pathInvolvesUserMetadata |= graph[*it] == EdgeType::userLoadAfter;
}

return pathInvolvesUserMetadata;
Expand All @@ -242,14 +230,12 @@ class GroupsVisitor : public boost::dfs_visitor<> {
// skipped.
bool AddEdges(const vertex_t& fromVertex,
const std::vector<vertex_t>& toPlugins,
const GroupGraph& graph) {
const bool groupPathInvolvesUserMetadata) {
if (toPlugins.empty()) {
return true;
}

const auto& fromPlugin = pluginGraph_->GetPlugin(fromVertex);
const auto groupPathInvolvesUserMetadata =
PathToGroupInvolvesUserMetadata(fromPlugin.GetGroup(), graph);

bool anyEdgeSkipped = false;

Expand Down Expand Up @@ -282,8 +268,8 @@ class GroupsVisitor : public boost::dfs_visitor<> {
}

void PopStacks() {
if (!pathStack_.empty()) {
pathStack_.pop_back();
if (!edgeStack_.empty()) {
edgeStack_.pop_back();
}

if (!pluginsBuffers_.empty()) {
Expand All @@ -298,7 +284,7 @@ class GroupsVisitor : public boost::dfs_visitor<> {
std::shared_ptr<spdlog::logger> logger_;

// This represents the path to the current target vertex in the group graph.
std::vector<GroupGraphVertex> pathStack_;
std::vector<GroupGraphEdge> edgeStack_;

// This represents the plugins carried forward from each vertex in the path
// to the current target vertex in the group path.
Expand Down

0 comments on commit 883b006

Please sign in to comment.