All Downloads are FREE. Search and download functionalities are using the official Maven repository.

umontreal.ssj.simevents.ListWithStat Maven / Gradle / Ivy

There is a newer version: 3.3.2
Show newest version
/*
 * Class:        ListWithStat
 * Description:  Implements a list with integrated statistical probes to
                 provide automatic collection of statistics on the sojourn
                 times of objects in the list and on the size of the list
 * Environment:  Java
 * Software:     SSJ
 * Copyright (C) 2001  Pierre L'Ecuyer and Universite de Montreal
 * Organization: DIRO, Universite de Montreal
 * @author
 * @since
 *
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package umontreal.ssj.simevents;
import java.util.Collection;
import java.util.List;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import umontreal.ssj.stat.Tally;
import umontreal.ssj.util.TransformingList;
import umontreal.ssj.util.PrintfFormat;

/**
 * Implements a list with integrated statistical probes to provide automatic
 * collection of statistics on the sojourn times of objects in the list and
 * on the size of the list as a function of time given by a simulator. The
 * automatic statistical collection can be enabled or disabled for each list,
 * to reduce overhead. This class extends
 * @ref umontreal.ssj.util.TransformingList and transforms elements into
 * nodes associating insertion times with elements.
 *
 * 
*/ public class ListWithStat extends TransformingList> { private boolean stats; // true si on a appele setStatCollecting private double initTime; // temps de la derniere initialisation private Accumulate blockSize; //block stat. sur la longueur de la liste private Tally blockSojourn; // block stat. sur les durees de sejour private String name; private Simulator sim; /** * Constructs a new list with internal data structure using the default * simulator and implemented by `nodeList`. The given list is cleared * for the constructed list to be initially empty. */ public ListWithStat (List> nodeList) { super (nodeList); nodeList.clear(); sim = Simulator.getDefaultSimulator(); stats = false; } /** * Constructs a new list with internal data structure implemented by * `nodeList`. The given list is cleared for the constructed list to be * initially empty. * @param nodeList the list containing the nodes */ public ListWithStat (Simulator inSim, List> nodeList) { super (nodeList); if (inSim == null || nodeList == null) throw new NullPointerException(); nodeList.clear(); sim = inSim; stats = false; } /** * Constructs a list containing the elements of the specified * collection, whose elements are stored into `nodeList` and using the * default simulator. * @param nodeList the list containing the nodes * @param c collection containing elements to fill in this * list with */ public ListWithStat (List> nodeList, Collection c) { this (Simulator.getDefaultSimulator(), nodeList); addAll (c); } /** * Constructs a list containing the elements of the specified * collection, whose elements are stored into `nodeList`. * @param inSim simulator associate to the current variable * @param nodeList the list containing the nodes * @param c collection containing elements to fill in this * list with */ public ListWithStat (Simulator inSim, List> nodeList, Collection c) { this (inSim, nodeList); addAll (c); } /** * Constructs a new list with name `name`, internal list `nodeList`, * and using the default simulator. This name can be used to identify * the list in traces and reports. The given list is cleared for the * constructed list to be initially empty. * @param nodeList the list containing the nodes * @param name name for the list object */ public ListWithStat (List> nodeList, String name) { this (Simulator.getDefaultSimulator(), nodeList); this.name = name; } /** * Constructs a new list with name `name`, and internal list * `nodeList`. This name can be used to identify the list in traces and * reports. The given list is cleared for the constructed list to be * initially empty. * @param inSim simulator associate to the current variable * @param nodeList the list containing the nodes * @param name name for the list object */ public ListWithStat (Simulator inSim, List> nodeList, String name) { this (inSim, nodeList); this.name = name; } /** * Constructs a new list containing the elements of the specified * collection `c`, with name `name`, internal list `nodeList`, and * using the default simulator. This name can be used to identify the * list in traces and reports. * @param nodeList the list containing the nodes * @param c collection containing elements to fill in this * list with * @param name name for the list object */ public ListWithStat (List> nodeList, Collection c, String name) { this (Simulator.getDefaultSimulator(), nodeList); this.name = name; addAll (c); } /** * Constructs a new list containing the elements of the specified * collection `c`, with name `name`, and internal list `nodeList`. This * name can be used to identify the list in traces and reports. * @param inSim simulator associate to the current variable * @param nodeList the list containing the nodes * @param c collection containing elements to fill in this * list with * @param name name for the list object */ public ListWithStat (Simulator inSim, List> nodeList, Collection c, String name) { this (inSim, nodeList); this.name = name; addAll (c); } public E convertFromInnerType (Node node) { return node.getElement(); } public Node convertToInnerType (E element) { return new Node (element, sim.time()); } /** * Returns the simulator associated with this list. * @return the simulator associated with this list */ public Simulator simulator() { return sim; } /** * Sets the simulator associated with this list. This list should be * cleared after this method is called. * @param sim the simulator of this list */ public void setSimulator(Simulator sim) { if (sim == null) throw new NullPointerException(); this.sim = sim; if (blockSize != null) blockSize.setSimulator (sim); } @Override public void clear() { if (stats) initStat(); super.clear(); } @Override public void add (int index, E obj) { super.add (index, obj); if (stats) blockSize.update (size()); } @Override public E remove (int index) { Node node = getInnerList().get (index); if (stats) blockSojourn.add (sim.time() - node.getInsertionTime()); E e = super.remove (index); if (stats) blockSize.update (size()); return e; } @Override public Iterator iterator() { return new IteratorWithStat (getInnerList().iterator()); } @Override public ListIterator listIterator() { return new ListIteratorWithStat (getInnerList().listIterator()); } @Override public ListIterator listIterator (int index) { return new ListIteratorWithStat (getInnerList().listIterator (index)); } @Override public E set (int index, E element) { Node oldNode = getInnerList().get (index); E oldElement = oldNode.getElement(); boolean equal; if (oldElement == null || element == null) equal = oldElement == element; else equal = oldElement.equals (element); if (equal) { getInnerList().set (index, new Node (element, oldNode.getInsertionTime())); return oldElement; } else { if (stats) blockSojourn.add (sim.time() - oldNode.getInsertionTime()); getInnerList().set (index, new Node (element, sim.time())); return oldElement; } } private class IteratorWithStat implements Iterator { private Iterator> itr; private Node lastRet; public IteratorWithStat (Iterator> itr) { this.itr = itr; } public boolean hasNext() { return itr.hasNext(); } public E next() { lastRet = itr.next(); return lastRet.getElement(); } public void remove() { itr.remove(); if (stats) { blockSize.update (size()); blockSojourn.add (sim.time() - lastRet.getInsertionTime()); } lastRet = null; } } private class ListIteratorWithStat implements ListIterator { private ListIterator> itr; private Node lastRet; public ListIteratorWithStat (ListIterator> itr) { this.itr = itr; } public void add (E o) { itr.add (new Node (o, sim.time())); lastRet = null; if (stats) blockSize.update (size()); } public boolean hasNext() { return itr.hasNext(); } public boolean hasPrevious() { return itr.hasPrevious(); } public E next() { lastRet = itr.next(); return lastRet.getElement(); } public int nextIndex() { return itr.nextIndex(); } public E previous() { lastRet = itr.previous(); return lastRet.getElement(); } public int previousIndex() { return itr.previousIndex(); } public void remove() { itr.remove(); if (stats) { blockSize.update (size()); blockSojourn.add (sim.time() - lastRet.getInsertionTime()); } lastRet = null; } public void set (E element) { if (lastRet == null) throw new NoSuchElementException(); Node oldNode = lastRet; E oldElement = oldNode.getElement(); boolean equal; if (oldElement == null || element == null) equal = oldElement == element; else equal = oldElement.equals (element); if (equal) { lastRet = new Node (element, oldNode.getInsertionTime()); itr.set (lastRet); } else { if (stats) blockSojourn.add (sim.time() - oldNode.getInsertionTime()); lastRet = new Node (element, sim.time()); itr.set (lastRet); } } } /** * @name Statistic collection methods * @{ */ /** * Returns `true` if the list collects statistics about its size and * sojourn times of elements, and `false` otherwise. By default, * statistical collecting is turned off. * @return the status of statistical collecting */ public boolean getStatCollecting() { return stats; } /** * Starts or stops collecting statistics on this list. If the statistical * collection is turned ON, the method creates two statistical probes if * they do not exist yet. The first one, of the class @ref Accumulate, * measures the evolution of the size of the list as a function of time. * It can be accessed by the method #statSize. The second one, of the * class @ref umontreal.ssj.stat.Tally and accessible via #statSojourn, * samples the sojourn times in the list of the objects removed during * the observation period, i.e., between the last initialization time of * this statistical probe and the current time. The method automatically * calls #initStat to initialize these two probes. When this method is * used, it is normally invoked immediately after calling the constructor * of the list. * @exception IllegalStateException if the statistical collection is in * the same state as the caller requires */ public void setStatCollecting (boolean b) { if (b && !stats) { if (blockSize == null) blockSize = new Accumulate(sim, "List Size " + name); if (blockSojourn == null) blockSojourn = new Tally("List Sojourn " + name); blockSize.update (size()); stats = true; initStat(); } else stats = false; } /** * Reinitializes the two statistical probes created by * {@link #setStatCollecting() setStatCollecting(true)} and makes an * update for the probe on the list size. * @exception IllegalStateException if the statistical collection is * disabled */ public void initStat() { if (!stats) throw new IllegalStateException("initStat for a list that did not call setStatCollecting (true)."); blockSize.init(); blockSojourn.init(); blockSize.update (size()); initTime = sim.time(); } /** * Returns the last simulation time #initStat was called. * @return the last simulation time #initStat was called */ public double getInitTime() { return initTime; } /** * Returns the statistical probe on the evolution of the size of the * list as a function of the simulation time. This probe exists only if * {@link #setStatCollecting() setStatCollecting(true)} has been called * for this list. * @return the statistical probe on the evolution of the size of the * list */ public Accumulate statSize() { return blockSize; } /** * Returns the statistical probe on the sojourn times of the objects in * the list. This probe exists only if {@link #setStatCollecting() * setStatCollecting(true)} has been called for this list. * @return the statistical probe for the sojourn times in the list */ public Tally statSojourn() { return blockSojourn; } /** * Returns a string containing a statistical report on the list, * provided that {@link #setStatCollecting() setStatCollecting(true)} * has been called before for this list. Even If #setStatCollecting * was called with `false` afterward, the report will be made for the * collected observations. If the probes do not exist, i.e., * #setStatCollecting was never called for this object, an illegal * state exception will be thrown. * @return a statistical report, represented as a string * * @exception IllegalStateException if no statistical probes exist */ public String report() { if (blockSojourn == null || blockSize == null) throw new IllegalStateException ("Calling report when no statistics were collected"); PrintfFormat str = new PrintfFormat(); str.append (PrintfFormat.NEWLINE + "REPORT ON LIST : ").append (name).append (PrintfFormat.NEWLINE); str.append (" From time: ").append (7, 2, 2, initTime); str.append (" to time: ").append (10, 2, 2, sim.time()); str.append (" min max average "); str.append ("standard dev. nb. Obs"); str.append (" Size "); str.append (9, (int)(blockSize.min()+0.5)); str.append (11, (int)(blockSize.max()+0.5)); str.append (14, 3, 2, blockSize.average()).append(PrintfFormat.NEWLINE); str.append (" Sojourn "); str.append ( 12, 3, 2, blockSojourn.min()).append (" "); str.append (10, 3, 2, blockSojourn.max()).append (" "); str.append (10, 3, 2, blockSojourn.average()).append (" "); str.append (10, 3, 2, blockSojourn.standardDeviation()).append (" "); str.append (11, blockSojourn.numberObs()).append (PrintfFormat.NEWLINE); return str.toString(); } /** * Returns the name associated to this list, or `null` if no name was * assigned. * @return the name associated to this list */ public String getName() { return name; } /** * @} */ /** * @name Inner class * @{ */ /** * Represents a node that can be part of a list with statistical * collecting. */ public static class Node { private E element; private double insertionTime; /** * @} */ /** * Constructs a new node containing element `element` inserted * into the list at time `insertionTime`. * @param element the element to add into this new node * @param insertionTime the insertion time of the element */ public Node (E element, double insertionTime) { this.element = element; this.insertionTime = insertionTime; } /** * Returns the element stored into this node. * @return the element into this node */ public E getElement() { return element; } /** * Returns the insertion time of the element in this node. * @return the insertion time of the element */ public double getInsertionTime() { return insertionTime; } public String toString() { String str = element == null ? "null" : element.toString(); str += " (inserted at time " + insertionTime + ")"; return str; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy