package com.github.ruediste1.btrbck.dom;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.joda.time.Period;
/**
* Describes a set of {@link Snapshot}s that should be retained.
*
* <p>
* The {@link #period} defines how far back from now the snapshots are to be
* retained. During this time, {@link #snapshotsPerTimeUnit} snapshots should be
* retained per {@link #timeUnit}. The snapshots should be evenly distributed
* within the time unit.
* </p>
*
* <p>
* The {@link Retention} defines a set of instants for which snapshots should
* ideally be retained. Since there is usually no snapshot at this precise
* instant, the next snapshot is taken.
* </p>
*/
@XmlRootElement
public class Retention {
/**
* Defines how far back snapshots should be retained
*/
@XmlJavaTypeAdapter(PeriodAdapter.class)
@XmlAttribute
public Period period;
/**
* {@link #snapshotsPerTimeUnit} {@link Snapshot}s per {@link #timeUnit}
* should be retained.
*/
@XmlAttribute
public TimeUnit timeUnit;
/**
* {@link #snapshotsPerTimeUnit} {@link Snapshot}s per {@link #timeUnit}
* should be retained.
*/
@XmlAttribute
public int snapshotsPerTimeUnit;
/**
* Calculate the instants a snapshot should be retained for, given the
* current time.
*/
public Set<DateTime> retentionTimes(DateTime now) {
HashSet<DateTime> result = new HashSet<>();
Interval interval = new Interval(now.minus(period), now);
DateTime current = timeUnit.truncate(interval.getStart());
while (current.isBefore(now)) {
DateTime endOfUnit = current.plus(timeUnit.getPeriod());
long step = new Interval(current, endOfUnit).toDurationMillis()
/ snapshotsPerTimeUnit;
for (int i = 0; i < snapshotsPerTimeUnit; i++) {
DateTime retentionTime = current.plus(i * step);
if (interval.contains(retentionTime)) {
result.add(retentionTime);
}
}
current = endOfUnit;
}
return result;
}
}