| 125 | } |
| 126 | |
| 127 | SIValue AR_SHORTEST_PATH(SIValue *argv, int argc, void *private_data) { |
| 128 | if(SI_TYPE(argv[0]) == T_NULL) return SI_NullVal(); |
| 129 | if(SI_TYPE(argv[1]) == T_NULL) return SI_NullVal(); |
| 130 | |
| 131 | Node *srcNode = argv[0].ptrval; |
| 132 | Node *destNode = argv[1].ptrval; |
| 133 | ShortestPathCtx *ctx = private_data; |
| 134 | GrB_Index src_id = ENTITY_GET_ID(srcNode); |
| 135 | GrB_Index dest_id = ENTITY_GET_ID(destNode); |
| 136 | |
| 137 | GrB_Info res; |
| 138 | UNUSED(res); |
| 139 | Edge *edges = NULL; |
| 140 | GrB_Vector V = GrB_NULL; // vector of results |
| 141 | GrB_Vector PI = GrB_NULL; // vector backtracking results to their parents |
| 142 | GraphContext *gc = QueryCtx_GetGraphCtx(); |
| 143 | |
| 144 | GrB_Index max_level = (ctx->maxHops == EDGE_LENGTH_INF) ? 0 : ctx->maxHops; |
| 145 | |
| 146 | if(ctx->R == GrB_NULL) { |
| 147 | // First invocation, initialize unset context members. |
| 148 | if(ctx->reltype_count > 0) { |
| 149 | // Retrieve IDs of traversed relationship types. |
| 150 | ctx->reltypes = array_new(int, ctx->reltype_count); |
| 151 | for(uint i = 0; i < ctx->reltype_count; i ++) { |
| 152 | Schema *s = GraphContext_GetSchema(gc, ctx->reltype_names[i], SCHEMA_EDGE); |
| 153 | // Skip missing schemas |
| 154 | if(s) array_append(ctx->reltypes, Schema_GetID(s)); |
| 155 | } |
| 156 | |
| 157 | // Update the reltype count, as it may have changed due to missing schemas |
| 158 | ctx->reltype_count = array_len(ctx->reltypes); |
| 159 | } |
| 160 | |
| 161 | // Get edge matrix and transpose matrix, if available. |
| 162 | if(ctx->reltypes == NULL) { |
| 163 | // No edge types were specified, use the overall adjacency matrix. |
| 164 | ctx->free_matrices = true; |
| 165 | res = RG_Matrix_export(&ctx->R, Graph_GetAdjacencyMatrix(gc->g, |
| 166 | false)); |
| 167 | ASSERT(res == GrB_SUCCESS); |
| 168 | } else if(ctx->reltype_count == 0) { |
| 169 | // If edge types were specified but none were valid, |
| 170 | // use the zero matrix |
| 171 | ctx->free_matrices = true; |
| 172 | res = RG_Matrix_export(&ctx->R, Graph_GetZeroMatrix(gc->g)); |
| 173 | ASSERT(res == GrB_SUCCESS); |
| 174 | } else if(ctx->reltype_count == 1) { |
| 175 | ctx->free_matrices = true; |
| 176 | res = RG_Matrix_export(&ctx->R, Graph_GetRelationMatrix(gc->g, |
| 177 | ctx->reltypes[0], false)); |
| 178 | ASSERT(res == GrB_SUCCESS); |
| 179 | } else { |
| 180 | // we have multiple edge types, combine them into a boolean matrix |
| 181 | ctx->free_matrices = true; |
| 182 | GrB_Index dims = Graph_RequiredMatrixDim(gc->g); |
| 183 | res = GrB_Matrix_new(&ctx->R, GrB_BOOL, dims, dims); |
| 184 | ASSERT(res == GrB_SUCCESS); |
nothing calls this directly
no test coverage detected