Imported Upstream version 15.21.0
[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     Date now = Date::now();
36
37     // compute value and check whether to report it
38     if ( hasRange() )
39     {
40       value_type newVal = _d->_val * 100 / ( _d->_max - _d->_min );
41
42       if ( newVal - _d->_last_val > 10
43            || now - _d->_last_send > 1
44            || ( _d->_last_val == 0 && newVal > 0 )
45            || ( newVal == 100 && _d->_last_val != 100 )
46            || ( newVal != 100 && _d->_last_val == 100 )
47            || _d->_state != RUN /*INIT||END*/ )
48       {
49         _d->_last_val  = newVal;
50         _d->_last_send = now;
51       }
52       else
53         return true;    // skip report, continue per default
54     }
55     else
56     {
57       if ( now - _d->_last_send > 1 || _d->_state != RUN /*INIT||END*/ )
58       {
59         _d->_last_val  = _d->_val;
60         _d->_last_send = now;
61       }
62       else
63         return true;    // skip report, continue per default
64     }
65
66     // now send report
67     if ( _d->_state == INIT )
68     {
69       _d->_state = RUN;
70     }
71     // XXX << str::form( "{#%u|%s}(%lld%s)", numericId(), name().c_str(), _d->_last_val, ( hasRange() ? "%" : "!" ) ) << endl;
72
73     if ( _d->_receiver )
74     {
75       if ( ! _d->_receiver( *this ) )
76       {
77         if ( _d->_state != END )
78         {
79           WAR << "User request to ABORT pending action. "
80           << str::form( "{#%u|%s}(%lld%s)", numericId(), name().c_str(),
81                         _d->_last_val, ( hasRange() ? "%" : "!" ) ) << endl;
82         }
83         return false;   // aborted by user
84       }
85     }
86     else if ( _d->_state == END )
87     {
88       DBG << str::form( "{#%u|%s}END", numericId(), name().c_str() ) << endl;
89     }
90
91     return true;        // continue per default
92   }
93
94   /******************************************************************
95   **
96   **    FUNCTION NAME : operator<<
97   **    FUNCTION TYPE : std::ostream &
98   */
99   std::ostream & operator<<( std::ostream & str, const ProgressData & obj )
100   {
101     if ( obj.hasRange() )
102     {
103       return str << str::form( "{%u|%s}[%lld,%lld](%lld)%lld%%)",
104                                obj.numericId(), obj.name().c_str(),
105                                obj.min(), obj.max(), obj.val(), obj.reportValue() );
106     }
107     return str << str::form( "{%u|%s}[-,-](%lld)",
108                              obj.numericId(), obj.name().c_str(),
109                              obj.val() );
110   }
111
112   /******************************************************************
113   **
114   **    FUNCTION NAME : operator<<
115   **    FUNCTION TYPE : std::ostream &
116   */
117   ProgressData makeProgressData( const InputStream & input_r )
118   {
119     ProgressData ret;
120     ret.name( input_r.name() );
121     if ( input_r.size() > 0 )
122       ret.range( input_r.size() );
123     return ret;
124   }
125
126   CombinedProgressData::CombinedProgressData( ProgressData &pd,
127                                               ProgressData::value_type weight )
128     : _weight(weight),
129       _last_value(0),
130       _pd(pd)
131   {
132
133   }
134
135   bool CombinedProgressData::operator()( const ProgressData &progress )
136   {
137     if ( progress.reportAlive() || ( _weight == 0 ) )
138       return _pd.tick();
139
140     // factor [0,1] of increase in subtask ( ie: before 0,2 now 0.5 )
141     float increment = ((float)(progress.val() - _last_value))/(progress.max() - progress.min());
142     // how much the subtask affects the parent task ie: 0,1
143     float parent_factor = (float)(_weight)/(_pd.max() - _pd.min());
144     // real increment of the parent task
145     float real_increment = parent_factor*increment;
146     _last_value = progress.val();
147     return _pd.incr( (int)( (_pd.max()-_pd.min()) * real_increment) );
148   }
149
150   /////////////////////////////////////////////////////////////////
151 } // namespace zypp
152 ///////////////////////////////////////////////////////////////////