Skip to content

Commit

Permalink
organizer: in/out-edges support - close #1069
Browse files Browse the repository at this point in the history
  • Loading branch information
skypjack committed May 6, 2024
1 parent d078633 commit 1e9ad0f
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 65 deletions.
50 changes: 35 additions & 15 deletions src/entt/entity/organizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@ class basic_organizer final {
struct vertex {
/**
* @brief Constructs a vertex of the task graph.
* @param vtype True if the vertex is a top-level one, false otherwise.
* @param data The data associated with the vertex.
* @param edges The indices of the children in the adjacency list.
* @param from List of in-edges of the vertex.
* @param to List of out-edges of the vertex.
*/
vertex(const bool vtype, vertex_data data, std::vector<std::size_t> edges)
: is_top_level{vtype},
node{std::move(data)},
reachable{std::move(edges)} {}
vertex(vertex_data data, std::vector<std::size_t> from, std::vector<std::size_t> to)
: node{std::move(data)},
in{std::move(from)},
out{std::move(to)} {}

/**
* @brief Fills a buffer with the type info objects for the writable
Expand Down Expand Up @@ -219,7 +219,7 @@ class basic_organizer final {
* @return True if the vertex is a top-level one, false otherwise.
*/
bool top_level() const noexcept {
return is_top_level;
return in.empty();
}

/**
Expand Down Expand Up @@ -254,12 +254,28 @@ class basic_organizer final {
return node.payload;
}

/**
* @brief Returns the list of in-edges of a vertex.
* @return The list of in-edges of a vertex.
*/
const std::vector<std::size_t> &in_edges() const noexcept {
return in;
}

/**
* @brief Returns the list of out-edges of a vertex.
* @return The list of out-edges of a vertex.
*/
const std::vector<std::size_t> &out_edges() const noexcept {
return out;
}

/**
* @brief Returns the list of nodes reachable from a given vertex.
* @return The list of nodes reachable from the vertex.
*/
const std::vector<std::size_t> &children() const noexcept {
return reachable;
[[deprecated("use ::out_edges")]] const std::vector<std::size_t> &children() const noexcept {
return out_edges();
}

/**
Expand All @@ -272,9 +288,9 @@ class basic_organizer final {
}

private:
bool is_top_level;
vertex_data node;
std::vector<std::size_t> reachable;
std::vector<std::size_t> in;
std::vector<std::size_t> out;
};

/**
Expand Down Expand Up @@ -375,14 +391,18 @@ class basic_organizer final {
auto adjacency_matrix = builder.graph();

for(auto curr: adjacency_matrix.vertices()) {
const auto iterable = adjacency_matrix.in_edges(curr);
std::vector<std::size_t> reachable{};
std::vector<std::size_t> in{};
std::vector<std::size_t> out{};

for(auto &&edge: adjacency_matrix.in_edges(curr)) {
in.push_back(edge.first);
}

for(auto &&edge: adjacency_matrix.out_edges(curr)) {
reachable.push_back(edge.second);
out.push_back(edge.second);
}

adjacency_list.emplace_back(iterable.cbegin() == iterable.cend(), vertices[curr], std::move(reachable));
adjacency_list.emplace_back(vertices[curr], std::move(in), std::move(out));
}

return adjacency_list;
Expand Down
153 changes: 103 additions & 50 deletions test/entt/entity/organizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,25 @@ TEST(Organizer, EmplaceFreeFunction) {
ASSERT_FALSE(graph[2u].top_level());
ASSERT_FALSE(graph[3u].top_level());

ASSERT_EQ(graph[0u].children().size(), 2u);
ASSERT_EQ(graph[1u].children().size(), 1u);
ASSERT_EQ(graph[2u].children().size(), 1u);
ASSERT_EQ(graph[3u].children().size(), 0u);

ASSERT_EQ(graph[0u].children()[0u], 1u);
ASSERT_EQ(graph[0u].children()[1u], 2u);
ASSERT_EQ(graph[1u].children()[0u], 3u);
ASSERT_EQ(graph[2u].children()[0u], 3u);
ASSERT_EQ(graph[0u].in_edges().size(), 0u);
ASSERT_EQ(graph[1u].in_edges().size(), 1u);
ASSERT_EQ(graph[2u].in_edges().size(), 1u);
ASSERT_EQ(graph[3u].in_edges().size(), 2u);

ASSERT_EQ(graph[1u].in_edges()[0u], 0u);
ASSERT_EQ(graph[2u].in_edges()[0u], 0u);
ASSERT_EQ(graph[3u].in_edges()[0u], 1u);
ASSERT_EQ(graph[3u].in_edges()[1u], 2u);

ASSERT_EQ(graph[0u].out_edges().size(), 2u);
ASSERT_EQ(graph[1u].out_edges().size(), 1u);
ASSERT_EQ(graph[2u].out_edges().size(), 1u);
ASSERT_EQ(graph[3u].out_edges().size(), 0u);

ASSERT_EQ(graph[0u].out_edges()[0u], 1u);
ASSERT_EQ(graph[0u].out_edges()[1u], 2u);
ASSERT_EQ(graph[1u].out_edges()[0u], 3u);
ASSERT_EQ(graph[2u].children()[0u], 3u); // NOLINT

for(auto &&vertex: graph) {
typename entt::organizer::function_type *cb = vertex.callback();
Expand Down Expand Up @@ -122,14 +132,23 @@ TEST(Organizer, EmplaceMemberFunction) {
ASSERT_FALSE(graph[2u].top_level());
ASSERT_FALSE(graph[3u].top_level());

ASSERT_EQ(graph[0u].children().size(), 1u);
ASSERT_EQ(graph[1u].children().size(), 1u);
ASSERT_EQ(graph[2u].children().size(), 1u);
ASSERT_EQ(graph[3u].children().size(), 0u);
ASSERT_EQ(graph[0u].in_edges().size(), 0u);
ASSERT_EQ(graph[1u].in_edges().size(), 1u);
ASSERT_EQ(graph[2u].in_edges().size(), 1u);
ASSERT_EQ(graph[3u].in_edges().size(), 1u);

ASSERT_EQ(graph[1u].in_edges()[0u], 0u);
ASSERT_EQ(graph[2u].in_edges()[0u], 1u);
ASSERT_EQ(graph[3u].in_edges()[0u], 2u);

ASSERT_EQ(graph[0u].out_edges().size(), 1u);
ASSERT_EQ(graph[1u].out_edges().size(), 1u);
ASSERT_EQ(graph[2u].out_edges().size(), 1u);
ASSERT_EQ(graph[3u].out_edges().size(), 0u);

ASSERT_EQ(graph[0u].children()[0u], 1u);
ASSERT_EQ(graph[1u].children()[0u], 2u);
ASSERT_EQ(graph[2u].children()[0u], 3u);
ASSERT_EQ(graph[0u].out_edges()[0u], 1u);
ASSERT_EQ(graph[1u].out_edges()[0u], 2u);
ASSERT_EQ(graph[2u].children()[0u], 3u); // NOLINT

for(auto &&vertex: graph) {
typename entt::organizer::function_type *cb = vertex.callback();
Expand Down Expand Up @@ -185,16 +204,24 @@ TEST(Organizer, EmplaceFreeFunctionWithPayload) {
ASSERT_FALSE(graph[3u].top_level());
ASSERT_FALSE(graph[4u].top_level());

ASSERT_EQ(graph[0u].children().size(), 1u);
ASSERT_EQ(graph[1u].children().size(), 1u);
ASSERT_EQ(graph[2u].children().size(), 1u);
ASSERT_EQ(graph[3u].children().size(), 1u);
ASSERT_EQ(graph[4u].children().size(), 0u);
ASSERT_EQ(graph[3u].in_edges().size(), 1u);
ASSERT_EQ(graph[4u].in_edges().size(), 3u);

ASSERT_EQ(graph[3u].in_edges()[0u], 2u);
ASSERT_EQ(graph[4u].in_edges()[0u], 0u);
ASSERT_EQ(graph[4u].in_edges()[1u], 1u);
ASSERT_EQ(graph[4u].in_edges()[2u], 3u);

ASSERT_EQ(graph[0u].out_edges().size(), 1u);
ASSERT_EQ(graph[1u].out_edges().size(), 1u);
ASSERT_EQ(graph[2u].out_edges().size(), 1u);
ASSERT_EQ(graph[3u].out_edges().size(), 1u);
ASSERT_EQ(graph[4u].out_edges().size(), 0u);

ASSERT_EQ(graph[0u].children()[0u], 4u);
ASSERT_EQ(graph[1u].children()[0u], 4u);
ASSERT_EQ(graph[2u].children()[0u], 3u);
ASSERT_EQ(graph[3u].children()[0u], 4u);
ASSERT_EQ(graph[0u].out_edges()[0u], 4u);
ASSERT_EQ(graph[1u].out_edges()[0u], 4u);
ASSERT_EQ(graph[2u].out_edges()[0u], 3u);
ASSERT_EQ(graph[3u].children()[0u], 4u); // NOLINT

for(auto &&vertex: graph) {
typename entt::organizer::function_type *cb = vertex.callback();
Expand Down Expand Up @@ -261,14 +288,22 @@ TEST(Organizer, EmplaceDirectFunction) {
ASSERT_FALSE(graph[2u].top_level());
ASSERT_FALSE(graph[3u].top_level());

ASSERT_EQ(graph[0u].children().size(), 1u);
ASSERT_EQ(graph[1u].children().size(), 1u);
ASSERT_EQ(graph[2u].children().size(), 1u);
ASSERT_EQ(graph[3u].children().size(), 0u);
ASSERT_EQ(graph[1u].in_edges().size(), 1u);
ASSERT_EQ(graph[2u].in_edges().size(), 1u);
ASSERT_EQ(graph[3u].in_edges().size(), 1u);

ASSERT_EQ(graph[0u].children()[0u], 1u);
ASSERT_EQ(graph[1u].children()[0u], 2u);
ASSERT_EQ(graph[2u].children()[0u], 3u);
ASSERT_EQ(graph[1u].in_edges()[0u], 0u);
ASSERT_EQ(graph[2u].in_edges()[0u], 1u);
ASSERT_EQ(graph[3u].in_edges()[0u], 2u);

ASSERT_EQ(graph[0u].out_edges().size(), 1u);
ASSERT_EQ(graph[1u].out_edges().size(), 1u);
ASSERT_EQ(graph[2u].out_edges().size(), 1u);
ASSERT_EQ(graph[3u].out_edges().size(), 0u);

ASSERT_EQ(graph[0u].out_edges()[0u], 1u);
ASSERT_EQ(graph[1u].out_edges()[0u], 2u);
ASSERT_EQ(graph[2u].children()[0u], 3u); // NOLINT

for(auto &&vertex: graph) {
typename entt::organizer::function_type *cb = vertex.callback();
Expand Down Expand Up @@ -310,19 +345,32 @@ TEST(Organizer, SyncPoint) {
ASSERT_FALSE(graph[4u].top_level());
ASSERT_FALSE(graph[5u].top_level());

ASSERT_EQ(graph[0u].children().size(), 1u);
ASSERT_EQ(graph[1u].children().size(), 2u);
ASSERT_EQ(graph[2u].children().size(), 1u);
ASSERT_EQ(graph[3u].children().size(), 1u);
ASSERT_EQ(graph[4u].children().size(), 1u);
ASSERT_EQ(graph[5u].children().size(), 0u);

ASSERT_EQ(graph[0u].children()[0u], 1u);
ASSERT_EQ(graph[1u].children()[0u], 2u);
ASSERT_EQ(graph[1u].children()[1u], 3u);
ASSERT_EQ(graph[2u].children()[0u], 4u);
ASSERT_EQ(graph[3u].children()[0u], 4u);
ASSERT_EQ(graph[4u].children()[0u], 5u);
ASSERT_EQ(graph[1u].in_edges().size(), 1u);
ASSERT_EQ(graph[2u].in_edges().size(), 1u);
ASSERT_EQ(graph[3u].in_edges().size(), 1u);
ASSERT_EQ(graph[4u].in_edges().size(), 2u);
ASSERT_EQ(graph[5u].in_edges().size(), 1u);

ASSERT_EQ(graph[1u].in_edges()[0u], 0u);
ASSERT_EQ(graph[2u].in_edges()[0u], 1u);
ASSERT_EQ(graph[3u].in_edges()[0u], 1u);
ASSERT_EQ(graph[4u].in_edges()[0u], 2u);
ASSERT_EQ(graph[4u].in_edges()[1u], 3u);
ASSERT_EQ(graph[5u].in_edges()[0u], 4u);

ASSERT_EQ(graph[0u].out_edges().size(), 1u);
ASSERT_EQ(graph[1u].out_edges().size(), 2u);
ASSERT_EQ(graph[2u].out_edges().size(), 1u);
ASSERT_EQ(graph[3u].out_edges().size(), 1u);
ASSERT_EQ(graph[4u].out_edges().size(), 1u);
ASSERT_EQ(graph[5u].out_edges().size(), 0u);

ASSERT_EQ(graph[0u].out_edges()[0u], 1u);
ASSERT_EQ(graph[1u].out_edges()[0u], 2u);
ASSERT_EQ(graph[1u].out_edges()[1u], 3u);
ASSERT_EQ(graph[2u].out_edges()[0u], 4u);
ASSERT_EQ(graph[3u].out_edges()[0u], 4u);
ASSERT_EQ(graph[4u].children()[0u], 5u); // NOLINT

for(auto &&vertex: graph) {
typename entt::organizer::function_type *cb = vertex.callback();
Expand All @@ -349,12 +397,17 @@ TEST(Organizer, Override) {
ASSERT_TRUE(graph[1u].top_level());
ASSERT_FALSE(graph[2u].top_level());

ASSERT_EQ(graph[0u].children().size(), 1u);
ASSERT_EQ(graph[1u].children().size(), 1u);
ASSERT_EQ(graph[2u].children().size(), 0u);
ASSERT_EQ(graph[2u].in_edges().size(), 2u);

ASSERT_EQ(graph[2u].in_edges()[0u], 0u);
ASSERT_EQ(graph[2u].in_edges()[1u], 1u);

ASSERT_EQ(graph[0u].out_edges().size(), 1u);
ASSERT_EQ(graph[1u].out_edges().size(), 1u);
ASSERT_EQ(graph[2u].out_edges().size(), 0u);

ASSERT_EQ(graph[0u].children()[0u], 2u);
ASSERT_EQ(graph[1u].children()[0u], 2u);
ASSERT_EQ(graph[0u].out_edges()[0u], 2u);
ASSERT_EQ(graph[1u].children()[0u], 2u); // NOLINT
}

TEST(Organizer, Prepare) {
Expand Down

0 comments on commit 1e9ad0f

Please sign in to comment.