Skip to content

Commit 4d19ccf

Browse files
authored
add progress option (closes #30) (#197)
Thanks @entrity and @t-oster for the work and the patience. This PR is built on top of your work in #42 and #190. I made some simplifications by using a std::function and caching the constant output, instead of a function pointer. closes #30
2 parents 9ea11ae + 4847cfc commit 4d19ccf

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-3
lines changed

Rdutil.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,16 +543,22 @@ int
543543
Rdutil::fillwithbytes(enum Fileinfo::readtobuffermode type,
544544
enum Fileinfo::readtobuffermode lasttype,
545545
const long nsecsleep,
546-
const std::size_t buffersize)
546+
const std::size_t buffersize,
547+
std::function<void(std::size_t)> progress_cb)
547548
{
548549
// first sort on inode (to read efficiently from the hard drive)
549550
sortOnDeviceAndInode();
550551

551552
const auto duration = std::chrono::nanoseconds{ nsecsleep };
552553

553554
std::vector<char> buffer(buffersize, '\0');
555+
std::size_t progress_count = 0;
554556

555557
for (auto& elem : m_list) {
558+
if (progress_cb) {
559+
++progress_count;
560+
progress_cb(progress_count);
561+
}
556562
elem.fillwithbytes(type, lasttype, buffer);
557563
if (nsecsleep > 0) {
558564
std::this_thread::sleep_for(duration);

Rdutil.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef rdutil_hh
1010
#define rdutil_hh
1111

12+
#include <functional>
1213
#include <vector>
1314

1415
#include "Fileinfo.hh" //file container
@@ -90,7 +91,8 @@ public:
9091
int fillwithbytes(enum Fileinfo::readtobuffermode type,
9192
enum Fileinfo::readtobuffermode lasttype,
9293
long nsecsleep,
93-
std::size_t buffersize);
94+
std::size_t buffersize,
95+
std::function<void(std::size_t)> progress_cb);
9496

9597
/// make symlinks of duplicates.
9698
std::size_t makesymlinks(bool dryrun) const;

rdfind.1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ Delete (unlink) files. Default is false.
115115
.PP
116116
General options:
117117
.TP
118+
.BR \-progress " " \fItrue\fR|\fIfalse\fR
119+
Show progress during elimination. Defaults to false.
120+
.TP
118121
.BR \-sleep " " \fIX\fRms
119122
Sleeps X milliseconds between reading each file, to reduce
120123
load. Default is 0 (no sleep). Note that only a few values are

rdfind.cc

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ static_assert(__cplusplus >= 201703L,
1212
// std
1313
#include <iostream>
1414
#include <limits>
15+
#include <sstream>
1516
#include <string>
1617
#include <vector>
1718

@@ -78,6 +79,7 @@ usage()
7879
<< " -makeresultsfile (true)| false makes a results file\n"
7980
<< " -outputname name sets the results file name to \"name\" "
8081
"(default results.txt)\n"
82+
<< " -progress true |(false) output progress information"
8183
<< " -deleteduplicates true |(false) delete duplicate files\n"
8284
<< " -sleep Xms sleep for X milliseconds between "
8385
"file reads.\n"
@@ -115,6 +117,7 @@ struct Options
115117
bool usesha512 = false; // use sha512 checksum to check for similarity
116118
bool usexxh128 = false; // use xxh128 checksum to check for similarity
117119
bool deterministic = true; // be independent of filesystem order
120+
bool showprogress = false; // show progress while reading file contents
118121
std::size_t buffersize = 1 << 20; // chunksize to use when reading files
119122
long nsecsleep = 0; // number of nanoseconds to sleep between each file read.
120123
std::string resultsfile = "results.txt"; // results file name.
@@ -237,6 +240,8 @@ parseOptions(Parser& parser)
237240
<< nextarg << "\" is not among them.\n";
238241
std::exit(EXIT_FAILURE);
239242
}
243+
} else if (parser.try_parse_bool("-progress")) {
244+
o.showprogress = parser.get_parsed_bool();
240245
} else if (parser.current_arg_is("-help") || parser.current_arg_is("-h") ||
241246
parser.current_arg_is("--help")) {
242247
usage();
@@ -409,12 +414,28 @@ main(int narg, const char* argv[])
409414
"xxh128 checksum");
410415
}
411416

417+
std::function<void(std::size_t)> progress_callback;
418+
if (o.showprogress) {
419+
progress_callback = []() {
420+
// format the total count only once, not each iteration.
421+
std::ostringstream oss;
422+
oss << "/" << filelist.size() << ")"
423+
<< "\033[u"; // Restore the cursor to the saved position;
424+
return [suffix = oss.str()](std::size_t completed) {
425+
std::cout
426+
<< "\033[s\033[K" // Save the cursor position & clear following text
427+
<< "(" << completed << suffix << std::flush;
428+
};
429+
}();
430+
}
431+
412432
for (auto it = modes.begin() + 1; it != modes.end(); ++it) {
413433
std::cout << dryruntext << "Now eliminating candidates based on "
414434
<< it->second << ": " << std::flush;
415435

416436
// read bytes (destroys the sorting, for disk reading efficiency)
417-
gswd.fillwithbytes(it[0].first, it[-1].first, o.nsecsleep, o.buffersize);
437+
gswd.fillwithbytes(
438+
it[0].first, it[-1].first, o.nsecsleep, o.buffersize, progress_callback);
418439

419440
// remove non-duplicates
420441
std::cout << "removed " << gswd.removeUniqSizeAndBuffer()

0 commit comments

Comments
 (0)