1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.utils;
18
19
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.concurrent.ExecutorService;
24 import java.util.concurrent.Executors;
25 import java.util.concurrent.TimeUnit;
26 import java.util.concurrent.atomic.AtomicReference;
27 import java.util.stream.Collectors;
28
29 import org.hamcrest.CoreMatchers;
30 import org.hamcrest.MatcherAssert;
31 import org.hipparchus.random.RandomGenerator;
32 import org.hipparchus.random.Well1024a;
33 import org.junit.Assert;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.orekit.Utils;
37 import org.orekit.errors.TimeStampedCacheException;
38 import org.orekit.time.AbsoluteDate;
39
40
41 public class GenericTimeStampedCacheTest {
42
43 @Test
44 public void testSingleCall() throws TimeStampedCacheException {
45 GenericTimeStampedCache<AbsoluteDate> cache = createCache(10, 3600.0, 13);
46 List<AbsoluteDate> list = new ArrayList<AbsoluteDate>();
47 list.add(AbsoluteDate.GALILEO_EPOCH);
48 Assert.assertEquals(1, checkDatesSingleThread(list, cache));
49 Assert.assertEquals(1, cache.getGetNeighborsCalls());
50 Assert.assertEquals(4, cache.getGenerateCalls());
51 Assert.assertEquals(0, cache.getSlotsEvictions());
52 Assert.assertEquals(10, cache.getMaxSlots());
53 Assert.assertEquals(Constants.JULIAN_DAY, cache.getNewSlotQuantumGap(), 1.0e-10);
54 Assert.assertEquals(Constants.JULIAN_YEAR, cache.getMaxSpan(), 1.0e-10);
55 }
56
57 @Test
58 public void testPastInfinityRange() throws TimeStampedCacheException {
59 GenericTimeStampedCache<AbsoluteDate> cache =
60 new GenericTimeStampedCache<AbsoluteDate>(2, 10, Constants.JULIAN_YEAR, Constants.JULIAN_DAY,
61 new Generator(AbsoluteDate.PAST_INFINITY,
62 AbsoluteDate.J2000_EPOCH,
63 10.0));
64 List<AbsoluteDate> list = new ArrayList<AbsoluteDate>();
65 list.add(AbsoluteDate.GALILEO_EPOCH);
66 list.add(AbsoluteDate.MODIFIED_JULIAN_EPOCH);
67 list.add(AbsoluteDate.JULIAN_EPOCH);
68 Assert.assertEquals(3, checkDatesSingleThread(list, cache));
69 Assert.assertEquals(3, cache.getGetNeighborsCalls());
70 try {
71 cache.getNeighbors(AbsoluteDate.J2000_EPOCH.shiftedBy(100.0));
72 Assert.fail("expected TimeStampedCacheException");
73 } catch (TimeStampedCacheException tce) {
74
75 } catch (Exception e) {
76 Assert.fail("wrong exception caught");
77 }
78 }
79
80 @Test
81 public void testFutureInfinityRange() throws TimeStampedCacheException {
82 GenericTimeStampedCache<AbsoluteDate> cache =
83 new GenericTimeStampedCache<AbsoluteDate>(2, 10, Constants.JULIAN_YEAR, Constants.JULIAN_DAY,
84 new Generator(AbsoluteDate.MODIFIED_JULIAN_EPOCH,
85 AbsoluteDate.FUTURE_INFINITY, 10.0));
86 List<AbsoluteDate> list = new ArrayList<AbsoluteDate>();
87 list.add(AbsoluteDate.J2000_EPOCH);
88 list.add(AbsoluteDate.GALILEO_EPOCH);
89 Assert.assertEquals(2, checkDatesSingleThread(list, cache));
90 Assert.assertEquals(2, cache.getGetNeighborsCalls());
91 try {
92 cache.getNeighbors(AbsoluteDate.JULIAN_EPOCH);
93 Assert.fail("expected TimeStampedCacheException");
94 } catch (TimeStampedCacheException tce) {
95
96 } catch (Exception e) {
97 Assert.fail("wrong exception caught");
98 }
99 }
100
101 @Test
102 public void testInfinityRange() throws TimeStampedCacheException {
103 GenericTimeStampedCache<AbsoluteDate> cache =
104 new GenericTimeStampedCache<AbsoluteDate>(2, 10, Constants.JULIAN_YEAR, Constants.JULIAN_DAY,
105 new Generator(AbsoluteDate.PAST_INFINITY,
106 AbsoluteDate.FUTURE_INFINITY,
107 10.0));
108 List<AbsoluteDate> list = new ArrayList<AbsoluteDate>();
109 list.add(AbsoluteDate.J2000_EPOCH.shiftedBy(+4.6e12));
110 list.add(AbsoluteDate.J2000_EPOCH.shiftedBy(-4.6e12));
111 list.add(AbsoluteDate.JULIAN_EPOCH);
112 list.add(AbsoluteDate.J2000_EPOCH);
113 list.add(AbsoluteDate.GALILEO_EPOCH);
114 Assert.assertEquals(5, checkDatesSingleThread(list, cache));
115 Assert.assertEquals(5, cache.getGetNeighborsCalls());
116 }
117
118 @Test
119 public void testRegularCalls() throws TimeStampedCacheException {
120 GenericTimeStampedCache<AbsoluteDate> cache = createCache(2, 3600, 13);
121 Assert.assertEquals(2000, testMultipleSingleThread(cache, new SequentialMode(), 2));
122 Assert.assertEquals(2000, cache.getGetNeighborsCalls());
123 Assert.assertEquals(56, cache.getGenerateCalls());
124 Assert.assertEquals(0, cache.getSlotsEvictions());
125 }
126
127 @Test
128 public void testAlternateCallsGoodConfiguration() throws TimeStampedCacheException {
129 GenericTimeStampedCache<AbsoluteDate> cache = createCache(2, 3600, 13);
130 Assert.assertEquals(2000, testMultipleSingleThread(cache, new AlternateMode(), 2));
131 Assert.assertEquals(2000, cache.getGetNeighborsCalls());
132 Assert.assertEquals(56, cache.getGenerateCalls());
133 Assert.assertEquals(0, cache.getSlotsEvictions());
134 }
135
136 @Test
137 public void testAlternateCallsBadConfiguration() throws TimeStampedCacheException {
138 GenericTimeStampedCache<AbsoluteDate> cache = createCache(1, 3600, 13);
139 Assert.assertEquals(2000, testMultipleSingleThread(cache, new AlternateMode(), 2));
140 Assert.assertEquals(2000, cache.getGetNeighborsCalls());
141 Assert.assertEquals(8000, cache.getGenerateCalls());
142 Assert.assertEquals(1999, cache.getSlotsEvictions());
143 }
144
145 @Test
146 public void testRandomCallsGoodConfiguration() throws TimeStampedCacheException {
147 GenericTimeStampedCache<AbsoluteDate> cache = createCache(30, 3600, 13);
148 Assert.assertEquals(5000, testMultipleSingleThread(cache, new RandomMode(64394632125212l), 5));
149 Assert.assertEquals(5000, cache.getGetNeighborsCalls());
150 Assert.assertTrue(cache.getGenerateCalls() < 250);
151 Assert.assertEquals(0, cache.getSlotsEvictions());
152 }
153
154 @Test
155 public void testRandomCallsBadConfiguration() throws TimeStampedCacheException {
156 GenericTimeStampedCache<AbsoluteDate> cache = createCache(3, 3600, 13);
157 Assert.assertEquals(5000, testMultipleSingleThread(cache, new RandomMode(64394632125212l), 5));
158 Assert.assertEquals(5000, cache.getGetNeighborsCalls());
159 Assert.assertTrue(cache.getGenerateCalls() > 400);
160 Assert.assertTrue(cache.getSlotsEvictions() > 300);
161 }
162
163 @Test
164 public void testMultithreadedGoodConfiguration() throws TimeStampedCacheException {
165 GenericTimeStampedCache<AbsoluteDate> cache = createCache(50, 3600, 13);
166 int n = testMultipleMultiThread(cache, new AlternateMode(), 50, 30);
167 Assert.assertEquals(n, cache.getGetNeighborsCalls());
168 Assert.assertTrue("this test may fail randomly due to multi-threading non-determinism" +
169 " (n = " + n + ", calls = " + cache.getGenerateCalls() +
170 ", ratio = " + (n / cache.getGenerateCalls()) + ")",
171 cache.getGenerateCalls() < n / 20);
172 Assert.assertTrue("this test may fail randomly due to multi-threading non-determinism" +
173 " (n = " + n + ", evictions = " + cache.getSlotsEvictions() +
174 (cache.getSlotsEvictions() == 0 ? "" : (", ratio = " + (n / cache.getSlotsEvictions()))) + ")",
175 cache.getSlotsEvictions() < n / 1000);
176 }
177
178 @Test
179 public void testMultithreadedBadConfiguration() throws TimeStampedCacheException {
180 GenericTimeStampedCache<AbsoluteDate> cache = createCache(3, 3600, 13);
181 int n = testMultipleMultiThread(cache, new AlternateMode(), 50, 100);
182 Assert.assertEquals(n, cache.getGetNeighborsCalls());
183 Assert.assertTrue("this test may fail randomly due to multi-threading non-determinism" +
184 " (n = " + n + ", calls = " + cache.getGenerateCalls() +
185 ", ratio = " + (n / cache.getGenerateCalls()) + ")",
186 cache.getGenerateCalls() > n / 15);
187 Assert.assertTrue("this test may fail randomly due to multi-threading non-determinism" +
188 " (n = " + n + ", evictions = " + cache.getSlotsEvictions() +
189 ", ratio = " + (n / cache.getSlotsEvictions()) + ")",
190 cache.getSlotsEvictions() > n / 60);
191 }
192
193 @Test
194 public void testSmallShift() throws TimeStampedCacheException {
195 double hour = 3600;
196 GenericTimeStampedCache<AbsoluteDate> cache = createCache(10, hour, 13);
197 Assert.assertEquals(0, cache.getSlots());
198 Assert.assertEquals(0, cache.getEntries());
199 final AbsoluteDate start = AbsoluteDate.GALILEO_EPOCH;
200 cache.getNeighbors(start);
201 Assert.assertEquals(1, cache.getGetNeighborsCalls());
202 Assert.assertEquals(1, cache.getSlots());
203 Assert.assertEquals(18, cache.getEntries());
204 Assert.assertEquals(4, cache.getGenerateCalls());
205 Assert.assertEquals(-11 * hour, cache.getEarliest().durationFrom(start), 1.0e-10);
206 Assert.assertEquals( +6 * hour, cache.getLatest().durationFrom(start), 1.0e-10);
207 cache.getNeighbors(start.shiftedBy(-3 * 3600));
208 Assert.assertEquals(2, cache.getGetNeighborsCalls());
209 Assert.assertEquals(1, cache.getSlots());
210 Assert.assertEquals(18, cache.getEntries());
211 Assert.assertEquals(4, cache.getGenerateCalls());
212 Assert.assertEquals(-11 * hour, cache.getEarliest().durationFrom(start), 1.0e-10);
213 Assert.assertEquals( +6 * hour, cache.getLatest().durationFrom(start), 1.0e-10);
214 cache.getNeighbors(start.shiftedBy(7 * 3600));
215 Assert.assertEquals(3, cache.getGetNeighborsCalls());
216 Assert.assertEquals(1, cache.getSlots());
217 Assert.assertEquals(25, cache.getEntries());
218 Assert.assertEquals(5, cache.getGenerateCalls());
219 Assert.assertEquals(-11 * hour, cache.getEarliest().durationFrom(start), 1.0e-10);
220 Assert.assertEquals(+13 * hour, cache.getLatest().durationFrom(start), 1.0e-10);
221 }
222
223 @Test(expected=IllegalArgumentException.class)
224 public void testNotEnoughSlots() {
225 createCache(0, 3600.0, 13);
226 }
227
228 @Test(expected=IllegalArgumentException.class)
229 public void testNotEnoughNeighbors() {
230 createCache(10, 3600.0, 1);
231 }
232
233 @Test(expected=IllegalStateException.class)
234 public void testNoEarliestEntry() {
235 createCache(10, 3600.0, 3).getEarliest();
236 }
237
238 @Test(expected=IllegalStateException.class)
239 public void testNoLatestEntry() {
240 createCache(10, 3600.0, 3).getLatest();
241 }
242
243 @Test(expected=TimeStampedCacheException.class)
244 public void testNoGeneratedData() throws TimeStampedCacheException {
245 TimeStampedGenerator<AbsoluteDate> nullGenerator =
246 new TimeStampedGenerator<AbsoluteDate>() {
247 public List<AbsoluteDate> generate(AbsoluteDate existingDate,
248 AbsoluteDate date) {
249 return new ArrayList<AbsoluteDate>();
250 }
251 };
252 new GenericTimeStampedCache<AbsoluteDate>(2, 10, Constants.JULIAN_YEAR, Constants.JULIAN_DAY,
253 nullGenerator).getNeighbors(AbsoluteDate.J2000_EPOCH);
254 }
255
256 @Test
257 public void testNoDataBefore() throws TimeStampedCacheException {
258 TimeStampedGenerator<AbsoluteDate> nullGenerator =
259 new TimeStampedGenerator<AbsoluteDate>() {
260 public List<AbsoluteDate> generate(AbsoluteDate existingDate,
261 AbsoluteDate date) {
262 return Collections.singletonList(AbsoluteDate.J2000_EPOCH);
263 }
264 };
265 AbsoluteDate central = AbsoluteDate.J2000_EPOCH.shiftedBy(-10);
266 GenericTimeStampedCache<AbsoluteDate> cache = new GenericTimeStampedCache<>(
267 2, 10, Constants.JULIAN_YEAR, Constants.JULIAN_DAY, nullGenerator);
268 try {
269 cache.getNeighbors(central);
270 Assert.fail("Expected Exception");
271 } catch (TimeStampedCacheException e) {
272 MatcherAssert.assertThat(e.getMessage(),
273 CoreMatchers.containsString(central.toString()));
274 }
275 }
276
277 @Test
278 public void testNoDataAfter() throws TimeStampedCacheException {
279 TimeStampedGenerator<AbsoluteDate> nullGenerator =
280 new TimeStampedGenerator<AbsoluteDate>() {
281 public List<AbsoluteDate> generate(AbsoluteDate existingDate,
282 AbsoluteDate date) {
283 return Collections.singletonList(AbsoluteDate.J2000_EPOCH);
284 }
285 };
286 AbsoluteDate central = AbsoluteDate.J2000_EPOCH.shiftedBy(+10);
287 GenericTimeStampedCache<AbsoluteDate> cache = new GenericTimeStampedCache<>(
288 2, 10, Constants.JULIAN_YEAR, Constants.JULIAN_DAY, nullGenerator);
289 try {
290 cache.getNeighbors(central);
291 Assert.fail("Expected Exception");
292 } catch (TimeStampedCacheException e) {
293 MatcherAssert.assertThat(e.getMessage(),
294 CoreMatchers.containsString(central.toString()));
295 }
296 }
297
298 @Test(expected=TimeStampedCacheException.class)
299 public void testUnsortedEntries() throws TimeStampedCacheException {
300 TimeStampedGenerator<AbsoluteDate> reversedGenerator =
301 new TimeStampedGenerator<AbsoluteDate>() {
302
303 public List<AbsoluteDate> generate(AbsoluteDate existingDate, AbsoluteDate date) {
304 List<AbsoluteDate> list = new ArrayList<AbsoluteDate>();
305 list.add(date);
306 list.add(date.shiftedBy(-10.0));
307 return list;
308 }
309 };
310
311 new GenericTimeStampedCache<AbsoluteDate>(3, 10, Constants.JULIAN_YEAR, Constants.JULIAN_DAY,
312 reversedGenerator).getNeighbors(AbsoluteDate.J2000_EPOCH);
313
314 }
315
316 @Test
317 public void testDuplicatingGenerator() throws TimeStampedCacheException {
318
319 final double step = 3600.0;
320
321 TimeStampedGenerator<AbsoluteDate> duplicatingGenerator =
322 new TimeStampedGenerator<AbsoluteDate>() {
323
324
325 public List<AbsoluteDate> generate(AbsoluteDate existingDate, AbsoluteDate date) {
326 List<AbsoluteDate> list = new ArrayList<AbsoluteDate>();
327 if (existingDate == null) {
328 list.add(date);
329 } else {
330 if (date.compareTo(existingDate) > 0) {
331 AbsoluteDate t = existingDate.shiftedBy(-10 * step);
332 do {
333 t = t.shiftedBy(step);
334 list.add(list.size(), t);
335 } while (t.compareTo(date) <= 0);
336 } else {
337 AbsoluteDate t = existingDate.shiftedBy(10 * step);
338 do {
339 t = t.shiftedBy(-step);
340 list.add(0, t);
341 } while (t.compareTo(date) >= 0);
342 }
343 }
344 return list;
345 }
346
347 };
348
349 final GenericTimeStampedCache<AbsoluteDate> cache =
350 new GenericTimeStampedCache<AbsoluteDate>(5, 10, Constants.JULIAN_YEAR, Constants.JULIAN_DAY,
351 duplicatingGenerator);
352
353 final AbsoluteDate start = AbsoluteDate.GALILEO_EPOCH;
354 final List<AbsoluteDate> firstSet = cache.getNeighbors(start).collect(Collectors.toList());
355 Assert.assertEquals(5, firstSet.size());
356 Assert.assertEquals(4, cache.getGenerateCalls());
357 Assert.assertEquals(8, cache.getEntries());
358 for (int i = 1; i < firstSet.size(); ++i) {
359 Assert.assertEquals(step, firstSet.get(i).durationFrom(firstSet.get(i - 1)), 1.0e-10);
360 }
361
362 final List<AbsoluteDate> secondSet = cache.getNeighbors(cache.getLatest().shiftedBy(10 * step)).collect(Collectors.toList());
363 Assert.assertEquals(5, secondSet.size());
364 Assert.assertEquals(7, cache.getGenerateCalls());
365 Assert.assertEquals(20, cache.getEntries());
366 for (int i = 1; i < secondSet.size(); ++i) {
367 Assert.assertEquals(step, firstSet.get(i).durationFrom(firstSet.get(i - 1)), 1.0e-10);
368 }
369
370 }
371
372 private int testMultipleSingleThread(GenericTimeStampedCache<AbsoluteDate> cache, Mode mode, int slots)
373 throws TimeStampedCacheException {
374 double step = ((Generator) cache.getGenerator()).getStep();
375 AbsoluteDate[] base = new AbsoluteDate[slots];
376 base[0] = AbsoluteDate.GALILEO_EPOCH;
377 for (int i = 1; i < base.length; ++i) {
378 base[i] = base[i - 1].shiftedBy(10 * Constants.JULIAN_DAY);
379 }
380 return checkDatesSingleThread(mode.generateDates(base, 25 * step, 0.025 * step), cache);
381 }
382
383 private int testMultipleMultiThread(GenericTimeStampedCache<AbsoluteDate> cache, Mode mode,
384 int slots, int threadPoolSize)
385 throws TimeStampedCacheException {
386 double step = ((Generator) cache.getGenerator()).getStep();
387 AbsoluteDate[] base = new AbsoluteDate[slots];
388 base[0] = AbsoluteDate.GALILEO_EPOCH;
389 for (int i = 1; i < base.length; ++i) {
390 base[i] = base[i - 1].shiftedBy(10 * Constants.JULIAN_DAY);
391 }
392 return checkDatesMultiThread(mode.generateDates(base, 25 * step, 0.025 * step), cache, threadPoolSize);
393 }
394
395 private GenericTimeStampedCache<AbsoluteDate> createCache(int maxSlots, double step, int neighborsSize) {
396 Generator generator =
397 new Generator(AbsoluteDate.J2000_EPOCH.shiftedBy(-Constants.JULIAN_CENTURY),
398 AbsoluteDate.J2000_EPOCH.shiftedBy(+Constants.JULIAN_CENTURY),
399 step);
400 return new GenericTimeStampedCache<AbsoluteDate>(neighborsSize, maxSlots, Constants.JULIAN_YEAR,
401 Constants.JULIAN_DAY, generator);
402 }
403
404 private int checkDatesSingleThread(final List<AbsoluteDate> centralDates,
405 final GenericTimeStampedCache<AbsoluteDate> cache)
406 throws TimeStampedCacheException {
407
408 final int n = cache.getNeighborsSize();
409 final double step = ((Generator) cache.getGenerator()).getStep();
410
411 for (final AbsoluteDate central : centralDates) {
412 final List<AbsoluteDate> neighbors = cache.getNeighbors(central).collect(Collectors.toList());
413 Assert.assertEquals(n, neighbors.size());
414 for (final AbsoluteDate date : neighbors) {
415 Assert.assertTrue(date.durationFrom(central) >= -(n + 1) * step);
416 Assert.assertTrue(date.durationFrom(central) <= n * step);
417 }
418 }
419
420 return centralDates.size();
421
422 }
423
424 private int checkDatesMultiThread(final List<AbsoluteDate> centralDates,
425 final GenericTimeStampedCache<AbsoluteDate> cache,
426 final int threadPoolSize)
427 throws TimeStampedCacheException {
428
429 final int n = cache.getNeighborsSize();
430 final double step = ((Generator) cache.getGenerator()).getStep();
431 final AtomicReference<AbsoluteDate[]> failedDates = new AtomicReference<AbsoluteDate[]>();
432 final AtomicReference<TimeStampedCacheException> caught = new AtomicReference<TimeStampedCacheException>();
433 ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
434
435 for (final AbsoluteDate central : centralDates) {
436 executorService.execute(new Runnable() {
437 public void run() {
438 try {
439 final List<AbsoluteDate> neighbors = cache.getNeighbors(central).collect(Collectors.toList());
440 Assert.assertEquals(n, neighbors.size());
441 for (final AbsoluteDate date : neighbors) {
442 if (date.durationFrom(central) < -(n + 1) * step ||
443 date.durationFrom(central) > n * step) {
444 AbsoluteDate[] dates = new AbsoluteDate[n + 1];
445 dates[0] = central;
446 System.arraycopy(neighbors, 0, dates, 1, n);
447 failedDates.set(dates);
448 }
449 }
450 } catch (TimeStampedCacheException tce) {
451 caught.set(tce);
452 }
453 }
454 });
455 }
456
457 try {
458 executorService.shutdown();
459 Assert.assertTrue(
460 "Not enough time for all threads to complete, try increasing the timeout",
461 executorService.awaitTermination(10, TimeUnit.MINUTES));
462 } catch (InterruptedException ie) {
463 Assert.fail(ie.getLocalizedMessage());
464 }
465
466 if (caught.get() != null) {
467 throw caught.get();
468 }
469
470 if (failedDates.get() != null) {
471 AbsoluteDate[] dates = failedDates.get();
472 StringBuilder builder = new StringBuilder();
473 String eol = System.getProperty("line.separator");
474 builder.append("central = ").append(dates[0]).append(eol);
475 builder.append("step = ").append(step).append(eol);
476 builder.append("neighbors =").append(eol);
477 for (int i = 1; i < dates.length; ++i) {
478 builder.append(" ").append(dates[i]).append(eol);
479 }
480 Assert.fail(builder.toString());
481 }
482
483 return centralDates.size();
484
485 }
486
487 private static class Generator implements TimeStampedGenerator<AbsoluteDate> {
488
489 private final AbsoluteDate earliest;
490 private final AbsoluteDate latest;
491 private final double step;
492
493 public Generator(final AbsoluteDate earliest, final AbsoluteDate latest, final double step) {
494 this.earliest = earliest;
495 this.latest = latest;
496 this.step = step;
497 }
498
499 public double getStep() {
500 return step;
501 }
502
503 public List<AbsoluteDate> generate(AbsoluteDate existingDate, AbsoluteDate date) {
504 List<AbsoluteDate> dates = new ArrayList<AbsoluteDate>();
505 if (existingDate == null) {
506 dates.add(date);
507 } else if (date.compareTo(existingDate) >= 0) {
508 AbsoluteDate previous = existingDate;
509 while (date.compareTo(previous) > 0) {
510 previous = previous.shiftedBy(step);
511 if (previous.compareTo(earliest) >= 0 && previous.compareTo(latest) <= 0) {
512 dates.add(dates.size(), previous);
513 }
514 }
515 } else {
516 AbsoluteDate previous = existingDate;
517 while (date.compareTo(previous) < 0) {
518 previous = previous.shiftedBy(-step);
519 if (previous.compareTo(earliest) >= 0 && previous.compareTo(latest) <= 0) {
520 dates.add(0, previous);
521 }
522 }
523 }
524 return dates;
525 }
526
527 }
528
529 private interface Mode {
530 List<AbsoluteDate> generateDates(AbsoluteDate[] base, double duration, double step);
531 }
532
533 private class SequentialMode implements Mode {
534
535 public List<AbsoluteDate> generateDates(AbsoluteDate[] base, double duration, double step) {
536 List<AbsoluteDate> list = new ArrayList<AbsoluteDate>();
537 for (final AbsoluteDate initial : base) {
538 for (double dt = 0; dt < duration; dt += step) {
539 list.add(initial.shiftedBy(dt));
540 }
541 }
542 return list;
543 }
544
545 }
546
547 private class AlternateMode implements Mode {
548
549 public List<AbsoluteDate> generateDates(AbsoluteDate[] base, double duration, double step) {
550 List<AbsoluteDate> list = new ArrayList<AbsoluteDate>();
551 for (double dt = 0; dt < duration; dt += step) {
552 for (final AbsoluteDate initial : base) {
553 list.add(initial.shiftedBy(dt));
554 }
555 }
556 return list;
557 }
558
559 }
560
561 private class RandomMode implements Mode {
562
563 private RandomGenerator random;
564
565 public RandomMode(long seed) {
566 random = new Well1024a(seed);
567 }
568
569 public List<AbsoluteDate> generateDates(AbsoluteDate[] base, double duration, double step) {
570 List<AbsoluteDate> list = new ArrayList<AbsoluteDate>();
571 for (int i = 0; i < base.length * duration / step; ++i) {
572 int j = random.nextInt(base.length);
573 double dt = random.nextDouble() * duration;
574 list.add(base[j].shiftedBy(dt));
575 }
576 return list;
577 }
578
579 }
580
581 @Before
582 public void setUp() {
583 Utils.setDataRoot("regular-data");
584 }
585 }