1 // progress_meter.h 2 3 4 /** 5 * Copyright (C) 2018-present MongoDB, Inc. 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the Server Side Public License, version 1, 9 * as published by MongoDB, Inc. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * Server Side Public License for more details. 15 * 16 * You should have received a copy of the Server Side Public License 17 * along with this program. If not, see 18 * <http://www.mongodb.com/licensing/server-side-public-license>. 19 * 20 * As a special exception, the copyright holders give permission to link the 21 * code of portions of this program with the OpenSSL library under certain 22 * conditions as described in each individual source file and distribute 23 * linked combinations including the program with the OpenSSL library. You 24 * must comply with the Server Side Public License in all respects for 25 * all of the code used other than as permitted herein. If you modify file(s) 26 * with this exception, you may extend this exception to your version of the 27 * file(s), but you are not obligated to do so. If you do not wish to do so, 28 * delete this exception statement from your version. If you delete this 29 * exception statement from all source files in the program, then also delete 30 * it in the license file. 31 */ 32 33 #pragma once 34 35 #include "mongo/util/thread_safe_string.h" 36 37 #include <string> 38 39 namespace mongo { 40 41 class ProgressMeter { 42 MONGO_DISALLOW_COPYING(ProgressMeter); 43 44 public: 45 ProgressMeter(unsigned long long total, 46 int secondsBetween = 3, 47 int checkInterval = 100, 48 std::string units = "", 49 std::string name = "Progress") _showTotal(true)50 : _showTotal(true), _units(units) { 51 _name = name.c_str(); 52 reset(total, secondsBetween, checkInterval); 53 } 54 ProgressMeter()55 ProgressMeter() { 56 _name = "Progress"; 57 } 58 59 // typically you do ProgressMeterHolder 60 void reset(unsigned long long total, int secondsBetween = 3, int checkInterval = 100); 61 finished()62 void finished() { 63 _active = false; 64 } isActive()65 bool isActive() const { 66 return _active; 67 } 68 69 /** 70 * @param n how far along we are relative to the total # we set in CurOp::setMessage 71 * @return if row was printed 72 */ 73 bool hit(int n = 1); 74 setUnits(const std::string & units)75 void setUnits(const std::string& units) { 76 _units = units; 77 } getUnit()78 std::string getUnit() const { 79 return _units; 80 } 81 setName(std::string name)82 void setName(std::string name) { 83 _name = name.c_str(); 84 } getName()85 std::string getName() const { 86 return _name.toString(); 87 } 88 setTotalWhileRunning(unsigned long long total)89 void setTotalWhileRunning(unsigned long long total) { 90 _total = total; 91 } 92 done()93 unsigned long long done() const { 94 return _done; 95 } 96 hits()97 unsigned long long hits() const { 98 return _hits; 99 } 100 total()101 unsigned long long total() const { 102 return _total; 103 } 104 showTotal(bool doShow)105 void showTotal(bool doShow) { 106 _showTotal = doShow; 107 } 108 109 std::string toString() const; 110 111 bool operator==(const ProgressMeter& other) const { 112 return this == &other; 113 } 114 115 private: 116 bool _active{false}; 117 118 unsigned long long _total; 119 bool _showTotal{true}; 120 int _secondsBetween{3}; 121 int _checkInterval{100}; 122 123 unsigned long long _done; 124 unsigned long long _hits; 125 int _lastTime; 126 127 std::string _units; 128 ThreadSafeString _name; 129 }; 130 131 // e.g.: 132 // CurOp * op = CurOp::get(opCtx); 133 // ProgressMeterHolder pm(op->setMessage("index: (1/3) external sort", 134 // "Index: External Sort Progress", d->stats.nrecords, 10)); loop { pm.hit(); } 135 class ProgressMeterHolder { 136 MONGO_DISALLOW_COPYING(ProgressMeterHolder); 137 138 public: ProgressMeterHolder(ProgressMeter & pm)139 ProgressMeterHolder(ProgressMeter& pm) : _pm(pm) {} 140 ~ProgressMeterHolder()141 ~ProgressMeterHolder() { 142 _pm.finished(); 143 } 144 145 ProgressMeter* operator->() { 146 return &_pm; 147 } 148 get()149 ProgressMeter* get() { 150 return &_pm; 151 } 152 153 bool hit(int n = 1) { 154 return _pm.hit(n); 155 } 156 finished()157 void finished() { 158 _pm.finished(); 159 } 160 161 bool operator==(const ProgressMeter& other) { 162 return _pm == other; 163 } 164 165 private: 166 ProgressMeter& _pm; 167 }; 168 } 169