Conversation
The fall-back day has 100 ISPs, but a forecast producer that writes a fixed 96-slot day leaves the four ISPs of the repeated hour without a predicted datapoint of their own. Those positions were submitted as 0.0, which posts a real zero trading position for an hour that genuinely exists. They now reuse the next forecast value of the day instead. The scope is deliberately narrow: an ISP qualifies only when its market local time occurs more than once in the day's ISP grid, which is true of the repeated hour and nothing else. Every other gap still goes out as 0.0, since it means the producer skipped intervals it covered or its horizon ended, and both are already logged. A repeated-hour ISP with nothing left in the day to borrow from also falls back to 0.0, because the API requires a volume on every entry. The interior/trailing gap counters move into the fill pass. The old formula derived interior gaps by subtracting the trailing ones from the total, which would now count every position filled from a neighbour as a gap that went out as 0.0, over-reporting by exactly that many. A filled position is always interior, since filling requires a real value later in the day, so the subtraction could not go negative. It would just be wrong. The collapse test can no longer enumerate every position holding the seeded value: the positions between the two passes of the repeated hour now borrow that same value, so a read and a fill are indistinguishable by value alone. It asserts the two passes directly instead.
Three cases, all under a UTC storage frame so the two passes of the fall-back hour keep separate rows and a dropped ISP is a genuinely empty position rather than a collapsed one. Dropping either pass of the repeated hour leaves 96 of 100 ISPs covered, the shape a producer writing a fixed 96-slot day produces, and the emptied positions take the next real value. A forecast that ends before the repeated hour has nothing to borrow, so those positions stay 0.0. A gap in the afternoon of the same day stays 0.0 too, which pins the scope to the repeated hour rather than to the DST day as a whole.
The javadoc claimed the method "becomes exact without changing" once predicted datapoints move to UTC. That is not true of the repeated hour. While the storage frame collapses the hour, both passes read the one surviving row and carry its distinct values. Under UTC each instant gets its own row, a producer that writes the hour once leaves the other pass empty, and that pass is filled flat on the next forecast value. The submitted day changes on the fall-back date when openremote/openremote#3292 lands, so the javadoc now says so and says the flat hour is deliberate. Also drops the claim that the rule covers "those four ISPs": detection is generic over any repeated market local time, which is two ISPs against a half-hour transition such as Australia/Lord_Howe. Test gaps: - Nothing pinned that a filled 0.0 is never itself a fill source. A refactor updating the carried value on every position, not just real ones, passed the whole suite and flattened the repeated hour to 0.0. The new case leaves the hour and the two ISPs after it unwritten, so the scan has to cross two filled zeros to reach 03:30. - The parameterised case asserted the dropped positions and everything outside the hour, never the pass that kept its rows, so a fill overwriting real values inside the hour went unnoticed. - The Amsterdam collapse guard only asserted "not 0.0", which holds for almost any wrong value. It now pins what each pass reads. - Comparing against a repeated list rather than calling every() also pins the element count. Hoists a duplicated toLocalDateTime() call in the detection loop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The fall-back day has 100 ISPs, and a producer writing a fixed 96-slot day leaves the four ISPs of the repeated hour without a predicted datapoint. Those positions went out as
0.0, which posts a real zero trading position for an hour that exists.They now reuse the next forecast value of the day. Only an ISP whose market local time repeats in the day's grid qualifies, so every other day is byte-identical to before and every other gap still goes out as
0.0.Commit messages carry the scope reasoning, the storage-frame behaviour and the test detail.
Checklist