Neater progress indicator

This commit is contained in:
Marcus Holland-Moritz 2020-11-29 17:49:34 +01:00
parent bd70ec7d7a
commit fbc4f1adc5
3 changed files with 63 additions and 30 deletions

View File

@ -35,8 +35,10 @@ class progress;
class console_writer : public logger { class console_writer : public logger {
public: public:
enum display_mode { NORMAL, REWRITE };
console_writer(std::ostream& os, bool is_terminal, size_t width, console_writer(std::ostream& os, bool is_terminal, size_t width,
level_type threshold); level_type threshold, display_mode mode = NORMAL);
void write(level_type level, const std::string& output) override; void write(level_type level, const std::string& output) override;
@ -53,5 +55,6 @@ class console_writer : public logger {
std::atomic<size_t> counter_{0}; std::atomic<size_t> counter_{0};
const bool show_progress_; const bool show_progress_;
const size_t width_; const size_t width_;
const display_mode mode_;
}; };
} // namespace dwarfs } // namespace dwarfs

View File

@ -24,6 +24,8 @@
#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp>
#include <fmt/format.h>
#include "dwarfs/console_writer.h" #include "dwarfs/console_writer.h"
#include "dwarfs/entry.h" #include "dwarfs/entry.h"
#include "dwarfs/file_interface.h" #include "dwarfs/file_interface.h"
@ -34,12 +36,14 @@
namespace dwarfs { namespace dwarfs {
console_writer::console_writer(std::ostream& os, bool show_progress, console_writer::console_writer(std::ostream& os, bool show_progress,
size_t width, level_type threshold) size_t width, level_type threshold,
display_mode mode)
: os_(os) : os_(os)
, threshold_(threshold) , threshold_(threshold)
, frac_(0.0) , frac_(0.0)
, show_progress_(show_progress) , show_progress_(show_progress)
, width_(width) { , width_(width)
, mode_(mode) {
os_.imbue(std::locale(os_.getloc(), os_.imbue(std::locale(os_.getloc(),
new boost::posix_time::time_facet("%H:%M:%S.%f"))); new boost::posix_time::time_facet("%H:%M:%S.%f")));
if (threshold > level_type::INFO) { if (threshold > level_type::INFO) {
@ -51,7 +55,14 @@ console_writer::console_writer(std::ostream& os, bool show_progress,
void console_writer::rewind() { void console_writer::rewind() {
if (!statebuf_.empty()) { if (!statebuf_.empty()) {
os_ << "\x1b[A\r\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A"; switch (mode_) {
case NORMAL:
os_ << "\x1b[A\r\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A";
break;
case REWRITE:
os_ << "\x1b[A\r\x1b[A\x1b[A\x1b[A";
break;
}
} }
} }
@ -99,57 +110,74 @@ void console_writer::update(const progress& p, bool last) {
if (show_progress_) { if (show_progress_) {
for (size_t i = 0; i < width_; ++i) { for (size_t i = 0; i < width_; ++i) {
oss << '-'; oss << "";
} }
oss << "\n"; oss << "\n";
} }
oss << p.status(width_) << newline switch (mode_) {
case NORMAL:
oss << p.status(width_) << newline
<< "scanned/found: " << p.dirs_scanned << "/" << p.dirs_found << " dirs, " << "scanned/found: " << p.dirs_scanned << "/" << p.dirs_found
<< p.links_scanned << "/" << p.links_found << " links, " << " dirs, " << p.links_scanned << "/" << p.links_found << " links, "
<< p.files_scanned << "/" << p.files_found << " files" << newline << p.files_scanned << "/" << p.files_found << " files" << newline
<< "original size: " << size_with_unit(p.original_size) << "original size: " << size_with_unit(p.original_size)
<< ", dedupe: " << size_with_unit(p.saved_by_deduplication) << " (" << ", dedupe: " << size_with_unit(p.saved_by_deduplication) << " ("
<< p.duplicate_files << p.duplicate_files
<< " files), segment: " << size_with_unit(p.saved_by_segmentation) << " files), segment: " << size_with_unit(p.saved_by_segmentation)
<< newline << newline
<< "filesystem: " << size_with_unit(p.filesystem_size) << " in " << "filesystem: " << size_with_unit(p.filesystem_size) << " in "
<< p.block_count << " blocks (" << p.chunk_count << " chunks, " << p.block_count << " blocks (" << p.chunk_count << " chunks, "
<< p.inodes_written << "/" << p.files_found - p.duplicate_files << p.inodes_written << "/" << p.files_found - p.duplicate_files
<< " inodes)" << newline << " inodes)" << newline
<< "compressed filesystem: " << p.blocks_written << " blocks/" << "compressed filesystem: " << p.blocks_written << " blocks/"
<< size_with_unit(p.compressed_size) << " written" << newline; << size_with_unit(p.compressed_size) << " written" << newline;
break;
case REWRITE:
oss << "filesystem: " << size_with_unit(p.filesystem_size) << " in "
<< p.block_count << " blocks (" << p.chunk_count << " chunks, "
<< p.inodes_written << " inodes)" << newline
<< "compressed filesystem: " << p.blocks_written << "/" << p.block_count
<< " blocks/" << size_with_unit(p.compressed_size) << " written"
<< newline;
break;
}
if (show_progress_) { if (show_progress_) {
// TODO: this can likely be improved
size_t orig = p.original_size - p.saved_by_deduplication; size_t orig = p.original_size - p.saved_by_deduplication;
double frac_fs = double frac_fs =
orig > 0 ? double(p.filesystem_size + p.saved_by_segmentation) / orig orig > 0 ? double(p.filesystem_size + p.saved_by_segmentation) / orig
: 0.0; : 0.0;
double frac_comp = double frac_comp =
p.block_count > 0 ? double(p.blocks_written) / p.block_count : 0.0; p.block_count > 0 ? double(p.blocks_written) / p.block_count : 0.0;
double frac = (frac_fs + frac_comp) / 2.0; double frac = mode_ == NORMAL ? (frac_fs + frac_comp) / 2.0 : frac_comp;
if (frac > frac_) { if (frac > frac_) {
frac_ = frac; frac_ = frac;
} }
size_t w = width_ * frac_; size_t barlen = 8 * (width_ - 6) * frac_;
size_t w = barlen / 8;
size_t c = barlen % 8;
for (size_t i = 0; i < width_; ++i) { static const char* bar[8] = {"", "", "", "", "", "", "", ""};
if (i == 0 || i == (width_ - 1)) {
oss << "|"; for (size_t i = 0; i < width_ - 6; ++i) {
if (i == (width_ - 7)) {
oss << bar[0];
} else if (i == w && !last) { } else if (i == w && !last) {
oss << "/-\\|"[counter_ % 4]; oss << bar[c];
} else { } else {
oss << (i < w ? "=" : " "); oss << (i < w ? bar[7] : " ");
} }
} }
oss << "\n"; oss << fmt::format("{:3.0f}% ", 100 * frac_) << "-\\|/"[counter_ % 4] << '\n';
++counter_; ++counter_;

View File

@ -443,7 +443,9 @@ int mkdwarfs(int argc, char** argv) {
max_scanner_workers); max_scanner_workers);
console_writer lgr(std::cerr, !no_progress && ::isatty(::fileno(stderr)), console_writer lgr(std::cerr, !no_progress && ::isatty(::fileno(stderr)),
get_term_width(), logger::parse_level(log_level)); get_term_width(), logger::parse_level(log_level),
recompress ? console_writer::REWRITE
: console_writer::NORMAL);
std::shared_ptr<script> script; std::shared_ptr<script> script;