Skip to content

Conversation

@cvvergara
Copy link
Member

@cvvergara cvvergara commented Feb 1, 2026

Fixes #3049

Changes proposed in this pull request:

  • Using enumeration on existing process & drivers
  • New utilities to get the name of the function based on the enumeration
  • Moved static code to utilities

@pgRouting/admins

Summary by CodeRabbit

Release Notes

  • Code Enhancements

    • Replaced magic numbers with type-safe enumerations for algorithm and process selection, improving code reliability and maintainability.
    • Added utility functions to standardize naming and configuration handling across routing operations.
  • Documentation

    • Updated release notes to document code quality improvements and enhancements.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 1, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review

Walkthrough

This pull request replaces hard-coded integer constants with the Which enumeration across multiple pgRouting drivers and processes. It updates function signatures to use enum Which instead of int for algorithm selection parameters, introduces utility functions for enum name retrieval and parameter handling, and updates release notes documentation.

Changes

Cohort / File(s) Summary
Release Notes & Translations
NEWS.md, doc/src/release_notes.rst, locale/pot/pgrouting_doc_strings.pot, locale/en/LC_MESSAGES/pgrouting_doc_strings.po
Added Code enhancements section referencing issue #3049 and updated POT creation date; translation entries for new documentation content added.
Enum Definition
include/c_common/enums.h
Expanded enum Which with new members: DIJKSTRA, WITHPOINTS, OLD_WITHPOINTS, FLOYD, JOHNSON, BANDWIDTH; added semantic grouping comments.
Public Utility Headers
include/cpp_common/utilities.hpp
New header declaring four utility functions: get_name (overloaded), estimate_drivingSide, and get_new_queries for enum-based name resolution and query construction.
Driver Headers
include/drivers/allpairs_driver.hpp, include/drivers/metrics_driver.hpp, include/drivers/shortestPath_driver.hpp
Updated function signatures to replace int/int32_t parameters with enum Which; added include for c_common/enums.h.
Process Headers
include/process/allpairs_process.h, include/process/metrics_process.h, include/process/shortestPath_process.h
Updated pgr_process_* function signatures to use enum Which instead of int/int32_t; added enums.h includes.
Utility Implementation
src/cpp_common/utilities.cpp
New implementation file with four utility functions: enum name mapping via get_name, parameter validation via estimate_drivingSide, and SQL query construction via get_new_queries.
CMake Configuration
src/cpp_common/CMakeLists.txt
Added utilities.cpp to cpp_common OBJECT library compilation.
Dijkstra Driver & Process
src/dijkstra/dijkstra.c, src/dijkstra/shortestPath_driver.cpp, src/dijkstra/shortestPath_process.cpp
Replaced hard-coded constants with DIJKSTRA enum value; refactored shortestPath_driver to use public utilities; updated function signatures and removed duplicate local utility implementations; modified driving_side from pointer to char parameter.
Allpairs Driver & Process
src/allpairs/johnson.c, src/allpairs/floydWarshall.c, src/allpairs/allpairs_driver.cpp, src/allpairs/allpairs_process.cpp
Replaced integer constants with JOHNSON and FLOYD enum values; updated do_allpairs signature from int to Which; refactored allpairs_process to use pgrouting::get_name for dynamic logging.
Metrics Driver & Process
src/metrics/bandwidth.c, src/metrics/metrics_driver.cpp, src/metrics/metrics_process.cpp
Replaced hard-coded 0 with BANDWIDTH enum; updated do_metrics signature from int to Which; refactored metrics_process to use dynamic enum-based naming via get_name.
Ordering Driver & Process
src/ordering/ordering_driver.cpp, src/ordering/ordering_process.cpp
Updated graph initialization logic to compare enum TOPOSORT instead of numeric threshold; refactored ordering_process to use pgrouting::get_name for consistent logging.
WithPoints
src/withPoints/withPoints.c
Replaced hard-coded integer mode selectors (1) with WITHPOINTS and OLD_WITHPOINTS enum constants; changed driving_side string extraction to character extraction.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • Standardize ordering functions code #3026 — Introduces and applies enum Which similarly across ordering-related drivers and processes; overlaps in include/c_common/enums.h modifications and ordering implementation changes.
  • enhancements on dijkstra #2730 — Modifies Dijkstra and withPoints code paths; this PR's refactor builds upon and refines the same algorithm selection mechanisms and function signatures.
  • Pass by reference on drivers #3033 — Concurrently modifies the same public driver/process function signatures (allpairs, metrics, shortestPath, ordering); coordinate parameter type changes across the codebase.

Suggested labels

Dijkstra, Refactor, Enhancement

Suggested reviewers

  • iosefa
  • krashish8
  • robe2

Poem

🐰 Enums now guide the drivers true,
No magic numbers left to rue!
From ints to Which, the paths align,
Each algorithm marked by design,
A clearer way, the rabbits cheer! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Using enumeration on existing drivers' is directly related to the main objective of the PR, which is to replace current selection mechanisms with enumerations across drivers.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from issue #3049: adds enumeration support to select algorithms, provides mapping functions to get algorithm names, and applies changes to dijkstra, allpairs, metrics, and ordering directories.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the linked issue objectives. Documentation updates (NEWS.md, release_notes.rst, locale files) and utility implementations are in-scope supporting changes for the enumeration adoption.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cvvergara cvvergara marked this pull request as draft February 1, 2026 00:21
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/ordering/ordering_driver.cpp (1)

103-108: ⚠️ Potential issue | 🟠 Major

Replace magic numbers with enum constants and ensure all ordering modes extract vertices.

The condition which == 0 || which == 2 maps to SLOAN and KING only, excluding CUTCHILL (enum value 1) from vertex extraction. Since all three modes use the undirected graph, CUTCHILL incorrectly receives an empty vertex set, breaking the Cuthill-McKee algorithm. Use enum constants for clarity and extract vertices for all ordering modes:

const auto vertices = pgrouting::extract_vertices(edges);
🤖 Fix all issues with AI agents
In `@NEWS.md`:
- Line 15: Replace the bold label "**Code enhancements**" in NEWS.md with a
proper Markdown heading (e.g., an H2) so the generator emits a heading instead
of a bold inline label to satisfy MD036; update the generator/template that
produces the "**Code enhancements**" token (or the NEWS.md source) so the output
uses a heading element for "Code enhancements" rather than bold text.
- Around line 15-17: The NEWS.md entry was edited directly but that file is
generated; revert the manual edit in NEWS.md and instead add the release note to
the generator inputs (or the generator script) so it is preserved on
regeneration: update the notes2news.pl input source or the notes2news.pl logic
to include the “Use enumeration on drivers and process” item (reference
notes2news.pl and the NEWS.md entry text) and then re-run the release-notes
generation to produce an updated NEWS.md.

In `@src/cpp_common/utilities.cpp`:
- Around line 25-29: The code uses std::make_pair in utilities.cpp (around the
code that references make_pair, e.g., functions or lines using make_pair) but
lacks the <utility> header; add `#include` <utility> to the includes at the top of
src/cpp_common/utilities.cpp so the compiler can resolve std::make_pair (ensure
it’s placed alongside other standard headers such as <string>).
- Around line 33-62: In get_name(Which which) remove unreachable code by
deleting all break; statements that follow return in each case of the switch and
also remove the redundant return "unknown"; after the switch; ensure the
function returns the appropriate string from each case and the default case
remains returning "unknown" so there is a single return path per switch branch.
- Around line 87-108: In estimate_drivingSide, avoid undefined behavior by
calling tolower with an unsigned char cast: replace tolower(driving_side) with
tolower(static_cast<unsigned char>(driving_side)); also remove the unreachable
"break;" after the "return ' ';" in the DIJKSTRA case; ensure the function still
handles WHICH cases DIJKSTRA, WITHPOINTS and default as before (no other logic
changes).

In `@src/metrics/metrics_driver.cpp`:
- Around line 76-83: The switch in metrics_driver.cpp handling the Which enum
currently returns 0 silently in the default branch; update the default case in
the function containing the switch (the branch handling BANDWIDTH ->
pgrouting::metrics::bandwidth(undigraph)) to emit a defensive warning or error
log that includes the unexpected Which value (or call site) before returning, or
alternatively add an assertion/exception if unhandled values are programming
errors, so unexpected enum values are visible in logs.

[#4.1.0](https://github.com/pgRouting/pgrouting/issues?utf8=%E2%9C%93&q=milestone%3A%22Release%204.1.0%22)

No changes yet
**Code enhancements**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Replace the bold label with a heading to satisfy MD036.

This should be emitted by the generator/source, not edited here.

🛠️ Suggested output change
-**Code enhancements**
+#### Code enhancements
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Code enhancements**
#### Code enhancements
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 15-15: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🤖 Prompt for AI Agents
In `@NEWS.md` at line 15, Replace the bold label "**Code enhancements**" in
NEWS.md with a proper Markdown heading (e.g., an H2) so the generator emits a
heading instead of a bold inline label to satisfy MD036; update the
generator/template that produces the "**Code enhancements**" token (or the
NEWS.md source) so the output uses a heading element for "Code enhancements"
rather than bold text.

Comment on lines 25 to 30
#include "cpp_common/utilities.hpp"

#include <string>

#include "c_common/enums.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Add missing #include <utility> for std::make_pair.

The pipeline is failing because std::make_pair is used at line 97 but <utility> is not included.

🔧 Proposed fix
 `#include` "cpp_common/utilities.hpp"
 
 `#include` <string>
+#include <utility>
 
 `#include` "c_common/enums.h"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include "cpp_common/utilities.hpp"
#include <string>
#include "c_common/enums.h"
`#include` "cpp_common/utilities.hpp"
`#include` <string>
`#include` <utility>
`#include` "c_common/enums.h"
🧰 Tools
🪛 Cppcheck (2.19.0)

[information] 29-29: Include file

(missingIncludeSystem)


[information] 27-27: Include file

(missingIncludeSystem)

🤖 Prompt for AI Agents
In `@src/cpp_common/utilities.cpp` around lines 25 - 29, The code uses
std::make_pair in utilities.cpp (around the code that references make_pair,
e.g., functions or lines using make_pair) but lacks the <utility> header; add
`#include` <utility> to the includes at the top of src/cpp_common/utilities.cpp so
the compiler can resolve std::make_pair (ensure it’s placed alongside other
standard headers such as <string>).

Comment on lines +33 to +63
std::string
get_name(Which which) {
switch (which) {
case SLOAN:
return "pgr_sloanOrdering";
break;
case CUTCHILL:
return "pgr_cuthillMckeeOrdering";
break;
case KING:
return "pgr_kingOrdering";
break;
case TOPOSORT:
return "pgr_topologicalSort";
break;
case FLOYD:
return "pgr_floydWarshall";
break;
case JOHNSON:
return "pgr_johnson";
break;
case BANDWIDTH:
return "pgr_bandwidth";
break;
default:
return "unknown";
break;
}
return "unknown";
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Remove unreachable code after return statements.

The break statements after each return and the final return "unknown" on line 61 are unreachable.

♻️ Proposed cleanup
 std::string
 get_name(Which which) {
     switch (which) {
         case SLOAN:
             return "pgr_sloanOrdering";
-            break;
         case CUTCHILL:
             return "pgr_cuthillMckeeOrdering";
-            break;
         case KING:
             return "pgr_kingOrdering";
-            break;
         case TOPOSORT:
             return "pgr_topologicalSort";
-            break;
         case FLOYD:
             return "pgr_floydWarshall";
-            break;
         case JOHNSON:
             return "pgr_johnson";
-            break;
         case BANDWIDTH:
             return "pgr_bandwidth";
-            break;
         default:
             return "unknown";
-            break;
     }
-    return "unknown";
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
std::string
get_name(Which which) {
switch (which) {
case SLOAN:
return "pgr_sloanOrdering";
break;
case CUTCHILL:
return "pgr_cuthillMckeeOrdering";
break;
case KING:
return "pgr_kingOrdering";
break;
case TOPOSORT:
return "pgr_topologicalSort";
break;
case FLOYD:
return "pgr_floydWarshall";
break;
case JOHNSON:
return "pgr_johnson";
break;
case BANDWIDTH:
return "pgr_bandwidth";
break;
default:
return "unknown";
break;
}
return "unknown";
}
std::string
get_name(Which which) {
switch (which) {
case SLOAN:
return "pgr_sloanOrdering";
case CUTCHILL:
return "pgr_cuthillMckeeOrdering";
case KING:
return "pgr_kingOrdering";
case TOPOSORT:
return "pgr_topologicalSort";
case FLOYD:
return "pgr_floydWarshall";
case JOHNSON:
return "pgr_johnson";
case BANDWIDTH:
return "pgr_bandwidth";
default:
return "unknown";
}
}
🧰 Tools
🪛 Cppcheck (2.19.0)

[style] 34-34: The function 'get_name' is never used.

(unusedFunction)

🤖 Prompt for AI Agents
In `@src/cpp_common/utilities.cpp` around lines 33 - 62, In get_name(Which which)
remove unreachable code by deleting all break; statements that follow return in
each case of the switch and also remove the redundant return "unknown"; after
the switch; ensure the function returns the appropriate string from each case
and the default case remains returning "unknown" so there is a single return
path per switch branch.

Comment on lines 87 to 116
char
estimate_drivingSide(char driving_side, Which which) {
char d_side = static_cast<char>(tolower(driving_side));
if (!((d_side == 'r') || (d_side == 'l') || (d_side == 'b'))) {
d_side = ' ';
}
switch (which) {
case DIJKSTRA: { return ' '; break; }
case WITHPOINTS: {
if (d_side == ' ') {
throw std::make_pair(std::string("Invalid value of 'driving side'"),
std::string("Valid value are 'r', 'l', 'b'"));
}
break;
}
default: {
/* For the moment its old signature of pgr_withPoints */
if (!((d_side == 'r') || (d_side == 'l'))) d_side = 'b';
}
}
return d_side;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider casting to unsigned char for tolower and remove unreachable break.

Line 89: Passing a char directly to tolower can cause undefined behavior if char is signed and contains a negative value. Line 94 has an unreachable break after return.

♻️ Proposed fix
 char
 estimate_drivingSide(char driving_side, Which which) {
-    char d_side = static_cast<char>(tolower(driving_side));
+    char d_side = static_cast<char>(tolower(static_cast<unsigned char>(driving_side)));
     if (!((d_side == 'r') || (d_side == 'l') || (d_side == 'b'))) {
         d_side = ' ';
     }
     switch (which) {
-        case DIJKSTRA: { return ' '; break; }
+        case DIJKSTRA: { return ' '; }
         case WITHPOINTS: {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
char
estimate_drivingSide(char driving_side, Which which) {
char d_side = static_cast<char>(tolower(driving_side));
if (!((d_side == 'r') || (d_side == 'l') || (d_side == 'b'))) {
d_side = ' ';
}
switch (which) {
case DIJKSTRA: { return ' '; break; }
case WITHPOINTS: {
if (d_side == ' ') {
throw std::make_pair(std::string("Invalid value of 'driving side'"),
std::string("Valid value are 'r', 'l', 'b'"));
}
break;
}
default: {
/* For the moment its old signature of pgr_withPoints */
if (!((d_side == 'r') || (d_side == 'l'))) d_side = 'b';
}
}
return d_side;
}
char
estimate_drivingSide(char driving_side, Which which) {
char d_side = static_cast<char>(tolower(static_cast<unsigned char>(driving_side)));
if (!((d_side == 'r') || (d_side == 'l') || (d_side == 'b'))) {
d_side = ' ';
}
switch (which) {
case DIJKSTRA: { return ' '; }
case WITHPOINTS: {
if (d_side == ' ') {
throw std::make_pair(std::string("Invalid value of 'driving side'"),
std::string("Valid value are 'r', 'l', 'b'"));
}
break;
}
default: {
/* For the moment its old signature of pgr_withPoints */
if (!((d_side == 'r') || (d_side == 'l'))) d_side = 'b';
}
}
return d_side;
}
🧰 Tools
🪛 Cppcheck (2.19.0)

[style] 88-88: The function 'estimate_drivingSide' is never used.

(unusedFunction)

🪛 GitHub Actions: Check files

[error] 97-97: cpplint: Add #include for make_pair. [build/include_what_you_use]

🤖 Prompt for AI Agents
In `@src/cpp_common/utilities.cpp` around lines 87 - 108, In estimate_drivingSide,
avoid undefined behavior by calling tolower with an unsigned char cast: replace
tolower(driving_side) with tolower(static_cast<unsigned char>(driving_side));
also remove the unreachable "break;" after the "return ' ';" in the DIJKSTRA
case; ensure the function still handles WHICH cases DIJKSTRA, WITHPOINTS and
default as before (no other logic changes).

Comment on lines 76 to 84
switch (which) {
case BANDWIDTH: {
result = pgrouting::metrics::bandwidth(undigraph);
break;
}
default:
break;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding a defensive log for unexpected enum values.

The switch-case structure is extensible for future metrics. However, the default case silently returns 0, which could mask programming errors if an invalid or unhandled Which value is passed. Consider logging a warning or adding a comment to clarify this is intentional.

♻️ Optional: Add defensive logging for unexpected values
         switch (which) {
             case BANDWIDTH: {
                                 result = pgrouting::metrics::bandwidth(undigraph);
                                 break;
                             }
             default:
+                            log << "Unexpected metrics type";
                             break;
         }
🧰 Tools
🪛 Cppcheck (2.19.0)

[performance] 81-81: Function parameter 'data_edges' should be passed by const reference.

(passedByValue)

🤖 Prompt for AI Agents
In `@src/metrics/metrics_driver.cpp` around lines 76 - 83, The switch in
metrics_driver.cpp handling the Which enum currently returns 0 silently in the
default branch; update the default case in the function containing the switch
(the branch handling BANDWIDTH -> pgrouting::metrics::bandwidth(undigraph)) to
emit a defensive warning or error log that includes the unexpected Which value
(or call site) before returning, or alternatively add an assertion/exception if
unhandled values are programming errors, so unexpected enum values are visible
in logs.

@cvvergara cvvergara force-pushed the using-enumeration-on-existing-drivers branch from de46bcd to e31721a Compare February 1, 2026 00:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use enumeration on drivers and process

2 participants