| 141 | } |
| 142 | |
| 143 | static SIValue *Proc_BFS_Step |
| 144 | ( |
| 145 | ProcedureCtx *ctx |
| 146 | ) { |
| 147 | ASSERT(ctx->privateData); |
| 148 | |
| 149 | BFSCtx *bfs_ctx = (BFSCtx *)ctx->privateData; |
| 150 | |
| 151 | // return NULL if the BFS for this source has already been emitted |
| 152 | // or there are no connected nodes |
| 153 | if(bfs_ctx->depleted || bfs_ctx->n == 0) return NULL; |
| 154 | |
| 155 | bool yield_nodes = (bfs_ctx->yield_nodes != NULL); |
| 156 | bool yield_edges = (bfs_ctx->yield_edges != NULL); |
| 157 | |
| 158 | // build arrays for the outputs the user has requested |
| 159 | uint n = bfs_ctx->n; |
| 160 | SIValue nodes, edges; |
| 161 | if(yield_nodes) nodes = SI_Array(n); |
| 162 | if(yield_edges) edges = SI_Array(n); |
| 163 | Edge *edge = array_new(Edge, 1); |
| 164 | |
| 165 | // setup result iterator |
| 166 | NodeID id; |
| 167 | GrB_Info res; |
| 168 | GxB_Iterator iter; |
| 169 | |
| 170 | UNUSED(res); |
| 171 | res = GxB_Iterator_new(&iter); |
| 172 | ASSERT(res == GrB_SUCCESS); |
| 173 | res = GxB_Vector_Iterator_attach(iter, bfs_ctx->nodes, NULL); |
| 174 | ASSERT(res == GrB_SUCCESS); |
| 175 | res = GxB_Vector_Iterator_seek(iter, 0); |
| 176 | |
| 177 | while(res == GrB_SUCCESS) { |
| 178 | id = GxB_Vector_Iterator_getIndex(iter); |
| 179 | |
| 180 | // get the reached node |
| 181 | if(yield_nodes) { |
| 182 | // append each reachable node to the nodes output array |
| 183 | Node n = GE_NEW_NODE(); |
| 184 | Graph_GetNode(bfs_ctx->g, id, &n); |
| 185 | SIArray_Append(&nodes, SI_Node(&n)); |
| 186 | } |
| 187 | |
| 188 | if(yield_edges) { |
| 189 | array_clear(edge); |
| 190 | GrB_Index parent_id; |
| 191 | // find the parent of the reached node |
| 192 | GrB_Info res = GrB_Vector_extractElement(&parent_id, |
| 193 | bfs_ctx->parents, id); |
| 194 | ASSERT(res == GrB_SUCCESS); |
| 195 | // retrieve edges connecting the parent node to the current node |
| 196 | // TODO: we only require a single edge |
| 197 | // `Graph_GetEdgesConnectingNodes` can return multiple edges |
| 198 | Graph_GetEdgesConnectingNodes(bfs_ctx->g, parent_id, id, bfs_ctx->reltype_id, &edge); |
| 199 | // append one edge to the edges output array |
| 200 | SIArray_Append(&edges, SI_Edge(edge)); |
nothing calls this directly
no test coverage detected