Skip to content

feat(cost): add route cost models - #5

Merged
404khai merged 1 commit into
mainfrom
feat/phase-4-cost-model
Sep 1, 2026
Merged

feat(cost): add route cost models#5
404khai merged 1 commit into
mainfrom
feat/phase-4-cost-model

Conversation

@404khai

@404khai 404khai commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Summary

Implements Phase 4 of the Roadrunner roadmap by separating graph topology from the routing objective used to evaluate an edge.

  • extends each directed Edge with validated Meters and Seconds attributes
  • adds immutable RoutingContext
  • adds unit-aware, validated RouteCost and CostKind
  • adds the CostModel: Send + Sync boundary
  • implements DistanceCost
  • implements TravelTimeCost
  • updates graph tests and traversal benchmarks for the expanded edge contract

Cost model contract

CostModel::edge_cost accepts an edge and routing context and returns a validated RouteCost. It returns Result so future dynamic or external cost models cannot silently introduce negative, NaN, or infinite values into routing algorithms.

DistanceCost selects Edge::distance() in meters. TravelTimeCost selects Edge::base_travel_time() in seconds. Neither model changes graph topology or mutates its context.

Unit safety

Each RouteCost carries a CostKind discriminator:

  • distance
  • travel_time

Costs reject negative and non-finite values at construction and deserialization. Costs with different kinds cannot be added or ordered against each other. Same-kind addition revalidates the result so floating-point overflow is reported instead of propagated.

Phase boundary

This PR introduces cost calculation but no path search, predecessor tracking, or route reconstruction. Dijkstra remains Phase 5. RoutingContext is intentionally empty for static Phase 4 models and provides the extension seam for later departure-time and traffic state.

Tests

New tests verify:

  • distance cost selects only edge distance
  • travel-time cost selects only base travel time
  • invalid costs are rejected
  • validated deserialization cannot bypass cost invariants
  • same-kind costs can be accumulated
  • mixed-unit arithmetic and comparison are rejected

Validation

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
  • cargo test --workspace --all-features --locked — 33 tests pass
  • cargo bench -p roadrunner-core --bench graph_traversal --no-run --locked
  • RUSTDOCFLAGS=-Dwarnings cargo doc --workspace --no-deps --locked
  • git diff --check main...HEAD

@404khai
404khai merged commit 4924259 into main Sep 1, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant