/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* ident "%Z%%M% %I% %E% SMI"
*/
package com.sun.solaris.domain.pools;
import java.math.BigInteger;
import java.util.Date;
import java.util.Iterator;
import java.text.*;
import com.sun.solaris.service.pools.UnsignedInt64;
/**
* Contains the information relating to a specific statistic for an
* object. The Statistic has no notion of the source of the data, it
* is simply a repository for holding statistical information.
*/
interface Statistic
{
/**
* Return the start of the sample period for which the
* statistic is representative.
*/
public Date getStart();
/**
* Return the end of the sample period for which the
* statistic is representative.
*/
public Date getEnd();
/**
* Get the value of this statistic.
*/
public Object getValue();
/**
* Get the value of this statistic as a Long.
*/
public Long getLongValue();
/**
* Get the value of this statistic as a Double.
*/
public Double getDoubleValue();
/**
* Get the value of this statistic as a UnsignedInt64.
*/
public UnsignedInt64 getUnsignedInt64Value();
}
/**
* An interface for Statistics which may be aggregated.
*/
interface AggregateStatistic extends Statistic
{
/**
* Add the supplied statistic to this.
*
* @param o The other statistic.
*/
public AggregateStatistic add(AggregateStatistic o);
/**
* Subtract the supplied statistic from this.
*
* @param o The other statistic.
*/
public AggregateStatistic subtract(AggregateStatistic o);
/**
* Produce the aggregate of all objects in the supplied
* iterator (which must be of the same type) whose start and
* end dates lie within the supplied ranges. If either start
* or end is null, then that bound is not applied. i.e. if no
* start date is supplied, then start checking is disabled.
*
* @param start The start date for qualification in the snapshot.
* @param end The end date for qualification in the snapshot.
* @throws IllegalArgumentException If the iterator is empty.
*/
public AggregateStatistic getSnapshotForInterval(Iterator it,
Date start, Date end) throws IllegalArgumentException;
}
/**
* A basic Statistic implementation which makes it easy to derive
* concrete statistic types. This is an immutable class, the state is
* set when the object is constructed and cannot be later changed.
*/
abstract class AbstractStatistic implements Statistic
{
/**
* The value of the statistic.
*/
private final Object value;
/**
* The start of the interval during which the statistic was
* captured.
*/
private final Date start;
/**
* The end of the interval during which the statistic was
* captured.
*/
private final Date end;
/**
* Formatter for the sample start time, used by toString().
*/
private static final DateFormat df = new SimpleDateFormat("kk:mm:ss");
/**
* Constructor. This is provided as a mechanism to allow
* inherited classes to correctly initialize their state.
*
* @param value The value of this statistic.
*/
protected AbstractStatistic(Object value)
{
this(value, null, null);
}
/**
* Constructor. This is provided as a mechanism to allow
* inherited classes to correctly initialize their state.
*
* @param value The value of this statistic.
* @param start The start of the sample period which this
* statistic represents.
* @param end The end of the sample period which this
* statistic represents.
*/
protected AbstractStatistic(Object value, Date start, Date end)
{
this.value = value;
this.start = start;
this.end = end;
}
/**
* Return the start of the sample period for which the
* statistic is representative.
*/
public Date getStart()
{
return (start);
}
/**
* Return the end of the sample period for which the
* statistic is representative.
*/
public Date getEnd()
{
return (end);
}
/**
* Get the value of this statistic.
*/
public Object getValue()
{
return (value);
}
public abstract Long getLongValue();
public abstract Double getDoubleValue();
public abstract UnsignedInt64 getUnsignedInt64Value();
/**
* Return the string representation of this statistic.
*/
public String toString()
{
StringBuffer buf = new StringBuffer();
buf.append(value);
if (start != null && end != null) {
buf.append(" from ");
buf.append(df.format(start));
buf.append(" to ");
buf.append(df.format(end));
}
return (buf.toString());
}
}
/**
* A statistic of type Double.
*/
final class DoubleStatistic extends AbstractStatistic
implements AggregateStatistic
{
/**
* Constructor.
*
* @param value The value of this statistic.
*/
public DoubleStatistic(Double value)
{
super(value);
}
/**
* Constructor.
*
* @param value The value of this statistic.
* @param start The start of the interval over which this
* statistic is representative.
* @param end The end of the interval over which this
* statistic is representative.
*/
public DoubleStatistic(Double value, Date start, Date end)
{
super(value, start, end);
}
public Double getDoubleValue()
{
return ((Double) getValue());
}
public Long getLongValue()
{
return (new Long(((Double) getValue()).longValue()));
}
public UnsignedInt64 getUnsignedInt64Value()
{
return (new UnsignedInt64(Long.toString(((Double) getValue()).
longValue())));
}
public AggregateStatistic add(AggregateStatistic o)
{
Double v1 = getDoubleValue();
Double v2 = o.getDoubleValue();
return (new DoubleStatistic(new Double(v1.doubleValue() +
v2.doubleValue()),
getStart(), getEnd()));
}
public AggregateStatistic subtract(AggregateStatistic o)
{
Double v1 = getDoubleValue();
Double v2 = o.getDoubleValue();
return (new DoubleStatistic(new Double(v1.doubleValue() -
v2.doubleValue()),
getStart(), getEnd()));
}
public AggregateStatistic getSnapshotForInterval(Iterator it,
Date start, Date end) throws IllegalArgumentException
{
double total = 0;
int count = 0;
Date first = start, last = end;
while (it.hasNext()) {
DoubleStatistic s = (DoubleStatistic) it.next();
if (start != null) {
if (s.getStart().compareTo(start) < 0)
continue;
}
if (first == null)
first = s.getStart();
if (end != null) {
if (s.getEnd().compareTo(end) > 0)
continue;
}
last = s.getEnd();
total += s.getDoubleValue().doubleValue();
count++;
}
if (count == 0)
throw new IllegalArgumentException("Cannot derive a " +
"snapshot from an empty iterator");
return (new DoubleStatistic(new Double(total / count), first,
last));
}
}
/**
* A statistic of type Long.
*/
final class LongStatistic extends AbstractStatistic
implements AggregateStatistic
{
/**
* Constructor.
*
* @param value The value of this statistic.
* @param start The start of the interval over which this
* statistic is representative.
* @param end The end of the interval over which this
* statistic is representative.
*/
public LongStatistic(Long value, Date start, Date end)
{
super(value, start, end);
}
public Double getDoubleValue()
{
return (new Double(((Long) getValue()).longValue()));
}
public Long getLongValue()
{
return ((Long) getValue());
}
public UnsignedInt64 getUnsignedInt64Value()
{
return (new UnsignedInt64(Long.toString(((Long) getValue()).
longValue())));
}
public AggregateStatistic add(AggregateStatistic o)
{
Long v1 = getLongValue();
Long v2 = o.getLongValue();
return (new LongStatistic(new Long(v1.longValue() +
v2.longValue()),
getStart(), getEnd()));
}
public AggregateStatistic subtract(AggregateStatistic o)
{
Long v1 = getLongValue();
Long v2 = o.getLongValue();
return (new LongStatistic(new Long(v1.longValue() -
v2.longValue()),
getStart(), getEnd()));
}
public AggregateStatistic getSnapshotForInterval(Iterator it,
Date start, Date end) throws IllegalArgumentException
{
long total = 0;
int count = 0;
Date first = start, last = end;
while (it.hasNext()) {
LongStatistic s = (LongStatistic) it.next();
if (start != null) {
if (s.getStart().compareTo(start) < 0)
continue;
}
if (first == null)
first = s.getStart();
if (end != null) {
if (s.getEnd().compareTo(end) > 0)
continue;
}
last = s.getEnd();
total += s.getLongValue().longValue();
count++;
}
if (count == 0)
throw new IllegalArgumentException("Cannot derive a " +
"snapshot from an empty iterator");
return (new LongStatistic(new Long(total / count), first,
last));
}
}
/**
* A statistic of type UnsignedInt64.
*/
final class UnsignedInt64Statistic extends AbstractStatistic
implements AggregateStatistic
{
/**
* Constructor.
*
* @param value The value of this statistic.
* @param start The start of the interval over which this
* statistic is representative.
* @param end The end of the interval over which this
* statistic is representative.
*/
public UnsignedInt64Statistic(UnsignedInt64 value, Date start,
Date end)
{
super(value, start, end);
}
public Double getDoubleValue()
{
return (new Double(((UnsignedInt64) getValue()).longValue()));
}
public Long getLongValue()
{
return (new Long(((UnsignedInt64) getValue()).longValue()));
}
public UnsignedInt64 getUnsignedInt64Value()
{
return ((UnsignedInt64) getValue());
}
public AggregateStatistic add(AggregateStatistic o)
{
UnsignedInt64 v1 = getUnsignedInt64Value();
UnsignedInt64 v2 = o.getUnsignedInt64Value();
return (new UnsignedInt64Statistic(
new UnsignedInt64(v1.add(v2)),
getStart(), getEnd()));
}
public AggregateStatistic subtract(AggregateStatistic o)
{
UnsignedInt64 v1 = getUnsignedInt64Value();
UnsignedInt64 v2 = o.getUnsignedInt64Value();
return (new UnsignedInt64Statistic(
new UnsignedInt64(v1.subtract(v2)),
getStart(), getEnd()));
}
public AggregateStatistic getSnapshotForInterval(Iterator it,
Date start, Date end) throws IllegalArgumentException
{
BigInteger total = new BigInteger("0");
int count = 0;
Date first = start, last = end;
while (it.hasNext()) {
UnsignedInt64Statistic s = (UnsignedInt64Statistic)
it.next();
if (start != null) {
if (s.getStart().compareTo(start) < 0)
continue;
}
if (first == null)
first = s.getStart();
if (end != null) {
if (s.getEnd().compareTo(end) > 0)
continue;
}
last = s.getEnd();
total = total.add(s.getUnsignedInt64Value());
count++;
}
if (count == 0)
throw new IllegalArgumentException("Cannot derive a " +
"snapshot from an empty iterator");
return (new UnsignedInt64Statistic(
new UnsignedInt64(total.divide(new BigInteger(
Integer.toString(count)))), first, last));
}
}