package umontreal.iro.lecuyer.stat.list;

import umontreal.iro.lecuyer.util.PrintfFormat;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.RandomAccess;
import umontreal.iro.lecuyer.stat.StatProbe;


/**
 * Represents a list of statistical probes that
 * can be managed simultaneously.
 * Each element of this list is a {@link umontreal.iro.lecuyer.stat.StatProbe StatProbe}
 * instance which can be obtained and manipulated.
 * 
 * 

* When constructing a list of statistical probes, one specifies the * concrete subclass of the {@link StatProbe} objects in it. * One then creates an empty list of probes, and fills * it with statistical probes. * If the list is not intended to be modified, one can then use the * {@link #setUnmodifiable setUnmodifiable} to prevent any change in the contents of * the list. * *

* Each list of statistical probes can have a global name describing * the contents of its elements, and local names associated with each * individual probe. For example, a list of statistical probes for * the waiting times can have the global name Waiting times * while the individual probes have local names type 1, * type 2, etc. These names are used for formatting reports. * *

* Facilities are provided to fill arrays with sums, averages, etc. obtained * from the individual statistical probes. * Methods are also provided to manipulate the contents of the list. * However, one should always call init immediately after adding or * removing statistical probes in the list. * */ public class ListOfStatProbes implements Cloneable, List, RandomAccess { // probes must implement RandomAccess, otherwise this class must not implement RandomAccess. private List probes; private List listeners = new ArrayList(); protected boolean collect = true; protected boolean broadcast = false; protected String name; /** * Constructs an empty list of statistical probes. * */ public ListOfStatProbes() { probes = new ArrayList(); } /** * Constructs an empty list of statistical probes with * name name. * * @param name the name of the new list. * * */ public ListOfStatProbes (String name) { probes = new ArrayList(); this.name = name; } /** * Returns the global name of this list of statistical probes. * * @return the global name of the list. * */ public String getName() { return name; } /** * Sets the global name of this list to name. * * @param name the new global name of the list. * * */ public void setName (String name) { this.name = name; } /** * Determines if this list of statistical probes is * modifiable, i.e., if probes can be added or removed. * Any list of statistical probes is modifiable by default, until one calls the * {@link #setUnmodifiable setUnmodifiable} method. * */ public boolean isModifiable() { return probes instanceof ArrayList; } /** * Forbids any future modification to this list of * statistical probes. * After this method is called, any attempt to modify the list results * in an exception. * Setting a list unmodifiable can be useful if some data structures * are defined depending on the probes in the list. * */ public void setUnmodifiable() { if (isModifiable()) probes = Collections.unmodifiableList (probes); } /** * Initializes this list of statistical probes by calling * {@link umontreal.iro.lecuyer.stat.StatProbe#init(()) init} on each element. * */ public void init() { for (StatProbe probe : probes) { if (probe != null) probe.init(); } } /** * For each probe in the list, computes * the sum by calling {@link umontreal.iro.lecuyer.stat.StatProbe#sum(()) sum}, and stores * the results into the array s. This method throws an exception if the size of s * mismatches with the size of the list. * * @param s the array to be filled with sums. * * @exception NullPointerException if s is null. * * @exception IllegalArgumentException if s.length * does not correspond to {@link #size(()) size}. * * */ public void sum (double[] s) { if (s.length != size()) throw new IllegalArgumentException ("Invalid length of the given array: given length is " + s.length + ", required length is " + size()); int i = 0; for (StatProbe probe : probes) s[i++] = probe == null ? Double.NaN : probe.sum(); } /** * For each probe in this list, computes * the average by calling {@link umontreal.iro.lecuyer.stat.StatProbe#average(()) average}, and stores * the results into the array a. This method throws an exception if the size of s * mismatches with the size of the list. * * @param a the array to be filled with averages. * * @exception NullPointerException if a is null. * * @exception IllegalArgumentException if a.length * does not correspond to {@link #size(()) size}. * * */ public void average (double[] a) { if (a.length != size()) throw new IllegalArgumentException ("Invalid length of the given array: given length is " + a.length + ", required length is " + size()); int i = 0; for (StatProbe probe : probes) a[i++] = probe == null ? Double.NaN : probe.average(); } /** * Determines if this list of statistical probes * is collecting values. Each probe of the list could or could not * be collecting values. The default is true. * * @return the status of statistical collecting. * */ public boolean isCollecting() { return collect; } /** * Sets the status of the statistical collecting * mechanism to c. A true value * turns statistical collecting ON, a false * value turns it OFF. * * @param c the status of statistical collecting. * * */ public void setCollecting (boolean c) { collect = c; } /** * Determines if this list of statistical probes * is broadcasting observations to registered observers. * The default is false. * * @return the status of broadcasting. * */ public boolean isBroadcasting() { return broadcast; } /** * Sets the status of the observation broadcasting * mechanism to b. A true value * turns broadcasting ON, a false * value turns it OFF. * * @param b the status of broadcasting. * * */ public void setBroadcasting (boolean b) { broadcast = b; } /** * Adds the observation listener l to the list of observers of * this list of statistical probes. * * @param l the new observation listener. * * @exception NullPointerException if l is null. * * */ public void addArrayOfObservationListener (ArrayOfObservationListener l) { if (l == null) throw new NullPointerException(); if (!listeners.contains (l)) listeners.add (l); } /** * Removes the observation listener l from the list of observers of * this list of statistical probes. * * @param l the observation listener to be deleted. * * */ public void removeArrayOfObservationListener (ArrayOfObservationListener l) { listeners.remove (l); } /** * Removes all observation listeners from the list of observers of * this list of statistical probes. * */ public void clearArrayOfObservationListeners() { listeners.clear(); } /** * Notifies the observation x to all registered observers * if broadcasting is ON. Otherwise, does nothing. * */ public void notifyListeners (double[] x) { if (!broadcast) return; // We could also use the enhanced for loop here, but this is less efficient. final int nl = listeners.size(); for (int i = 0; i < nl; i++) listeners.get (i).newArrayOfObservations (this, x); } /** * Formats a report for each probe in the list of * statistical probes. The returned string is constructed by * using StatProbe.report (getName(), this). * * @return the report formatted as a string. * */ public String report() { return StatProbe.report (name, this); } /** * Clones this object. This makes a shallow copy * of this list, i.e., this does not clone all the probes in the list. * The created clone is modifiable, even if the original list is unmodifiable. * */ public ListOfStatProbes clone() { ListOfStatProbes sa; try { sa = (ListOfStatProbes)super.clone(); } catch (CloneNotSupportedException cne) { throw new IllegalStateException ("CloneNotSupportedException for a class implementing Cloneable"); } if (probes != null) sa.probes = new ArrayList (probes); return sa; } public boolean add (E o) { return probes.add (o); } public void add (int index, E o) { probes.add (index, o); } public boolean addAll (Collection c) { return probes.addAll (c); } public boolean addAll (int index, Collection c) { return probes.addAll (index, c); } public void clear() { probes.clear(); } public boolean contains (Object o) { return probes.contains (o); } public boolean containsAll (Collection c) { return probes.containsAll (c); } public boolean equals (Object o) { return probes.equals (o); } public E get (int index) { return probes.get (index); } public int hashCode() { return probes.hashCode(); } public int indexOf (Object o) { return probes.indexOf (o); } public boolean isEmpty() { return probes.isEmpty(); } public Iterator iterator() { return probes.iterator(); } public int lastIndexOf (Object o) { return probes.lastIndexOf (o); } public ListIterator listIterator() { return probes.listIterator(); } public ListIterator listIterator (int index) { return probes.listIterator(); } public E remove (int index) { return probes.remove (index); } public boolean remove (Object o) { return probes.remove (o); } public boolean removeAll (Collection c) { return probes.removeAll (c); } public boolean retainAll (Collection c) { return probes.retainAll (c); } public E set (int index, E element) { return probes.set (index, element); } public int size() { return probes.size(); } public List subList (int fromIndex, int toIndex) { return probes.subList (fromIndex, toIndex); } public Object[] toArray() { return probes.toArray(); } public T[] toArray (T[] a) { return probes.toArray (a); } }

Ads help maintain this website.