-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add generalizedCostMaxLimit
field to the PageCursor
to enable using RemoveTransitIfStreetOnlyIsBetter
filter with paging
#6474
base: dev-2.x
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev-2.x #6474 +/- ##
=============================================
+ Coverage 70.25% 71.06% +0.81%
+ Complexity 18385 18321 -64
=============================================
Files 2088 2008 -80
Lines 77417 75962 -1455
Branches 7840 7786 -54
=============================================
- Hits 54386 53983 -403
+ Misses 20262 19232 -1030
+ Partials 2769 2747 -22 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
I removed the direct mode search with paging and refactored |
bestStreetOnlyCost
field to the PageCursor
to enable using RemoveTransitIfStreetOnlyIsBetter
filter with pagingstreetOnlyCost
field to the PageCursor
to enable using RemoveTransitIfStreetOnlyIsBetter
filter with paging
...ation/src/main/java/org/opentripplanner/model/plan/paging/cursor/DefaultPageCursorInput.java
Outdated
Show resolved
Hide resolved
...ation/src/main/java/org/opentripplanner/model/plan/paging/cursor/DefaultPageCursorInput.java
Outdated
Show resolved
Hide resolved
...ation/src/main/java/org/opentripplanner/model/plan/paging/cursor/DefaultPageCursorInput.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursor.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactory.java
Outdated
Show resolved
Hide resolved
...planner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java
Outdated
Show resolved
Hide resolved
...planner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetter.java
Outdated
Show resolved
Hide resolved
...main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java
Outdated
Show resolved
Hide resolved
...ner/routing/algorithm/filterchain/filters/transit/RemoveTransitIfStreetOnlyIsBetterTest.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/opentripplanner/routing/algorithm/RoutingWorker.java
Outdated
Show resolved
Hide resolved
…ror with case that should not happen.
streetOnlyCost
field to the PageCursor
to enable using RemoveTransitIfStreetOnlyIsBetter
filter with paginggeneralizedCostMaxLimit
field to the PageCursor
to enable using RemoveTransitIfStreetOnlyIsBetter
filter with paging
…into paging-filtering-fix
This PR depends on how the new logic in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a fast architecture review - I did not read all code-lines. If you want we can go through it in a meeting.
import org.opentripplanner.routing.algorithm.filterchain.filters.system.NumItinerariesFilterResult; | ||
import org.opentripplanner.routing.algorithm.filterchain.filters.transit.RemoveTransitIfStreetOnlyIsBetterResult; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PageCursorInput define a role implemented by the itinerary filter chain - we did this to invert the dependencies and to decouple the paging from the itinerary filter chain. There is no point in having the implementation of an interface in the same package (unless its just the default of many) - it indicates that there is a design mistake.
There should NOT be any dependencies from paging to the itinerary-filter-chain.
So, this should be moved inside the filter-chain, witch should be responsible for produsing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the DefaultPageCursorInput
into the org.opentripplanner.routing.algorithm.filterchain
package
DefaultPageCursorInput.of() | ||
.withNumItinerariesFilterResult(numItinerariesFilterResult) | ||
.withRemoveTransitIfStreetOnlyIsBetterResult(removeTransitIfStreetOnlyIsBetterResult) | ||
.build(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the itinerary-filter-chain should be responsible for producing the PageCursorInput - this adds an extra layer of abstraction, but the coupling at field/information level is so high, that I do not se the point of doing it. The responsibility of the RoutingWorker is to wire things together, not mapping from one domain to another. The mapping logic should then be extracted, but it is simpler to just push it into he filter-chain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, we need the result of filters to produce the event to send back to the paging. There are many ways to do it:
Alt 1. We can store the result in the filters and add the filters to a result aggregator. When the filter-chain is compleate, we notify the aggregator and it produces the paging event.
Alt 2. The filters can send a event to the result aggregator and the aggregator can send an event to the paging when it has rescieved an event from both of the filters. This is complex, and if one of the filters is disabled it might fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created a PageCursorInputAggregator and use a callback to set the PageCursorInput
…rithm.filterchain.
.../java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java
Outdated
Show resolved
Hide resolved
this.pageCursorInputSubscriber = builder.pageCursorInputSubscriber(); | ||
} | ||
|
||
public void createPageCursorInput() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if create is the right word here since this is not a factory method. Maybe providePageCursorInput
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this to providePageCursorInput
...main/java/org/opentripplanner/routing/algorithm/mapping/RouteRequestToFilterChainMapper.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test class should be restored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I restored it and added new tests for when the pagecursor exists
} | ||
|
||
public FilterTransitWhenDirectModeIsEmpty(StreetMode originalDirectMode) { | ||
public FilterTransitWhenDirectModeIsEmpty( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should update this class' javadoc and add some to the public methods as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the class' javadoc and added documentation to two methods
...cation/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactoryTest.java
Show resolved
Hide resolved
...est/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainTest.java
Outdated
Show resolved
Hide resolved
I resolved the comments that I think have been fixed/are not relevant anymore. I think the ones that are open either are still relevant, need changes and/or should be taken a look at by @t2gran if everything is ok now. |
...entripplanner/routing/algorithm/raptoradapter/router/FilterTransitWhenDirectModeIsEmpty.java
Outdated
Show resolved
Hide resolved
...cation/src/test/java/org/opentripplanner/model/plan/paging/cursor/PageCursorFactoryTest.java
Outdated
Show resolved
Hide resolved
* The earliest-removed-departure defines the start of the search-window following the | ||
* current window. To include this removed itinerary (and all other removed itineraries) | ||
* in the next-page search the search windows must overlap. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct when searching to the other direction? The purpose of latestRemovedDeparture
should probably be also explained.
* current window. To include this removed itinerary (and all other removed itineraries) | ||
* in the next-page search the search windows must overlap. | ||
* <p> | ||
* In case the result has too many results: The {@code numberOfItineraries} request parameter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* In case the result has too many results: The {@code numberOfItineraries} request parameter | |
* In case the result has too many results, if the {@code numberOfItineraries} request parameter |
* is less than the number of itineraries found, then we keep the last itinerary kept and | ||
* returned as part of the result. The sort vector will be included in the page-cursor and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "then we keep the last itinerary kept and returned as part of the result" part is difficult to understand.
* @param costLimitFunction the cost limit function to use with the filter | ||
* @param generalizedCostMaxLimit this limit is not null when paging is used |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the param can be null in some case, it should be marked as @Nullable
and field can be marked as such also.
* based on a direct mode used in the search. We achieve the filtering by setting the directMode | ||
* before searching. This triggers the direct street search, and later the result is passed into | ||
* the filter chain where none optimal results are removed. Finally the street itinerary is removed | ||
* and the request street mode is assigned back to the original state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* based on a direct mode used in the search. We achieve the filtering by setting the directMode | |
* before searching. This triggers the direct street search, and later the result is passed into | |
* the filter chain where none optimal results are removed. Finally the street itinerary is removed | |
* and the request street mode is assigned back to the original state. | |
* based on a direct search cost from the original search. We achieve the filtering by setting the | |
* directMode before searching. This triggers the direct street search, and later the result is | |
* passed into the filter chain where none optimal results are removed. Finally the street itinerary | |
* is removed and the request street mode is assigned back to the original state. |
/** | ||
* If the direct mode was not set and if the page cursor does not exist, | ||
* the WALK mode is returned for filtering itineraries. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class feels really weird in many ways. The name makes it sound like this is a filter but this actually isn't one. This class has too many responsibilities in my opinion and this pr makes it even harder to follow the logic. It feels a bit hacky how we need to set the direct mode back-and-forth in many places. However, we have plans in the future to perhaps refactor the "direct filter" logic a bit so maybe this isn't the right time to do refactoring here.
* The earliest-removed-departure defines the start of the search-window following the | ||
* current window. To include this removed itinerary (and all other removed itineraries) | ||
* in the next-page search the search windows must overlap. | ||
* This contains the results from {@link org.opentripplanner.routing.algorithm.filterchain.filters.system.NumItinerariesFilter}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still haven't decided what to do about this?
Summary
This PR adds the
generalizedCostMaxLimit
field to thePageCursor
. This enables using theRemoveTransitIfStreetOnlyIsBetter
filter with paging. Before this PR, this was not possible because paging only used the walk mode to create a direct itinerary which made the filter work incorrectly.Issue
N/A
Unit tests
Changed existing unit tests for compatibility and created new ones. Also performed manual testing.
Documentation
Code comments, no other documentation