Skip to content

Commit 3533aa2

Browse files
authored
Merge pull request #501 from roycpro/fix-cross-year-data
fix: throw ChangeInYearsException for streams spanning multiple years
2 parents b2c7913 + 710b067 commit 3533aa2

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

src/main/org/epics/archiverappliance/retrieval/postprocessors/ArrayListCollectorEventStream.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.epics.archiverappliance.common.remotable.ArrayListEventStream;
99
import org.epics.archiverappliance.common.remotable.RemotableEventStreamDesc;
1010
import org.epics.archiverappliance.common.remotable.RemotableOverRaw;
11+
import org.epics.archiverappliance.retrieval.ChangeInYearsException;
1112

1213
import java.io.IOException;
1314
import java.util.Iterator;
@@ -64,10 +65,18 @@ public boolean hasNext() {
6465
public Event next() {
6566
Event next = sourceStream.get(currentIndex);
6667
short eventYear = TimeUtils.computeYearForEpochSeconds(next.getEpochSeconds());
68+
69+
if (currentYear == -1) {
70+
currentYear = eventYear;
71+
desc.setYear(eventYear);
72+
}
73+
6774
if (eventYear != currentYear) {
6875
logger.info("Detected a change in years eventYear " + eventYear + " and currentYear is " + currentYear);
6976
ArrayListCollectorEventStream.this.desc.setYear(eventYear);
77+
short tempCurrentYear = currentYear;
7078
currentYear = eventYear;
79+
throw new ChangeInYearsException(tempCurrentYear, eventYear);
7180
}
7281
currentIndex++;
7382
return next;

src/test/org/epics/archiverappliance/retrieval/postprocessor/OptimizedPostProcessorTest.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.epics.archiverappliance.data.ScalarValue;
1313
import org.epics.archiverappliance.data.VectorValue;
1414
import org.epics.archiverappliance.retrieval.CallableEventStream;
15+
import org.epics.archiverappliance.retrieval.ChangeInYearsException;
1516
import org.epics.archiverappliance.retrieval.postprocessors.Optimized;
1617
import org.epics.archiverappliance.utils.simulation.SimulationEvent;
1718
import org.junit.jupiter.api.Assertions;
@@ -322,4 +323,68 @@ static Stream<Arguments> testInclusionOfLastValueBeforeFirstBinIntoFirstBin_gene
322323
Arguments.of(50000, 51000, Arrays.asList(50.0)),
323324
Arguments.of(51000, 52000, Arrays.asList(50.0)));
324325
}
326+
327+
@Test
328+
public void testOptimizedCrossYearDetection() {
329+
String optimizedTestPVName = "Test_OptimizedCrossYearDetection";
330+
331+
YearSecondTimestamp start2024 =
332+
TimeUtils.convertToYearSecondTimestamp(TimeUtils.convertFromISO8601String("2024-12-31T23:59:50.000Z"));
333+
YearSecondTimestamp start2025 =
334+
TimeUtils.convertToYearSecondTimestamp(TimeUtils.convertFromISO8601String("2025-01-01T00:00:00.000Z"));
335+
336+
double valueIn2024 = 1.0;
337+
double valueIn2025 = 2.0;
338+
339+
ArrayListEventStream testData = new ArrayListEventStream(
340+
2,
341+
new RemotableEventStreamDesc(ArchDBRTypes.DBR_SCALAR_DOUBLE, optimizedTestPVName, start2024.getYear()));
342+
343+
// Add 1 first-year event
344+
testData.add(new SimulationEvent(
345+
start2024.getSecondsintoyear(),
346+
start2024.getYear(),
347+
ArchDBRTypes.DBR_SCALAR_DOUBLE,
348+
new ScalarValue<>(valueIn2024)));
349+
350+
// Add 1 second-year event
351+
testData.add(new SimulationEvent(
352+
start2025.getSecondsintoyear(),
353+
start2025.getYear(),
354+
ArchDBRTypes.DBR_SCALAR_DOUBLE,
355+
new ScalarValue<>(valueIn2025)));
356+
357+
Optimized optimizedPostProcessor = new Optimized();
358+
try {
359+
optimizedPostProcessor.initialize("optimized_5760", optimizedTestPVName);
360+
} catch (IOException e) {
361+
throw new RuntimeException(e);
362+
}
363+
364+
var callableEventStream = CallableEventStream.makeOneStreamCallable(testData, null, false);
365+
366+
var callable = optimizedPostProcessor.wrap(callableEventStream);
367+
368+
try {
369+
callable.call();
370+
} catch (Exception e) {
371+
Assertions.fail(
372+
"An exception occurred when calling optimizedPostProcessor.wrap(callableEventStream).call()");
373+
}
374+
375+
EventStream eventStream = optimizedPostProcessor.getConsolidatedEventStream();
376+
377+
// First event is in 2024 - do not trigger the ChangeInYearsException
378+
Event first = eventStream.iterator().next();
379+
Assertions.assertEquals(valueIn2024, first.getSampleValue().getValue());
380+
381+
// Second event is in 2025 - trigger the ChangeInYearsException
382+
ChangeInYearsException ex = Assertions.assertThrows(
383+
ChangeInYearsException.class,
384+
eventStream.iterator()::next,
385+
"Expected ChangeInYearsException when year changes");
386+
387+
Assertions.assertEquals(start2024.getYear(), ex.getPreviousYear());
388+
Assertions.assertEquals(start2025.getYear(), ex.getCurrentYear());
389+
}
325390
}

0 commit comments

Comments
 (0)