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

Function SSpaths_next

src/procedures/proc_ss_paths.c:425–494  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

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

Callers 3

SSpaths_all_minimalFunction · 0.85
SSpaths_single_minimalFunction · 0.85
SSpaths_k_minimalFunction · 0.85

Calls 11

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_EdgeCountFunction · 0.85
Path_PopEdgeFunction · 0.85
_get_value_or_defualtFunction · 0.70
addNeighborsFunction · 0.70

Tested by

no test coverage detected