backup
[platform/upstream/libzypp.git] / zypp / ProgressData.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ProgressData.cc
10  *
11 */
12 #include <iostream>
13 #include "zypp/base/Logger.h"
14 #include "zypp/base/InputStream.h"
15 #include "zypp/base/String.h"
16
17 #include "zypp/ProgressData.h"
18
19 using std::endl;
20
21 #undef  ZYPP_BASE_LOGGER_LOGGROUP
22 #define  ZYPP_BASE_LOGGER_LOGGROUP "Progress"
23
24 ///////////////////////////////////////////////////////////////////
25 namespace zypp
26 { /////////////////////////////////////////////////////////////////
27
28   ///////////////////////////////////////////////////////////////////
29   //
30   //    METHOD NAME : ProgressData::report
31   //    METHOD TYPE : void
32   //
33   bool ProgressData::report()
34   {
35     bool goOn     = true;  // continue per default
36     bool doReport = false;
37
38     // compute value and check whether to report it
39     if ( hasRange() )
40     {
41       value_type newVal = _d->_val * 100;
42       newVal /= ( _d->_max - _d->_min );
43
44       if ( newVal - _d->_last_val > 20
45            || Date::now() - _d->_last_send > 1
46            || ( newVal == 100 && _d->_last_send != 100 )
47            || _d->_state == END )
48       {
49         _d->_last_val  = newVal;
50         _d->_last_send = Date::now();
51         doReport = true;
52       }
53     }
54     else
55     {
56       if ( Date::now() - _d->_last_send > 1 || _d->_state == END )
57       {
58         _d->_last_val  = _d->_val;
59         _d->_last_send = Date::now();
60         doReport = true;
61       }
62     }
63
64     // report if necessary
65     if ( doReport )
66     {
67       if ( _d->_state == INIT )
68       {
69         _d->_state = RUN;
70       }
71
72       if ( _d->_receiver )
73       {
74         goOn = _d->_receiver( *this );
75       }
76       else
77       {
78         if ( _d->_state != END )
79         {
80           XXX << str::form( "{#%u|%s}(%lld%s)",
81                             numericId(), name().c_str(),
82                             _d->_last_val, ( hasRange() ? "%" : "!" ) ) << endl;
83         }
84         else
85         {
86           DBG << str::form( "{#%u|%s}END", numericId(), name().c_str() ) << endl;
87         }
88       }
89     }
90
91     // log abort request and return
92     if ( ! goOn && _d->_state != END )
93     {
94       WAR << "User request to ABORT pending action. "
95           << str::form( "{#%u|%s}(%lld%s)",
96                         numericId(), name().c_str(),
97                         _d->_last_val, ( hasRange() ? "%" : "!" ) ) << endl;
98     }
99     return goOn;
100   }
101
102   /******************************************************************
103   **
104   **    FUNCTION NAME : operator<<
105   **    FUNCTION TYPE : std::ostream &
106   */
107   std::ostream & operator<<( std::ostream & str, const ProgressData & obj )
108   {
109     if ( obj.hasRange() )
110     {
111       return str << str::form( "{%u|%s}[%lld,%lld](%lld)%lld%%)",
112                                obj.numericId(), obj.name().c_str(),
113                                obj.min(), obj.max(), obj.val(), obj.reportValue() );
114     }
115     return str << str::form( "{%u|%s}[-,-](%lld)",
116                              obj.numericId(), obj.name().c_str(),
117                              obj.val() );
118   }
119
120   /******************************************************************
121   **
122   **    FUNCTION NAME : operator<<
123   **    FUNCTION TYPE : std::ostream &
124   */
125   ProgressData makeProgressData( const InputStream & input_r )
126   {
127     ProgressData ret;
128     ret.name( input_r.name() );
129     if ( input_r.size() > 0 )
130       ret.range( input_r.size() );
131     return ret;
132   }
133
134   CombinedProgressData::CombinedProgressData( ProgressData &pd,
135                                               ProgressData::value_type weight )
136     : _weight(weight),
137       _last_value(0),
138       _pd(pd)
139   {
140
141   }
142
143   bool CombinedProgressData::operator()( const ProgressData &progress )
144   {
145     if ( progress.reportAlive() || ( _weight == 0 ) )
146       return _pd.tick();
147
148     // factor [0,1] of increase in subtask ( ie: before 0,2 now 0.5 )
149     float increment = ((float)(progress.val() - _last_value))/(progress.max() - progress.min());
150     // how much the subtask affects the parent task ie: 0,1
151     float parent_factor = (float)(_weight)/(_pd.max() - _pd.min());
152     // real increment of the parent task
153     float real_increment = parent_factor*increment;
154     _last_value = progress.val();
155     return _pd.incr( (int)( (_pd.max()-_pd.min()) * real_increment) );
156   }
157
158   /////////////////////////////////////////////////////////////////
159 } // namespace zypp
160 ///////////////////////////////////////////////////////////////////