Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: desmoj/QueueBased.java


1   package desmoj;
2   
3   /**
4    * Provides the typical statistics common to all ModelComponents based on
5    * Queues. It is set abstract to prevent users to use it straight without
6    * deriving a class first because it only provides the functionality
7    * for statistical data extraction, not the functionality for actually
8    * queueing Entities.
9    * The statistical values provided are the queue's length and its
10   * elements' waiting times with minimum, maximum, mean and 
11   * standard deviation for each.
12   * This class should be used when any type of ModelComponent using Queues
13   * is created. In combination with class QueueList an automatic insert/remove
14   * mechanism including search functionality with condition checking
15   * can be set up within a few lines of code. It also provides full
16   * automatic statistical data about the Queue used.
17   * @author Tim Lechler
18   * @author modified by Soenke Claassen
19   * @see QueueList
20   *
21   * @version DESMO-J,  Ver. 1.5 copyright (c) 2001 licensed under GNU GPL
22   */
23  public abstract class QueueBased extends desmoj.Reportable {
24  
25    /**
26    * Represents the value returned if for a given statistics no valid value
27    * can be returned.
28    */
29    public static final double UNDEFINED = -1;
30  
31    /**
32    * Displays the current number of objects waiting inside the queue.
33    */
34    private int currentLength;
35  
36    /**
37    * Flag for letting the underlying queue implementation (<code>QueueList</code>)
38    * show own warnings (<code>true</code>) or suppressing
39    * them (<code>false</code>).
40    * Is <code>false</code> by default but can be set to <code>true</code> for 
41    * debugging purposes
42    */
43    private boolean qImpWarnings;
44  
45    /**
46    * Displays the minimum number of objects that have been waiting inside 
47    * the queue since the last reset.
48    */
49    private int minimumLength;
50  
51    /**
52    * Displays the maximum number of objects that have been waiting inside 
53    * the queue since the last reset.
54    */
55    private int maximumLength;
56  
57    /**
58    * Displays the number of objects that have passed the queue without
59    * waiting time. Thus the name "zeros" for zero waiting time.
60    * Value is valid for the span of time since the last reset.
61    */
62    private long zeros;
63  
64    /**
65    * Displays the sum of the queue length weighted over the time each
66    * object spent waiting in the queue.
67    * Value is valid for the span of time since the last reset.
68    */
69    private double wSumLength;
70  
71    /**
72    * Displays the squares of the sums of the queue length weighted over
73    * the time each object spent waiting in the queue.
74    * Value is valid for the span of time since the last reset.
75    */
76    private double wSumSquareLength;
77  
78    /**
79    * The point in simulation time the queue was last accessed.
80    * Value is valid for the span of time since the last reset.
81    */
82    private SimTime lastAcc;
83  
84    /**
85    * The point in simulation time the queue's minimum length was recorded.
86    * Value is valid for the span of time since the last reset.
87    */
88    private SimTime minimumLengthAt;
89  
90    /**
91    * The point in simulation time the queue's maximum length was recorded.
92    * Value is valid for the span of time since the last reset.
93    */
94    private SimTime maximumLengthAt;
95  
96    /**
97    * The maximum time an object inside the queue spent waiting.
98    * Value is valid for the span of time since the last reset.
99    */
100   private SimTime maximumWaitTime;
101 
102   /**
103   * The point in simulation time the maximum waiting time of an object inside
104   * the queue was recorded at.
105   * Value is valid for the span of time since the last reset.
106   */
107   private SimTime maximumWaitTimeAt;
108 
109   /**
110   * The sum of the waiting times spent by all objects that have passed through
111   * the queue.
112   * Value is valid for the span of time since the last reset.
113   */
114   private SimTime sumWaitTime;
115 
116   /**
117   * The square of the sums of the waiting times spent by all objects that 
118   * have passed through the queue.
119   * Value is valid for the span of time since the last reset.
120   */
121   private SimTime sumSquareWaitTime;
122 
123  /**
124   * Defining a constant for the service discipline of the underlying queue.
125   * FIFO = First In First Out.
126   */
127   public final static int FIFO = 0;
128 
129  /**
130   * Defining a constant for the service discipline of the underlying queue.
131   * LIFO = Last In First Out.
132   */
133   public final static int LIFO = 1;
134 
135  /**
136   * Represents the maximum number of entities in the queue (default is 
137   * unlimited capacity).
138   */
139   protected int queueLimit = Integer.MAX_VALUE;
140 
141  /**
142   * An array representing the possible queueing strategies as implemented
143   * in the QueueListFifo and QueueListLifo classes. If new queueing
144   * strategies are added later on, they must be declared here also.
145   */
146   protected java.lang.Class[] queueingStrategy = 
147   new Class[]  {desmoj.QueueListFifo.class, desmoj.QueueListLifo.class};
148 
149 /**
150  * Creates a queuebased object and initializes all statistical counters.
151  * If this standard constructor is used a queue with Fifo sort order and
152  * no limited capacity will be created.
153  * @param owner desmoj.Model : The model it belongs to
154  * @param name java.lang.String : The name for this QueueBased object
155  * @param showInReport boolean : Flag if values are shown in report
156  * @param showInTrace boolean : Flag if QueueBased writes trace messages
157  */
158 public QueueBased(desmoj.Model owner, String name, 
159                        boolean showInReport, boolean showInTrace) {
160                        
161   super(owner, name, showInReport, showInTrace);  // create reportable
162   
163   // initialize all statistics
164   currentLength = 0;              // no one in here at starting time
165   lastAcc = currentTime();        // time of last access is now
166   minimumLength = currentLength;  
167   maximumLength = currentLength;
168   zeros = 0;
169   wSumLength = 0;
170   wSumSquareLength = 0;
171   sumWaitTime = sumSquareWaitTime  // reset points of simulation time
172               = maximumWaitTime
173               = maximumWaitTimeAt
174               = minimumLengthAt
175               = maximumLengthAt = new SimTime(0);
176         
177   qImpWarnings = false;    // no queue implementation warnings
178 
179 }
180 /**
181  * Updates the statistics when a new element is inserted into the underlying
182  * queue.
183  * Note that this method must always be called whenever an insertion is
184  * made. If class <code>QueueList</code> is used in combination with a
185  * queuebased, this method gets called automatically whenever a new entity 
186  * is inserted.
187  * @see QueueList
188  * @see QueueListFifo
189  * @see QueueListLifo
190  */
191 protected void addItem() {
192   
193   updateStatistics();
194   currentLength++;
195   
196   if ( currentLength > maximumLength ) {  // do we have a new record high?
197     maximumLength = currentLength;        // yes, store the record length
198     maximumLengthAt = currentTime();      // and write down the time for it
199   }
200   
201 }
202 /**
203  * Returns the average length of the underlying queue since the last reset.
204  * Current length of that queue will be returned, if the time span since
205  * the last reset is smaller than the smallest distinguishable timespan
206  * epsilon.
207  * @return double : The average queue length since last reset or current length
208  * of queue if no distinguishable periode of time has passed
209  */
210 public double averageLength() {
211   
212   SimTime now = currentTime();                      // store current time
213   SimTime deltaTime = SimTime.diff(now, resetAt());  // time since last reset
214   
215   // calculate the average length
216   double avgLength = (wSumLength + 
217             ( currentLength *  (now.getTimeValue() - lastAcc.getTimeValue())))
218           / deltaTime.getTimeValue();  // not nice to read, but it really does 
219                                       // calculate the average!!!
220   
221   // round the average length
222   double rndAvgLength = java.lang.Math.rint( 100000 * avgLength )
223                                             / 100000;  
224   // return the rounded average length                                     
225   if ( SimTime.isSmaller(deltaTime, epsilon()))      // is delta too small?
226     return UNDEFINED;                                // value is not defined
227   else 
228   {
229     return rndAvgLength;  
230   }
231 }
232 /**
233  * Returns the average waiting time of all objects who have exited the queue.
234  * Value is valid for the time span since the last reset.
235  * Returns 0 (zero) if no objects have exited the queue after the last reset.
236  * @return SimTime : Average waiting time of all objects since last reset
237  * or 0 if no objects have exited the queue 
238  */
239 public SimTime averageWaitTime() {
240   
241   double obs = getObservations();    // get and store number of observations
242   
243   // calculate the resulting average wait time and round it
244   double avgWaitTime = java.lang.Math.rint(100000 * 
245                                                 (sumWaitTime.getTimeValue() 
246                                                   / obs) 
247                                             )
248                                           / 100000;  
249   // return rounded average wait time
250   if ( obs > 0 ) return new SimTime( avgWaitTime );
251   else return new SimTime(0);      // no observations -> zero SimTime value
252   
253 }
254 /**
255  * Creates the reporter qualified to produce a report about a class
256  * that has been derived from queuebased.
257  * This method is declared abstract since no real queuebased is supposed to be
258  * instantiated and thus no rReporter can be defined here.
259  * Implement this method in the subclasses of queuebased such as in class
260  * Queue.
261  * @see Queue
262  */
263 public abstract desmoj.report.Reporter createReporter() ;
264 /**
265  * Updates the statistics when a new element is exiting the underlying queue.
266  * Note that this method must always be called whenever an object is
267  * taken from the queue. The simulation time parameter given provides the
268  * statistics with the information about the point of time the exiting object
269  * had enterd this queue. This is needed to calculate the waiting times.
270  * If a queuebased is used in conjunction with class queuelist,
271  * this method is automatically called whenever an entity is taken from
272  * the queuelist to keep track of 
273  * @param entryTime SimTime : Point of simulation time that the object 
274  * now exiting the queuebased had entered it
275  */
276 protected void deleteItem(SimTime entryTime) {
277   
278   updateStatistics();
279   SimTime now  = currentTime(); // Store the actual simulation time
280   SimTime waitTime = SimTime.diff(now, entryTime);  // time waited in queue
281   sumWaitTime = SimTime.add(sumWaitTime, waitTime);  // update sum
282   
283   // calculate square of waitTimes and
284   sumSquareWaitTime = new SimTime( sumSquareWaitTime.getTimeValue() 
285                         + ( waitTime.getTimeValue() * waitTime.getTimeValue())) ;
286 
287   if ( SimTime.isLarger( waitTime, maximumWaitTime ) )  // do we have a new waiting record?
288   {
289     maximumWaitTime = waitTime;      // store new record
290     maximumWaitTimeAt = now;        // and the moment it happened
291   }
292 
293   if ( SimTime.isSmaller( waitTime, epsilon() ) ) {  // no recognizable timespan
294     zeros++;
295   }
296   
297   if ( currentLength <= 0 ) {
298     sendWarning("Inconsistent Qeueue length",
299                 "QueueBased : "
300                   +getName()+" Method: void activateAfter(SimTime dt)",
301                 "Error in Statistic operations of Queues",
302                 "Report information to DESMO-J designer Tim Lechler via eMail : "+
303                 "1lechler@informatik.uni-hamburg.de");
304     return;  // bad stuff ?? We got more objects in the queue than registered!!!
305   }
306   
307   currentLength--;
308   
309   if ( currentLength < minimumLength ) {
310     minimumLength = currentLength;
311   }
312   
313   incrementObservations();
314 }
315 /**
316  * Returns the maximum possible number of entities in the underlying queue.
317  * @return int : the maximum number of entities in the queue.
318  */
319 public int getQueueLimit() {
320   return queueLimit;
321 }
322 /**
323  * Returns the current length of the underlying queue.
324  * @return int : The current queue length
325  */
326 public int length() {
327   
328   return currentLength;
329   
330 }
331 /**
332  * Returns the maximum length of the underlying queue since the last reset.
333  * @return int : The maximum queue length since last reset
334  */
335 public int maxLength() {
336   
337   return maximumLength;
338   
339 }
340 /**
341  * Returns the point of simulation time with the maximum number of objects
342  * waiting inside the underlying queue.
343  * The value is valid for the period since the last reset.
344  * @return desmoj.SimTime : Point of time with maximum queue length since last
345  * reset
346  */
347 public SimTime maxLengthAt() {
348   
349   return maximumLengthAt;
350   
351 }
352 /**
353  * Returns the maximum duration in simulation time that an object has
354  * spent waiting inside the underlying queue.
355  * The value is valid for the period since the last reset.
356  * @return desmoj.SimTime : Longest waiting time of an object in the queue
357  * since last reset
358  */
359 public SimTime maxWaitTime() {
360   
361   return maximumWaitTime;
362   
363 }
364 /**
365  * Returns the point of simulation time when the object with the maximum
366  * waiting time exited the underlying queue.
367  * The value is valid for the period since the last reset.
368  * @return desmoj.SimTime : The point of simulation time when the object with the maximum
369  * waiting time exited the queue
370  */
371 public SimTime maxWaitTimeAt() {
372   
373   return maximumWaitTimeAt;
374   
375 }
376 /**
377  * Returns the minimumn length of the underlying queue since the last reset.
378  * @return int : The minimum queue length since last reset
379  */
380 public int minLength() {
381   
382   return minimumLength;
383   
384 }
385 /**
386  * Returns the point of simulation time with the minimum number of objects
387  * waiting inside the underlying queue.
388  * The value is valid for the period since the last reset.
389  * @return desmoj.SimTime : Point of time with minimum queue length since last
390  * reset
391  */
392 public SimTime minLengthAt() {
393   
394   return minimumLengthAt;
395   
396 }
397 /**
398  * Returns a boolean flag telling if the underlying queue implementation
399  * should issue own warnings or not. The warnings from the queue implementation
400  *(<code>QueueList</code>) are needed for debugging purposes. 
401  * @return boolean : Is <code>true</code> if the underlying queue
402  * implementation should issue warnings, <code>false</code> otherwise
403  */
404 boolean qImpWarn() {
405   
406   return qImpWarnings;
407   
408 }
409 /**
410  * Resets all statistical counters to their default values. The mininum and
411  * maximum length of the queue are set to the current number of queued objects.
412  */
413 public void reset() {
414   
415   super.reset();      // reset of Reportable
416   
417   lastAcc = currentTime();        // time of last access is now
418   minimumLength = currentLength;  
419   maximumLength = currentLength;
420   zeros = 0;
421   wSumLength = 0;
422   wSumSquareLength = 0;
423   sumWaitTime = sumSquareWaitTime  // reset points of simulation time
424               = maximumWaitTime
425               = maximumWaitTimeAt
426               = minimumLengthAt
427               = maximumLengthAt = new SimTime(0);
428               
429 }
430 /**
431  * Method switches on warnings issued from the underlying queue
432  * implementation if parameter given is <code>true</code>.
433  * Warnings are suppressed if <code>false</code> is given.
434  * This method is used for internal debugging only.
435  * @param warnFlag boolean : <code>true</code> switches warnings on,
436  * <code>false</code> switches warnings off
437  */
438 public void setQueueImpWarning(boolean warnFlag) {
439 
440   qImpWarnings = warnFlag;
441   
442 }
443 /**
444  * Returns the standard deviation of the queue's length. 
445  * Value is weighted over time.
446  * @return double : The standard deviation for the queue's length weighted over
447  * time
448  */
449 public double stdDevLength() {
450   
451   SimTime now = currentTime();                      // store current time
452   SimTime deltaTime = SimTime.diff(now, resetAt());  // time since last reset
453   
454   if ( SimTime.isSmaller(deltaTime, epsilon()))      // is delta too small?
455     return UNDEFINED;                                        // no valid data
456   else {
457     double len = (double)currentLength;        // store and convert length
458     double mean = averageLength();            // get mean for queuelength
459     SimTime span = SimTime.diff(now, lastAcc);  // time span since last access
460     
461     return java.lang.Math.sqrt(
462             java.lang.Math.abs(
463               (wSumSquareLength + (len * len * span.getTimeValue()))
464                 / deltaTime.getTimeValue() - ( mean * mean )));
465   }
466   
467 }
468 /**
469  * Returns the standard deviation of the queue's objects waiting times. 
470  * @return double : The standard deviation for the queue's objects waiting
471  * times
472  */
473 public SimTime stdDevWaitTime() {
474   
475   if ( getObservations() > 0 ) {
476     double mean = averageWaitTime().getTimeValue();  // get avrg time
477     double obs  = (double)getObservations();        // number of obs exited
478     
479     return new SimTime ( java.lang.Math.sqrt(        // not nice but functual
480                          java.lang.Math.abs(
481                           ((obs * sumSquareWaitTime.getTimeValue())
482                           - ( mean * mean ))
483                            / ( obs * (obs - 1.0 ) ))) );  // as simple as that
484   }
485   else return new SimTime(0);    // no observations -> no values
486   
487 }
488 /**
489  * Updates the parts of the statistics used by both addItem and deleteItem.
490  */
491 protected void updateStatistics() {
492   
493   SimTime now = currentTime();    // store current time
494   SimTime deltaTime = SimTime.diff( now, lastAcc );  // get time since last xs
495   wSumLength += currentLength * deltaTime.getTimeValue();  // weighted length sum
496   wSumSquareLength += currentLength * currentLength
497                       * deltaTime.getTimeValue();  // weighted square length sum
498   lastAcc = now;
499   
500 }
501 /**
502  * Returns the number of objects that have passed through the queue without
503  * spending time waiting.
504  * @return long : The number of elements who have passed the queue without
505  * waiting
506  */
507 public long zeroWaits() {
508   
509   return zeros;
510   
511 }
512 }