use of de.invesdwin.util.time.range.TimeRange in project invesdwin-context-persistence by subes.
the class ASegmentedTimeSeriesDBWithoutShiftKeysAndQueryInterceptorTest method setUp.
@Override
public void setUp() throws Exception {
super.setUp();
final AHistoricalCache<TimeRange> segmentFinder = PeriodicalSegmentFinder.newCache(new Duration(2, FTimeUnit.YEARS), false);
table = new ASegmentedTimeSeriesDB<String, FDate>(getClass().getSimpleName()) {
@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()) {
return null;
}
return segmentFinder.query().getValue(entities.get(0)).getFrom();
}
@Override
public FDate getLastAvailableHistoricalSegmentTo(final String key, final FDate updateTo) {
if (entities.isEmpty()) {
return null;
}
return segmentFinder.query().getValue(entities.get(entities.size() - 1)).getTo();
}
@Override
protected String getElementsName() {
return "values";
}
};
}
use of de.invesdwin.util.time.range.TimeRange in project invesdwin-context-persistence by subes.
the class ASegmentedTimeSeriesStorageCache method getSegmentsReverse.
private ICloseableIterable<TimeRange> getSegmentsReverse(final FDate from, final FDate to, final FDate lastAvailableSegmentTo) {
if (from == null || to == null) {
return EmptyCloseableIterable.getInstance();
}
final TimeRange nextSegment = getSegmentFinder(key).query().getValue(from.addMilliseconds(1));
final FDate adjFrom;
if (from.equalsNotNullSafe(lastAvailableSegmentTo) && nextSegment.getFrom().equalsNotNullSafe(from)) {
// adjust for overlapping segments
adjFrom = from.addMilliseconds(-1);
} else {
adjFrom = from;
}
final FDate adjTo = to;
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.getTo().isAfter(adjTo);
}
@Override
public TimeRange next() {
final TimeRange curSegment = nextSegment;
if (curSegment == null) {
throw new FastNoSuchElementException("ASegmentedTimeSeriesStorageCache getSegments end reached null");
}
// get one segment earlier
nextSegment = getSegmentFinder(key).query().setFutureNullEnabled().getValue(nextSegment.getFrom().addMilliseconds(-1));
return curSegment;
}
@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(adjTo)) {
// no need to continue going lower
throw new FastNoSuchElementException("ASegmentedTimeSeriesStorageCache getSegments end reached adjTo");
}
// skip last value and continue with earlier ones
final FDate segmentFrom = element.getFrom();
return segmentFrom.isAfter(adjFrom);
}
};
return filteredSegments;
}
use of de.invesdwin.util.time.range.TimeRange in project invesdwin-context-persistence by subes.
the class ASegmentedTimeSeriesStorageCache method readRangeValues.
public ICloseableIterable<V> readRangeValues(final FDate from, final FDate to, final Lock readLock, final ISkipFileFunction skipFileFunction) {
final FDate firstAvailableSegmentFrom = getFirstAvailableSegmentFrom(key);
if (firstAvailableSegmentFrom == null) {
return EmptyCloseableIterable.getInstance();
}
final FDate lastAvailableSegmentTo = getLastAvailableSegmentTo(key, to);
if (lastAvailableSegmentTo == null) {
return EmptyCloseableIterable.getInstance();
}
// adjust dates directly to prevent unnecessary segment calculations
final FDate adjFrom = FDates.max(from, firstAvailableSegmentFrom);
final FDate adjTo = FDates.min(to, lastAvailableSegmentTo);
final ICloseableIterable<TimeRange> segments = getSegments(adjFrom, adjTo, lastAvailableSegmentTo);
final ATransformingIterable<TimeRange, ICloseableIterable<V>> segmentQueries = new ATransformingIterable<TimeRange, ICloseableIterable<V>>(segments) {
@Override
protected ICloseableIterable<V> transform(final TimeRange value) {
return new ICloseableIterable<V>() {
@Override
public ICloseableIterator<V> iterator() {
final SegmentedKey<K> segmentedKey = new SegmentedKey<K>(key, value);
maybeInitSegment(segmentedKey);
final FDate segmentAdjFrom = FDates.max(adjFrom, value.getFrom());
final FDate segmentAdjTo = FDates.min(adjTo, value.getTo());
final Lock compositeReadLock = Locks.newCompositeLock(readLock, segmentedTable.getTableLock(segmentedKey).readLock());
return segmentedTable.getLookupTableCache(segmentedKey).readRangeValues(segmentAdjFrom, segmentAdjTo, compositeReadLock, skipFileFunction);
}
};
}
};
final ICloseableIterable<V> rangeValues = new FlatteningIterable<V>(segmentQueries);
return rangeValues;
}
use of de.invesdwin.util.time.range.TimeRange in project invesdwin-context-persistence by subes.
the class ASegmentedTimeSeriesStorageCache method getFirstValue.
public V getFirstValue() {
if (cachedFirstValue != null) {
maybePrepareForUpdate(null);
}
if (cachedFirstValue == null) {
final FDate firstAvailableSegmentFrom = getFirstAvailableSegmentFrom(key);
if (firstAvailableSegmentFrom == null) {
cachedFirstValue = Optional.empty();
} else {
FDate lastAvailableSegmentTo = getLastAvailableSegmentTo(key, null);
final TimeRange nextSegment = getSegmentFinder(key).query().getValue(lastAvailableSegmentTo.addMilliseconds(1));
if (nextSegment.getFrom().equals(lastAvailableSegmentTo)) {
// adjust for overlapping segments
lastAvailableSegmentTo = lastAvailableSegmentTo.addMilliseconds(-1);
}
final IHistoricalCacheQuery<TimeRange> segmentFinderQuery = getSegmentFinder(key).query();
final TimeRange lastSegment = segmentFinderQuery.getValue(lastAvailableSegmentTo);
TimeRange segment = segmentFinderQuery.getValue(firstAvailableSegmentFrom);
if (!segment.getFrom().equalsNotNullSafe(firstAvailableSegmentFrom)) {
throw new IllegalStateException("segment.from [" + segment.getFrom() + "] should be equal to firstAvailableSegmentFrom [" + firstAvailableSegmentFrom + "]");
}
while (cachedFirstValue == null && segment.getFrom().isBeforeOrEqualTo(lastSegment.getFrom())) {
final SegmentedKey<K> segmentedKey = new SegmentedKey<K>(key, segment);
maybeInitSegment(segmentedKey);
final String segmentedHashKey = segmentedTable.hashKeyToString(segmentedKey);
final MemoryFileSummary latestValue = storage.getFileLookupTable().getLatestValue(segmentedHashKey, FDate.MIN_DATE);
final V firstValue;
if (latestValue == null) {
segment = segmentFinderQuery.getValue(segment.getTo().addMilliseconds(1));
} else {
firstValue = latestValue.getFirstValue(valueSerde);
cachedFirstValue = Optional.of(firstValue);
}
}
if (cachedFirstValue == null) {
cachedFirstValue = Optional.empty();
}
}
}
return cachedFirstValue.orElse(null);
}
use of de.invesdwin.util.time.range.TimeRange in project invesdwin-context-persistence by subes.
the class ASegmentedTimeSeriesStorageCache method readRangeValuesReverse.
public ICloseableIterable<V> readRangeValuesReverse(final FDate from, final FDate to, final Lock readLock, final ISkipFileFunction skipFileFunction) {
final FDate firstAvailableSegmentFrom = getFirstAvailableSegmentFrom(key);
final FDate lastAvailableSegmentTo = getLastAvailableSegmentTo(key, to);
// adjust dates directly to prevent unnecessary segment calculations
final FDate adjFrom = FDates.min(from, lastAvailableSegmentTo);
final FDate adjTo = FDates.max(to, firstAvailableSegmentFrom);
final ICloseableIterable<TimeRange> filteredSegments = getSegmentsReverse(adjFrom, adjTo, lastAvailableSegmentTo);
final ATransformingIterable<TimeRange, ICloseableIterable<V>> segmentQueries = new ATransformingIterable<TimeRange, ICloseableIterable<V>>(filteredSegments) {
@Override
protected ICloseableIterable<V> transform(final TimeRange value) {
return new ICloseableIterable<V>() {
@Override
public ICloseableIterator<V> iterator() {
final SegmentedKey<K> segmentedKey = new SegmentedKey<K>(key, value);
maybeInitSegment(segmentedKey);
final FDate segmentAdjFrom = FDates.min(adjFrom, value.getTo());
final FDate segmentAdjTo = FDates.max(adjTo, value.getFrom());
final Lock compositeReadLock = Locks.newCompositeLock(readLock, segmentedTable.getTableLock(segmentedKey).readLock());
return segmentedTable.getLookupTableCache(segmentedKey).readRangeValuesReverse(segmentAdjFrom, segmentAdjTo, compositeReadLock, skipFileFunction);
}
};
}
};
final ICloseableIterable<V> rangeValues = new FlatteningIterable<V>(segmentQueries);
return rangeValues;
}
Aggregations