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

Function SPpaths_next

src/procedures/proc_sp_paths.c:430–503  ·  view source on GitHub ↗

use DFS to find all paths from src to dst tracking cost and weight

Source from the content-addressed store, hash-verified

428
429// use DFS to find all paths from src to dst tracking cost and weight
430static void SPpaths_next
431(
432 SinglePairCtx *ctx,
433 WeightedPath *p,
434 double max_weight
435) {
436 // as long as path is not empty OR there are neighbors to traverse.
437 while(Path_NodeCount(ctx->path) || _SinglePairCtx_LevelNotEmpty(ctx, 0)) {
438 uint32_t depth = Path_NodeCount(ctx->path);
439
440 // can we advance?
441 if(_SinglePairCtx_LevelNotEmpty(ctx, depth)) {
442 // get a new frontier.
443 LevelConnection frontierConnection = array_pop(ctx->levels[depth]);
444 Node frontierNode = frontierConnection.node;
445
446 bool frontierAlreadyOnPath = Path_ContainsNode(ctx->path, &frontierNode);
447
448 // don't allow cycles
449 if(frontierAlreadyOnPath) continue;
450
451 // add frontier to path.
452 Path_AppendNode(ctx->path, frontierNode);
453
454 // if depth is 0 this is the source node, there is no leading edge to it.
455 // For depth > 0 for each frontier node, there is a leading edge.
456 if(depth > 0) {
457 SIValue c = _get_value_or_defualt((GraphEntity *)&frontierConnection.edge, ctx->cost_prop, SI_LongVal(1));
458 SIValue w = _get_value_or_defualt((GraphEntity *)&frontierConnection.edge, ctx->weight_prop, SI_LongVal(1));
459 if(p->cost + SI_GET_NUMERIC(c) <= ctx->max_cost && p->weight + SI_GET_NUMERIC(w) <= max_weight) {
460 p->cost += SI_GET_NUMERIC(c);
461 p->weight += SI_GET_NUMERIC(w);
462 Path_AppendEdge(ctx->path, frontierConnection.edge);
463 } else {
464 Path_PopNode(ctx->path);
465 continue;
466 }
467 }
468
469 // update path depth.
470 depth++;
471
472 // introduce neighbors only if path depth < maximum path length.
473 // and frontier wasn't already expanded.
474 if(depth < ctx->maxLen) {
475 addNeighbors(ctx, &frontierConnection, depth, ctx->dir);
476 }
477
478 // see if we can return path.
479 if(depth >= ctx->minLen && depth <= ctx->maxLen) {
480 Node dst = Path_Head(ctx->path);
481 if(ENTITY_GET_ID(ctx->dst) != ENTITY_GET_ID(&dst)) {
482 continue;
483 }
484 p->path = ctx->path;
485 return;
486 }
487 } else {

Callers 3

SPpaths_all_minimalFunction · 0.85
SPpaths_single_minimalFunction · 0.85
SPpaths_k_minimalFunction · 0.85

Calls 12

Path_NodeCountFunction · 0.85
Path_ContainsNodeFunction · 0.85
Path_AppendNodeFunction · 0.85
SI_LongValFunction · 0.85
Path_AppendEdgeFunction · 0.85
Path_PopNodeFunction · 0.85
Path_HeadFunction · 0.85
Path_EdgeCountFunction · 0.85
Path_PopEdgeFunction · 0.85
_get_value_or_defualtFunction · 0.70
addNeighborsFunction · 0.70

Tested by

no test coverage detected