mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-09 04:19:10 -04:00
Neater progress indicator
This commit is contained in:
parent
bd70ec7d7a
commit
fbc4f1adc5
@ -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
|
||||||
|
@ -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_;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user