DurationStatistic.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const DurationStatistic_cxx_Version = 
  51.     "$Id: DurationStatistic.cxx,v 1.3 2001/01/27 00:33:50 icahoon Exp $";
  52. #include "DurationStatistic.hxx"
  53. #include <cassert>
  54. using Vocal::Statistics::DurationStatistic;
  55. using Vocal::Statistics::Statistic;
  56. using Vocal::Statistics::StatisticsDb;
  57. DurationStatistic::DurationStatistic(
  58.     StatisticsDb     &   p_db, 
  59.     const Data       &   p_name,
  60.     u_int32_t          p_window
  61. )
  62.     : Statistic(p_db, p_name),
  63.      m_duration(),
  64.      m_next(0),
  65. m_last(0),
  66. m_window(p_window),
  67. m_size(1),
  68. m_length(0)
  69. {
  70. }
  71. DurationStatistic::DurationStatistic(const DurationStatistic & src)
  72.     : Statistic(src),
  73.      m_duration(src.m_duration),
  74. m_next(0),
  75. m_last(0),
  76. m_window(src.m_window),
  77. m_size(1),
  78. m_length(src.m_duration.length())
  79. {
  80.     // If the given statistic is a combination, just append the entire
  81.     // list to the end, which will give us two copies of the first
  82.     // element. Then just pop the first one off.
  83.     //
  84.     if ( src.m_next != 0 )
  85.     {
  86.      append(src);
  87. pop();
  88.     }
  89. }
  90. const DurationStatistic & 
  91. DurationStatistic::operator=(const DurationStatistic & src)
  92. {
  93.     if ( this != &src )
  94.     {
  95.      clear();
  96.      Statistic::operator=(src);
  97. m_duration = src.m_duration;
  98. m_next = 0;
  99. m_last = 0;
  100. m_window = src.m_window;
  101. m_size = 1;
  102. m_length = src.m_duration.length();    
  103. // See copy ctor.
  104. //
  105.      if ( src.m_next != 0 )
  106. {
  107.          append(src);
  108.     pop();
  109. }
  110.     }
  111.     return ( *this );
  112. }
  113. DurationStatistic::~DurationStatistic()
  114. {
  115.     clear();
  116. }
  117.     
  118. void
  119. DurationStatistic::combine(const Statistic & src)
  120. {
  121.     const DurationStatistic * srcD 
  122.      = dynamic_cast<const DurationStatistic *>(&src);
  123.     
  124.     if ( srcD == 0 )
  125.     {
  126.      assert( srcD != 0 );
  127. return;
  128.     }
  129.     append(*srcD);
  130.     
  131.     if ( m_window > 0 )
  132.     {
  133. while ( m_size > m_window )
  134. {
  135.          pop();
  136. }
  137.     }
  138. }
  139. Statistic *
  140. DurationStatistic::copy() const
  141. {
  142.     return ( new DurationStatistic(*this) );
  143. }
  144. DurationStatistic *
  145. DurationStatistic::next() const
  146. {
  147.     return ( m_next );
  148. }
  149. u_int32_t   
  150. DurationStatistic::size() const
  151. {
  152.     return ( m_size );
  153. }
  154. u_int32_t   
  155. DurationStatistic::window() const
  156. {
  157.     return ( m_window );
  158. }
  159. int64_t 
  160. DurationStatistic::length() const
  161. {
  162.     return ( m_length );
  163. }
  164. double
  165. DurationStatistic::average() const
  166. {
  167.     int64_t len = length();
  168.     
  169.     return ( static_cast<double>(len) / size() );
  170. }
  171. ostream &   
  172. DurationStatistic::writeTo(ostream & out) const
  173. {
  174.     const char *  label = name().getData();
  175.     
  176.     out << label << ":n{n  data: (" << m_duration.length();
  177.     
  178.     for (   DurationStatistic * current = m_next; 
  179.          current != 0; 
  180.     current = current->m_next 
  181. )
  182.     {
  183.      out << "," << current->m_duration.length();
  184.     }
  185.     out << "),n  window: " << window()
  186.      << ",n  size: " << size()
  187. << ",n  length: " << length()
  188. << ",n  average: " << average() << "n}";
  189.     return ( out );
  190. }
  191.  
  192. DurationStatistic::DurationStatistic(
  193.     const Statistic     &   p_stat, 
  194.     const Duration      &   p_duration,
  195.     u_int32_t          p_window
  196. )
  197.     : Statistic(p_stat),
  198.      m_duration(p_duration),
  199.      m_next(0),
  200. m_last(0),
  201. m_window(p_window),
  202. m_size(1),
  203. m_length(p_duration.length())
  204. {
  205. }
  206. void
  207. DurationStatistic::append(const DurationStatistic & src)
  208. {
  209.     // Create a copy of the list first, then glue them together. 
  210.     // This avoids an infinite loop when you append a list to itself.
  211.     //
  212.     DurationStatistic       *   newList = 0,
  213.                     *   newLast = 0;
  214.     u_int32_t             newSize = 0;
  215.     int64_t               newLength = 0;
  216.     const DurationStatistic  *   nextStat = 0,
  217.      *   currentStat = 0;
  218.     for ( currentStat = &src; currentStat != 0; currentStat = nextStat )
  219.     {
  220. if ( key() != currentStat->key() )
  221. {
  222.          assert( key() == currentStat->key() );
  223.     return;
  224. }
  225.      nextStat = currentStat->m_next;
  226.      if ( m_last )
  227. {
  228.     assert( newLast != m_last );
  229. }
  230.      DurationStatistic * newStat = new DurationStatistic(
  231.           *currentStat, currentStat->m_duration, currentStat->m_window);
  232.      if ( newList == 0 )
  233. {
  234.     newList = newStat;
  235.     newLast = newStat;
  236. }
  237. else
  238. {
  239.     newLast->m_next = newStat;
  240.     newLast = newStat;
  241. }
  242. ++newSize;
  243. newLength += currentStat->m_duration.length();
  244.     }
  245.     
  246.     if ( m_next == 0 )
  247.     {
  248.      assert( m_last == 0 );
  249. m_next = newList;
  250. m_last = newLast;
  251.     }
  252.     else
  253.     {
  254.      assert( m_last != 0 );
  255. assert( m_last->m_next == 0 );
  256. assert( m_last->m_last == 0 );
  257.      m_last->m_next = newList;
  258. m_last = newLast;
  259.     }
  260.     m_size += newSize;
  261.     if ( m_length == 0 )
  262.     {
  263.      m_length = m_duration.length();
  264.     }
  265.     m_length += newLength;
  266.     assert( m_size > 1 );
  267.     assert( m_next != 0 );
  268.     assert( m_last != 0 );
  269.     assert( m_last->m_next == 0 );
  270.     assert( m_last->m_last == 0 );
  271. }
  272. void
  273. DurationStatistic::pop()
  274. {
  275.     if ( m_size <= 1 )
  276.     {
  277.      assert( m_size > 2 );
  278. return;
  279.     }
  280.     if ( m_next == 0 )
  281.     {
  282.      assert( m_next != 0 );
  283. return;
  284.     }
  285.     m_length -= m_duration.length();
  286.     m_size--;
  287.     m_duration = m_next->m_duration;
  288.     if ( m_next == m_last )
  289.     {
  290.      m_last = 0;
  291.     }    
  292.     DurationStatistic * nuke = m_next;
  293.     m_next = m_next->m_next;
  294.         
  295.     nuke->m_next = 0;
  296.     delete nuke;
  297.     assert( m_size >= 1 );
  298.     if ( m_next == 0 )
  299.     {
  300.      assert( m_last == 0 );
  301.     }
  302.     else
  303.     {
  304.      assert( m_last != 0 );
  305. assert( m_last->m_next == 0 );
  306. assert( m_last->m_last == 0 );
  307.     }
  308. }
  309. void
  310. DurationStatistic::clear()
  311. {
  312.     if ( m_next == 0 )
  313.     {
  314.      assert( m_last == 0 );
  315.      return;
  316.     }
  317.     
  318.     DurationStatistic * nextStat = 0;
  319.     
  320.     for (   DurationStatistic * currentStat = m_next;
  321.          currentStat != 0;
  322.     currentStat = nextStat
  323. )
  324.     {
  325.      nextStat = currentStat->m_next;
  326.      currentStat->m_next = 0;
  327.      delete currentStat;
  328.     }
  329.     
  330.     m_next = m_last = 0;
  331.     m_size = 1;
  332.     
  333.     m_length = 0;
  334. }