MCPcopy Create free account
hub / github.com/RedisGraph/RedisGraph / AllShortestPaths_NextPath

Function AllShortestPaths_NextPath

src/algorithms/all_shortest_paths.c:105–167  ·  view source on GitHub ↗

find paths from src to dest by traversing from dest to src using DFS inspecting nodes which where discovered by the previous call to `AllShortestPaths_FindMinimumLength`

Source from the content-addressed store, hash-verified

103// inspecting nodes which where discovered by
104// the previous call to `AllShortestPaths_FindMinimumLength`
105Path *AllShortestPaths_NextPath
106(
107 AllPathsCtx *ctx
108) {
109 ASSERT(ctx != NULL);
110
111 uint32_t depth = Path_NodeCount(ctx->path);
112 if(depth > 0) {
113 // a full path already returned
114 // advance to next path by backtracking
115 depth--;
116 } else {
117 if(array_len(ctx->levels[0]) == 0) return NULL;
118
119 Path_EnsureLen(ctx->path, ctx->minLen);
120 LevelConnection frontierConnection = array_pop(ctx->levels[0]);
121 Node frontierNode = frontierConnection.node;
122 Path_SetNode(ctx->path, ctx->minLen - depth - 1, frontierNode);
123 depth++;
124 addNeighbors(ctx, &frontierConnection, depth, ctx->dir);
125 }
126
127 // as long as we didn't found a full path from src to dest
128 while (depth < ctx->maxLen) {
129 if (array_len(ctx->levels[depth]) > 0) {
130 // get a new node from the frontier
131 bool is_visited;
132 LevelConnection frontierConnection = array_pop(ctx->levels[depth]);
133 Node frontierNode = frontierConnection.node;
134 NodeID frontierID = ENTITY_GET_ID(&frontierNode);
135 GrB_Info info = GrB_Vector_extractElement_BOOL(&is_visited,
136 ctx->visited, frontierID);
137
138 // consider only previously discovered nodes
139 if(info == GrB_NO_VALUE) continue;
140
141 // if we reached to the end of the path and this node is not the
142 // dst node continue
143 if(depth == ctx->maxLen - 1 &&
144 frontierID != ENTITY_GET_ID(ctx->dst)) {
145 continue;
146 }
147
148 Path_SetNode(ctx->path, ctx->minLen - depth - 1, frontierNode);
149 Path_SetEdge(ctx->path, ctx->minLen - depth - 1, frontierConnection.edge);
150
151 if(depth == ctx->maxLen - 1) break;
152
153 depth++;
154 addNeighbors(ctx, &frontierConnection, depth, ctx->dir);
155 } else {
156 depth--;
157 if(depth == 0) {
158 Path_Clear(ctx->path);
159 // first level fully consumed
160 // there are no more paths leading from src to dest, we're done
161 return NULL;
162 }

Callers 1

AllPathsCtx_NextPathFunction · 0.85

Calls 7

Path_NodeCountFunction · 0.85
array_lenFunction · 0.85
Path_EnsureLenFunction · 0.85
Path_SetNodeFunction · 0.85
Path_SetEdgeFunction · 0.85
Path_ClearFunction · 0.85
addNeighborsFunction · 0.70

Tested by

no test coverage detected