use of de.invesdwin.util.time.range.TimeRange in project invesdwin-context-persistence by subes.
the class FileLiveSegmentTest method testInverseOrder.
@Test
public void testInverseOrder() {
final Map<Integer, FDate> extractTime = new HashMap<>();
final SegmentedKey<FDate> segmentedKey = new SegmentedKey<FDate>(FDate.MIN_DATE, new TimeRange(FDate.MIN_DATE, FDate.MAX_DATE));
final ALiveSegmentedTimeSeriesDB<FDate, Integer> timeSeriesDB = new ALiveSegmentedTimeSeriesDB<FDate, Integer>("testInverseOrder") {
@Override
protected File getBaseDirectory() {
return ContextProperties.getCacheDirectory();
}
@Override
protected ICloseableIterable<? extends Integer> downloadSegmentElements(final SegmentedKey<FDate> segmentedKey) {
throw new UnsupportedOperationException();
}
@Override
public AHistoricalCache<TimeRange> getSegmentFinder(final FDate key) {
throw new UnsupportedOperationException();
}
@Override
protected Integer newValueFixedLength() {
return null;
}
@Override
protected ISerde<Integer> newValueSerde() {
return IntegerSerde.GET;
}
@Override
protected FDate extractEndTime(final Integer value) {
return extractTime.get(value);
}
@Override
protected String innerHashKeyToString(final FDate key) {
return key.toString(FDate.FORMAT_UNDERSCORE_DATE_TIME_MS);
}
@Override
public FDate getFirstAvailableHistoricalSegmentFrom(final FDate key) {
throw new UnsupportedOperationException();
}
@Override
public FDate getLastAvailableHistoricalSegmentTo(final FDate key, final FDate updateTo) {
throw new UnsupportedOperationException();
}
@Override
protected String getElementsName() {
throw new UnsupportedOperationException();
}
};
@SuppressWarnings("unchecked") final ALiveSegmentedTimeSeriesDB<FDate, Integer>.HistoricalSegmentTable historicalSegmentTable = Reflections.field("historicalSegmentTable").ofType(HistoricalSegmentTable.class).in(timeSeriesDB).get();
final FileLiveSegment<FDate, Integer> rangeTable = new FileLiveSegment<FDate, Integer>(segmentedKey, historicalSegmentTable);
final FDate now = FDateBuilder.newDate(2000);
final FDate oneDate = now.addDays(1);
final FDate twoDate = now.addDays(2);
final FDate threeDate = now.addDays(3);
rangeTable.putNextLiveValue(oneDate, 1);
extractTime.put(1, oneDate);
rangeTable.putNextLiveValue(twoDate, 2);
extractTime.put(2, twoDate);
rangeTable.putNextLiveValue(threeDate, 3);
extractTime.put(3, threeDate);
final ICloseableIterator<Integer> range3 = rangeTable.rangeValues(now, null, DisabledLock.INSTANCE, null).iterator();
Assertions.assertThat(range3.next()).isEqualTo(1);
Assertions.assertThat(range3.next()).isEqualTo(2);
Assertions.assertThat(range3.next()).isEqualTo(3);
Assertions.assertThat(range3.hasNext()).isFalse();
try {
range3.next();
Fail.fail("Exception expected!");
} catch (final NoSuchElementException e) {
Assertions.assertThat(e).isNotNull();
}
// should already be closed but should not cause an error when calling again
range3.close();
final ICloseableIterator<Integer> rangeNone = rangeTable.rangeValues(null, null, DisabledLock.INSTANCE, null).iterator();
Assertions.assertThat(rangeNone.next()).isEqualTo(1);
Assertions.assertThat(rangeNone.next()).isEqualTo(2);
Assertions.assertThat(rangeNone.next()).isEqualTo(3);
Assertions.assertThat(rangeNone.hasNext()).isFalse();
try {
rangeNone.next();
Fail.fail("Exception expected!");
} catch (final NoSuchElementException e) {
Assertions.assertThat(e).isNotNull();
}
final ICloseableIterator<Integer> rangeMin = rangeTable.rangeValues(FDate.MIN_DATE, null, DisabledLock.INSTANCE, null).iterator();
Assertions.assertThat(rangeMin.next()).isEqualTo(1);
Assertions.assertThat(rangeMin.next()).isEqualTo(2);
Assertions.assertThat(rangeMin.next()).isEqualTo(3);
Assertions.assertThat(rangeMin.hasNext()).isFalse();
try {
rangeMin.next();
Fail.fail("Exception expected!");
} catch (final NoSuchElementException e) {
Assertions.assertThat(e).isNotNull();
}
final ICloseableIterator<Integer> rangeMax = rangeTable.rangeValues(FDate.MAX_DATE, null, DisabledLock.INSTANCE, null).iterator();
Assertions.assertThat(rangeMax.hasNext()).isFalse();
try {
rangeMax.next();
Fail.fail("Exception expected!");
} catch (final NoSuchElementException e) {
Assertions.assertThat(e).isNotNull();
}
final ICloseableIterator<Integer> range2 = rangeTable.rangeValues(twoDate, null, DisabledLock.INSTANCE, null).iterator();
Assertions.assertThat(range2.next()).isEqualTo(2);
Assertions.assertThat(range2.next()).isEqualTo(3);
Assertions.assertThat(range2.hasNext()).isFalse();
try {
range2.next();
Fail.fail("Exception expected!");
} catch (final NoSuchElementException e) {
Assertions.assertThat(e).isNotNull();
}
testReverse(rangeTable, oneDate, twoDate, threeDate);
testGetLatestForRange(rangeTable, oneDate, twoDate, threeDate);
rangeTable.close();
}
use of de.invesdwin.util.time.range.TimeRange in project invesdwin-context-persistence by subes.
the class RangeTableLiveSegmentTest method testInverseOrder.
@Test
public void testInverseOrder() {
final Map<Integer, FDate> extractTime = new HashMap<>();
final SegmentedKey<FDate> segmentedKey = new SegmentedKey<FDate>(FDate.MIN_DATE, new TimeRange(FDate.MIN_DATE, FDate.MAX_DATE));
final ALiveSegmentedTimeSeriesDB<FDate, Integer> timeSeriesDB = new ALiveSegmentedTimeSeriesDB<FDate, Integer>("testInverseOrder") {
@Override
protected File getBaseDirectory() {
return ContextProperties.getCacheDirectory();
}
@Override
protected ICloseableIterable<? extends Integer> downloadSegmentElements(final SegmentedKey<FDate> segmentedKey) {
throw new UnsupportedOperationException();
}
@Override
public AHistoricalCache<TimeRange> getSegmentFinder(final FDate key) {
throw new UnsupportedOperationException();
}
@Override
protected Integer newValueFixedLength() {
return null;
}
@Override
protected ISerde<Integer> newValueSerde() {
return IntegerSerde.GET;
}
@Override
protected FDate extractEndTime(final Integer value) {
return extractTime.get(value);
}
@Override
protected String innerHashKeyToString(final FDate key) {
return key.toString(FDate.FORMAT_UNDERSCORE_DATE_TIME_MS);
}
@Override
public FDate getFirstAvailableHistoricalSegmentFrom(final FDate key) {
throw new UnsupportedOperationException();
}
@Override
public FDate getLastAvailableHistoricalSegmentTo(final FDate key, final FDate updateTo) {
throw new UnsupportedOperationException();
}
@Override
protected String getElementsName() {
throw new UnsupportedOperationException();
}
};
@SuppressWarnings("unchecked") final ALiveSegmentedTimeSeriesDB<FDate, Integer>.HistoricalSegmentTable historicalSegmentTable = Reflections.field("historicalSegmentTable").ofType(HistoricalSegmentTable.class).in(timeSeriesDB).get();
final RangeTableLiveSegment<FDate, Integer> rangeTable = new RangeTableLiveSegment<FDate, Integer>(segmentedKey, historicalSegmentTable);
final FDate now = FDateBuilder.newDate(2000);
final FDate oneDate = now.addDays(1);
final FDate twoDate = now.addDays(2);
final FDate threeDate = now.addDays(3);
rangeTable.putNextLiveValue(oneDate, 1);
extractTime.put(1, oneDate);
rangeTable.putNextLiveValue(twoDate, 2);
extractTime.put(2, twoDate);
rangeTable.putNextLiveValue(threeDate, 3);
extractTime.put(3, threeDate);
final ICloseableIterator<Integer> range3 = rangeTable.rangeValues(now, null, DisabledLock.INSTANCE, null).iterator();
Assertions.assertThat(range3.next()).isEqualTo(1);
Assertions.assertThat(range3.next()).isEqualTo(2);
Assertions.assertThat(range3.next()).isEqualTo(3);
Assertions.assertThat(range3.hasNext()).isFalse();
try {
range3.next();
Fail.fail("Exception expected!");
} catch (final NoSuchElementException e) {
Assertions.assertThat(e).isNotNull();
}
// should already be closed but should not cause an error when calling again
range3.close();
final ICloseableIterator<Integer> rangeNone = rangeTable.rangeValues(null, null, DisabledLock.INSTANCE, null).iterator();
Assertions.assertThat(rangeNone.next()).isEqualTo(1);
Assertions.assertThat(rangeNone.next()).isEqualTo(2);
Assertions.assertThat(rangeNone.next()).isEqualTo(3);
Assertions.assertThat(rangeNone.hasNext()).isFalse();
try {
rangeNone.next();
Fail.fail("Exception expected!");
} catch (final NoSuchElementException e) {
Assertions.assertThat(e).isNotNull();
}
final ICloseableIterator<Integer> rangeMin = rangeTable.rangeValues(FDate.MIN_DATE, null, DisabledLock.INSTANCE, null).iterator();
Assertions.assertThat(rangeMin.next()).isEqualTo(1);
Assertions.assertThat(rangeMin.next()).isEqualTo(2);
Assertions.assertThat(rangeMin.next()).isEqualTo(3);
Assertions.assertThat(rangeMin.hasNext()).isFalse();
try {
rangeMin.next();
Fail.fail("Exception expected!");
} catch (final NoSuchElementException e) {
Assertions.assertThat(e).isNotNull();
}
final ICloseableIterator<Integer> rangeMax = rangeTable.rangeValues(FDate.MAX_DATE, null, DisabledLock.INSTANCE, null).iterator();
Assertions.assertThat(rangeMax.hasNext()).isFalse();
try {
rangeMax.next();
Fail.fail("Exception expected!");
} catch (final NoSuchElementException e) {
Assertions.assertThat(e).isNotNull();
}
final ICloseableIterator<Integer> range2 = rangeTable.rangeValues(twoDate, null, DisabledLock.INSTANCE, null).iterator();
Assertions.assertThat(range2.next()).isEqualTo(2);
Assertions.assertThat(range2.next()).isEqualTo(3);
Assertions.assertThat(range2.hasNext()).isFalse();
try {
range2.next();
Fail.fail("Exception expected!");
} catch (final NoSuchElementException e) {
Assertions.assertThat(e).isNotNull();
}
testReverse(rangeTable, oneDate, twoDate, threeDate);
testGetLatestForRange(rangeTable, oneDate, twoDate, threeDate);
rangeTable.close();
}
use of de.invesdwin.util.time.range.TimeRange in project invesdwin-context-persistence by subes.
the class ASegmentedTimeSeriesStorageCache method getSegments.
private ICloseableIterable<TimeRange> getSegments(final FDate from, final FDate to, final FDate lastAvailableSegmentTo) {
if (from == null || to == null) {
return EmptyCloseableIterable.getInstance();
}
final TimeRange nextSegment = getSegmentFinder(key).query().getValue(to.addMilliseconds(1));
final FDate adjTo;
if (to.equalsNotNullSafe(lastAvailableSegmentTo) && nextSegment.getFrom().equalsNotNullSafe(to)) {
// adjust for overlapping segments
adjTo = to.addMilliseconds(-1);
} else {
adjTo = to;
}
final FDate adjFrom = from;
final ICloseableIterable<TimeRange> segments = new ICloseableIterable<TimeRange>() {
@Override
public ICloseableIterator<TimeRange> iterator() {
return new ICloseableIterator<TimeRange>() {
private TimeRange nextSegment = getSegmentFinder(key).query().getValue(adjFrom);
@Override
public boolean hasNext() {
return nextSegment != null && nextSegment.getFrom().isBeforeOrEqualTo(adjTo);
}
@Override
public TimeRange next() {
if (nextSegment == null) {
throw new FastNoSuchElementException("ASegmentedTimeSeriesStorageCache getSegments nextSegment is null");
}
final TimeRange curSegment = nextSegment;
// get one segment later
nextSegment = determineNextSegment(curSegment);
return curSegment;
}
private TimeRange determineNextSegment(final TimeRange curSegment) {
final FDate nextSegmentStart = nextSegment.getTo().addMilliseconds(1);
final TimeRange nextSegment = getSegmentFinder(key).query().getValue(nextSegmentStart);
if (!curSegment.getTo().equalsNotNullSafe(nextSegment.getFrom()) && !nextSegmentStart.equals(nextSegment.getFrom())) {
// allow overlapping segments
throw new IllegalStateException("Segment start expected [" + curSegment.getTo() + " or " + nextSegmentStart + "] != found [" + nextSegment.getFrom() + "]");
}
return nextSegment;
}
@Override
public void close() {
nextSegment = null;
}
};
}
};
final ASkippingIterable<TimeRange> filteredSegments = new ASkippingIterable<TimeRange>(segments) {
@Override
protected boolean skip(final TimeRange element) {
// though additionally skip ranges that exceed the available dates
final FDate segmentTo = element.getTo();
if (segmentTo.isBefore(adjFrom)) {
throw new IllegalStateException("segmentTo [" + segmentTo + "] should not be before adjFrom [" + adjFrom + "]");
}
final FDate segmentFrom = element.getFrom();
if (segmentFrom.isAfter(adjTo)) {
// no need to continue going higher
throw new FastNoSuchElementException("ASegmentedTimeSeriesStorageCache getSegments end reached");
}
return false;
}
};
return filteredSegments;
}
use of de.invesdwin.util.time.range.TimeRange in project invesdwin-context-persistence by subes.
the class ALiveSegmentedTimeSeriesDBWithCacheTest method setUp.
@Override
public void setUp() throws Exception {
super.setUp();
final AHistoricalCache<TimeRange> segmentFinder = PeriodicalSegmentFinder.newCache(new Duration(2, FTimeUnit.YEARS), false);
table = new ALiveSegmentedTimeSeriesDB<String, FDate>(getClass().getSimpleName()) {
private FDate curTime = null;
@Override
public AHistoricalCache<TimeRange> getSegmentFinder(final String key) {
return segmentFinder;
}
@Override
protected ISerde<FDate> newValueSerde() {
return new TypeDelegateSerde<FDate>(FDate.class);
}
@Override
protected Integer newValueFixedLength() {
return null;
}
@Override
protected String innerHashKeyToString(final String key) {
return key;
}
@Override
protected FDate extractEndTime(final FDate value) {
return value;
}
@Override
protected File getBaseDirectory() {
return ContextProperties.TEMP_DIRECTORY;
}
@Override
protected ICloseableIterable<? extends FDate> downloadSegmentElements(final SegmentedKey<String> segmentedKey) {
return new ASkippingIterable<FDate>(WrapperCloseableIterable.maybeWrap(entities)) {
private final FDate from = segmentedKey.getSegment().getFrom();
private final FDate to = segmentedKey.getSegment().getTo();
@Override
protected boolean skip(final FDate element) {
return element.isBefore(from) || element.isAfter(to);
}
};
}
@Override
public FDate getFirstAvailableHistoricalSegmentFrom(final String key) {
if (entities.isEmpty() || curTime == null) {
return null;
}
final FDate firstTime = FDates.min(curTime, entities.get(0));
final TimeRange firstSegment = segmentFinder.query().getValue(firstTime);
if (firstSegment.getTo().isBeforeOrEqualTo(curTime)) {
return firstSegment.getFrom();
} else {
return segmentFinder.query().getValue(firstSegment.getFrom().addMilliseconds(-1)).getFrom();
}
}
@Override
public FDate getLastAvailableHistoricalSegmentTo(final String key, final FDate updateTo) {
if (entities.isEmpty() || curTime == null) {
return null;
}
final TimeRange lastSegment = segmentFinder.query().getValue(curTime);
if (lastSegment.getTo().isBeforeOrEqualTo(curTime)) {
return lastSegment.getTo();
} else {
return segmentFinder.query().getValue(lastSegment.getFrom().addMilliseconds(-1)).getTo();
}
}
@Override
public void putNextLiveValue(final String key, final FDate nextLiveValue) {
curTime = nextLiveValue;
super.putNextLiveValue(key, nextLiveValue);
}
@Override
protected String getElementsName() {
return "values";
}
};
for (final FDate entity : entities) {
table.putNextLiveValue(KEY, entity);
}
}
use of de.invesdwin.util.time.range.TimeRange in project invesdwin-context-persistence by subes.
the class ALiveSegmentedTimeSeriesDBWithNoCacheAndNoQueryCacheTest method setUp.
@Override
public void setUp() throws Exception {
super.setUp();
final AHistoricalCache<TimeRange> segmentFinder = new AHistoricalCache<TimeRange>() {
private final PeriodicalSegmentFinder calculation = PeriodicalSegmentFinder.newInstance(new Duration(2, FTimeUnit.YEARS));
@Override
protected Integer getInitialMaximumSize() {
return 1000;
}
@Override
protected FDate innerExtractKey(final TimeRange value) {
return value.getFrom();
}
@Override
protected IEvaluateGenericFDate<TimeRange> newLoadValue() {
return this::loadValue;
}
private synchronized TimeRange loadValue(final IFDateProvider pKey) {
final FDate key = pKey.asFDate();
final TimeRange value = calculation.getSegment(key);
final TimeRange upperTimeRange = new TimeRange(value.getFrom().addYears(1), value.getTo().addYears(1));
if (upperTimeRange.containsInclusive(key)) {
return upperTimeRange;
} else {
return new TimeRange(value.getFrom().addYears(-1), value.getTo().addYears(-1));
}
}
@Override
protected FDate innerCalculateNextKey(final FDate key) {
return query().getValue(key).getTo().addMilliseconds(1);
}
@Override
protected FDate innerCalculatePreviousKey(final FDate key) {
return query().getValue(key).getFrom().addMilliseconds(-1);
}
@Override
public void preloadData(final ExecutorService executor) {
// noop
}
};
table = new ALiveSegmentedTimeSeriesDB<String, FDate>(getClass().getSimpleName()) {
private FDate curTime = null;
@Override
public AHistoricalCache<TimeRange> getSegmentFinder(final String key) {
return segmentFinder;
}
@Override
protected ISerde<FDate> newValueSerde() {
return new TypeDelegateSerde<FDate>(FDate.class);
}
@Override
protected Integer newValueFixedLength() {
return null;
}
@Override
protected String innerHashKeyToString(final String key) {
return key;
}
@Override
protected File getBaseDirectory() {
return ContextProperties.TEMP_DIRECTORY;
}
@Override
protected ICloseableIterable<? extends FDate> downloadSegmentElements(final SegmentedKey<String> segmentedKey) {
return new ASkippingIterable<FDate>(WrapperCloseableIterable.maybeWrap(entities)) {
private final FDate from = segmentedKey.getSegment().getFrom();
private final FDate to = segmentedKey.getSegment().getTo();
@Override
protected boolean skip(final FDate element) {
return element.isBefore(from) || element.isAfter(to);
}
};
}
@Override
protected FDate extractEndTime(final FDate value) {
return value;
}
@Override
public FDate getFirstAvailableHistoricalSegmentFrom(final String key) {
if (entities.isEmpty() || curTime == null) {
return null;
}
final FDate firstTime = FDates.min(curTime, entities.get(0));
final TimeRange firstSegment = segmentFinder.query().getValue(firstTime);
if (firstSegment.getTo().isBeforeOrEqualTo(curTime)) {
return firstSegment.getFrom();
} else {
return segmentFinder.query().getValue(firstSegment.getFrom().addMilliseconds(-1)).getFrom();
}
}
@Override
public FDate getLastAvailableHistoricalSegmentTo(final String key, final FDate updateTo) {
if (entities.isEmpty() || curTime == null) {
return null;
}
final TimeRange lastSegment = segmentFinder.query().getValue(curTime);
if (lastSegment.getTo().isBeforeOrEqualTo(curTime)) {
return lastSegment.getTo();
} else {
return segmentFinder.query().getValue(lastSegment.getFrom().addMilliseconds(-1)).getTo();
}
}
@Override
public void putNextLiveValue(final String key, final FDate nextLiveValue) {
curTime = nextLiveValue;
super.putNextLiveValue(key, nextLiveValue);
}
@Override
protected String getElementsName() {
return "values";
}
};
for (final FDate entity : entities) {
table.putNextLiveValue(KEY, entity);
}
}
Aggregations