1/*
2 * Legal Notice
3 *
4 * This document and associated source code (the "Work") is a part of a
5 * benchmark specification maintained by the TPC.
6 *
7 * The TPC reserves all right, title, and interest to the Work as provided
8 * under U.S. and international laws, including without limitation all patent
9 * and trademark rights therein.
10 *
11 * No Warranty
12 *
13 * 1.1 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE INFORMATION
14 * CONTAINED HEREIN IS PROVIDED "AS IS" AND WITH ALL FAULTS, AND THE
15 * AUTHORS AND DEVELOPERS OF THE WORK HEREBY DISCLAIM ALL OTHER
16 * WARRANTIES AND CONDITIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
17 * INCLUDING, BUT NOT LIMITED TO, ANY (IF ANY) IMPLIED WARRANTIES,
18 * DUTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
19 * PURPOSE, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OF
20 * WORKMANLIKE EFFORT, OF LACK OF VIRUSES, AND OF LACK OF NEGLIGENCE.
21 * ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT,
22 * QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT
23 * WITH REGARD TO THE WORK.
24 * 1.2 IN NO EVENT WILL ANY AUTHOR OR DEVELOPER OF THE WORK BE LIABLE TO
25 * ANY OTHER PARTY FOR ANY DAMAGES, INCLUDING BUT NOT LIMITED TO THE
26 * COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST PROFITS, LOSS
27 * OF USE, LOSS OF DATA, OR ANY INCIDENTAL, CONSEQUENTIAL, DIRECT,
28 * INDIRECT, OR SPECIAL DAMAGES WHETHER UNDER CONTRACT, TORT, WARRANTY,
29 * OR OTHERWISE, ARISING IN ANY WAY OUT OF THIS OR ANY OTHER AGREEMENT
30 * RELATING TO THE WORK, WHETHER OR NOT SUCH AUTHOR OR DEVELOPER HAD
31 * ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.
32 *
33 * Contributors
34 * - Christopher Chan-Nui
35 */
36
37#include "utilities/threading.h"
38
39#include <iostream>
40
41#include "main/progressmeter.h"
42#include "main/strutil.h"
43
44namespace TPCE {
45
46// total - The total number of tasks to complete before the job is done.
47ProgressMeter::ProgressMeter(int total_in, int verbosity, std::ostream *output)
48 : m_total(total_in), m_current(0), m_display_interval(10), m_start_time(), m_last_time(m_start_time),
49 m_output(output), m_verbosity(verbosity), m_mutex() {
50}
51
52// val - minimum number of seconds between automatic display updates
53// set to -1 to disable automatic displays
54void ProgressMeter::set_display_interval(int val) {
55 TPCE::Locker<ProgressMeter> locker(*this);
56 m_display_interval = val;
57}
58
59int ProgressMeter::display_interval() const {
60 TPCE::Locker<const ProgressMeter> locker(*this);
61 return m_display_interval;
62}
63
64// Displays the current progress and an estimated time to finish
65void ProgressMeter::display() const {
66 TPCE::Locker<const ProgressMeter> locker(*this);
67 display_message(*m_output);
68 (*m_output) << std::endl;
69}
70
71// Displays a progress message to the specified output stream
72// Lock progress meter before calling this function!
73//
74// output - output stream to display progress to
75void ProgressMeter::display_message(std::ostream &out) const {
76 CDateTime now;
77 INT32 elapsed_in_ms = now.DiffInMilliSeconds(m_start_time);
78 double rate = static_cast<double>(elapsed_in_ms) / static_cast<double>(m_current) / 1000.0;
79 out << m_current << "/" << m_total << " (" << m_current * 100 / m_total << "%)"
80 << " [Remain: " << int64totimestr((int)(rate * (double)(m_total - m_current))) << ", "
81 << "Elapsed: " << int64totimestr(elapsed_in_ms / 1000) << "]";
82}
83
84// Notifies the progress meter that some tasks have been completed. If there
85// hasn't been a display update within display_interval seconds then an update
86// will be emitted to the output stream.
87//
88// count - number of tasks completed
89// output - output stream to display progress to
90void ProgressMeter::inc(int count) {
91 CDateTime now;
92 {
93 TPCE::Locker<ProgressMeter> locker(*this);
94 m_current += count;
95 if (m_verbosity <= 0 || m_display_interval < 0 ||
96 now.DiffInMilliSeconds(m_last_time) <= m_display_interval * 1000) {
97 return;
98 }
99 m_last_time.Set();
100 }
101 display();
102}
103
104// Return current count
105int ProgressMeter::current() const {
106 TPCE::Locker<const ProgressMeter> locker(*this);
107 return m_current;
108}
109
110// Return total count
111int ProgressMeter::total() const {
112 TPCE::Locker<const ProgressMeter> locker(*this);
113 return m_total;
114}
115
116// Display a message if the verbosity level is greater than message level
117//
118// mesg - message to display
119// level - verbosity level to display at
120void ProgressMeter::message(const std::string &mesg, int level) {
121 TPCE::Locker<ProgressMeter> locker(*this);
122 if (level >= m_verbosity) {
123 return;
124 }
125 (*m_output) << mesg << std::endl;
126}
127
128void ProgressMeter::lock() const {
129 m_mutex.lock();
130}
131
132void ProgressMeter::unlock() const {
133 m_mutex.unlock();
134}
135
136} // namespace TPCE
137