package org.dcache.services.info.stateInfo;
import diskCacheV111.pools.PoolCostInfo;
import org.dcache.services.info.base.IntegerStateValue;
import org.dcache.services.info.base.StatePath;
import org.dcache.services.info.base.StateUpdate;
/**
* Information about some (generic) space.
*
* @author Paul Millar <paul.millar@desy.de>
*/
public class SpaceInfo
{
public static final String PATH_ELEMENT_TOTAL = "total";
public static final String PATH_ELEMENT_FREE = "free";
public static final String PATH_ELEMENT_PRECIOUS = "precious";
public static final String PATH_ELEMENT_REMOVABLE = "removable";
public static final String PATH_ELEMENT_USED = "used";
private long _total;
private long _free;
private long _precious;
private long _removable;
private long _used;
public SpaceInfo(long totalSpace, long freeSpace, long preciousSpace,
long removableSpace)
{
_total = totalSpace;
_free = freeSpace;
_precious = preciousSpace;
_removable = removableSpace;
// Derived data.
_used = totalSpace - freeSpace;
}
/**
* Create a new SpaceInfo that duplicates information in otherInfo
* @param otherInfo the SpaceInfo to duplicate
*/
public SpaceInfo(SpaceInfo otherInfo)
{
this(otherInfo.getTotal(), otherInfo.getFree(), otherInfo.getPrecious(),
otherInfo.getRemovable());
}
/**
* Create a zero-sized Space.
*/
public SpaceInfo()
{
_total = _free = _precious = _removable = _used = 0;
}
/**
* Create an initially-empty space information.
* @param capacity the size of the space.
*/
public SpaceInfo(long capacity)
{
_free = _total = capacity;
_used = _precious = _removable = 0;
}
public SpaceInfo(PoolCostInfo.PoolSpaceInfo spaceInfo)
{
_total = spaceInfo.getTotalSpace();
_free = spaceInfo.getFreeSpace();
_precious = spaceInfo.getPreciousSpace();
_removable = spaceInfo.getRemovableSpace();
//_used = spaceInfo.getUsedSpace();
_used = _total-_free;
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof SpaceInfo)) {
return false;
}
SpaceInfo info = (SpaceInfo) o;
return info._total == _total && info._free == _free && info._precious == _precious && info._removable == _removable && info._used == _used;
}
@Override
public int hashCode()
{
return (int)_total+(int)_free+(int)_precious+(int)_removable;
}
/**
* Increase space values by the values specified in otherSpace
* @param otherSpace the SpaceInfo to add
*/
public void add(SpaceInfo otherSpace)
{
if (otherSpace == null) {
return;
}
_total += otherSpace._total;
_free += otherSpace._free;
_precious += otherSpace._precious;
_removable += otherSpace._removable;
_used += otherSpace._used;
}
public void setTotal(long totalSpace)
{
_total = totalSpace;
}
public void setFree(long freeSpace)
{
_free = freeSpace;
}
public void setPrecious(long preciousSpace)
{
_precious = preciousSpace;
}
public void setRemovable(long removableSpace)
{
_removable = removableSpace;
}
public void setUsed(long usedSpace)
{
_used = usedSpace;
}
/**
* Add additional space unconditionally to the recorded total space.
* @param extraTotalSpace amount to add
*/
public void addToTotal(long extraTotalSpace)
{
_total += extraTotalSpace;
}
/**
* Add additional space unconditionally to the recorded free space.
* @param extraFreeSpace amount to add
*/
public void addToFree(long extraFreeSpace)
{
_free += extraFreeSpace;
}
/**
* Add additional space unconditionally to the recorded removable space.
* @param extraRemovableSpace amount to add
*/
public void addToRemovable(long extraRemovableSpace)
{
_removable += extraRemovableSpace;
}
/**
* Add additional space unconditionally to the recorded precious space
* @param extraPreciousSpace amount to add
*/
public void addToPrecious(long extraPreciousSpace)
{
_precious += extraPreciousSpace;
}
/**
* Add additional space unconditionally to the recorded used space
* @param extraUsedSpace amount to add
*/
public void addToUsed(long extraUsedSpace)
{
_used += extraUsedSpace;
}
/**
* Update the precious space, applying a delta.
* If the delta would be impossible, it is capped.
* The free space is also adjusted.
* @param change the change to precious space: positive number increases space usage.
*/
public void updatePrecious(long change)
{
if (change > _free) {
change = _free;
}
if (change < -_precious) {
change = -_precious;
}
_precious += change;
recalcFree();
}
/**
* Update the space used to store removable data. The
* value is updated by applying a delta. If the delta would
* be impossible, it is capped. The free space is also adjusted
* @param change the change to removable space: positive number increases space usage.
*/
public void updateRemovable(long change)
{
if (change > _free) {
change = _free;
}
if (change < -_removable) {
change = -_removable;
}
_removable += change;
recalcFree();
}
/**
* Recalculate the free space based on total capacity, precious
* removable and pinned. If the free-space would
* be negative (due to inconsistent information), it is
* capped at 0.
*/
public void recalcFree()
{
_used = _precious + _removable;
_free = _used < _total ? _total - _used : 0;
}
public long getTotal()
{
return _total;
}
public long getFree()
{
return _free;
}
public long getPrecious()
{
return _precious;
}
public long getRemovable()
{
return _removable;
}
public long getUsed()
{
return _used;
}
/**
* Add StateUpdate entries to update dCache state that add or update the standard metrics
* values. All metrics are added under a common StatePath. StateValues will be Mortal and
* will expire after the given duration has elapsed.
* @param update the StateUpdate to append with the new metrics
* @param path the point in dCache state that the metrics will be children of.
* @param duration how long this metric should survive, in seconds.
*/
public void addMetrics(StateUpdate update, StatePath path, long duration)
{
update.appendUpdate(path.newChild(PATH_ELEMENT_TOTAL), new IntegerStateValue(_total, duration));
update.appendUpdate(path.newChild(PATH_ELEMENT_FREE), new IntegerStateValue(_free, duration));
update.appendUpdate(path.newChild(PATH_ELEMENT_PRECIOUS), new IntegerStateValue(_precious, duration));
update.appendUpdate(path.newChild(PATH_ELEMENT_REMOVABLE), new IntegerStateValue(_removable, duration));
update.appendUpdate(path.newChild(PATH_ELEMENT_USED), new IntegerStateValue(_used, duration));
}
/**
* Add StateUpdate entries to update dCache state that add or update the standard metrics
* values. All metrics are added under a common StatePath. StateValues will be Ephemeral
* or Immortal
* @param update the StateUpdate to append these values.
* @param path the StatePath under which the StateValues will be added.
* @param isImmortal if true, the metric will be immortal, otherwise ephemeral.
*/
public void addMetrics(StateUpdate update, StatePath path, boolean isImmortal)
{
update.appendUpdate(path.newChild(PATH_ELEMENT_TOTAL), new IntegerStateValue(_total, isImmortal));
update.appendUpdate(path.newChild(PATH_ELEMENT_FREE), new IntegerStateValue(_free, isImmortal));
update.appendUpdate(path.newChild(PATH_ELEMENT_PRECIOUS), new IntegerStateValue(_precious, isImmortal));
update.appendUpdate(path.newChild(PATH_ELEMENT_REMOVABLE), new IntegerStateValue(_removable, isImmortal));
update.appendUpdate(path.newChild(PATH_ELEMENT_USED), new IntegerStateValue(_used, isImmortal));
}
/**
* A string describing this SpaceInfo object.
*/
@Override
public String toString()
{
return "[SpaceInfo: total="+_total + ", precious="+_precious +
", removable="+_removable + ", used="+_used + ", free="+_free +"]";
}
}