mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2024-11-29 01:33:46 +00:00
Improve progress output.
This commit is contained in:
parent
8d4e8b86b1
commit
f48626960d
3 changed files with 89 additions and 17 deletions
|
@ -23,7 +23,7 @@
|
|||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
# include <atomic>
|
||||
# include <condition_variable>
|
||||
|
@ -31,6 +31,9 @@
|
|||
#include <cstdint>
|
||||
#include <ciso646>
|
||||
#include <cassert>
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
|
||||
#if defined(INDEXER_VERBOSE)
|
||||
# include <iostream>
|
||||
|
@ -65,7 +68,9 @@ namespace din {
|
|||
};
|
||||
|
||||
namespace {
|
||||
void hash_dir (std::vector<FileEntry>::iterator parEntry, std::vector<FileEntry>::iterator parEnd, const PathName& parCurrDir, std::function<void()> parItemDoneCallback) {
|
||||
typedef std::vector<FileEntry>::iterator FileEntryIt;
|
||||
|
||||
void hash_dir (FileEntryIt parEntry, FileEntryIt parBegin, FileEntryIt parEnd, const PathName& parCurrDir, std::function<void(std::size_t)> parNextItemCallback) {
|
||||
assert(parEntry != parEnd);
|
||||
assert(parEntry->is_dir);
|
||||
FileEntry& curr_entry = *parEntry;
|
||||
|
@ -94,7 +99,7 @@ namespace din {
|
|||
while (parEnd != it_entry and it_entry->level == curr_entry_it->level + 1 and parCurrDir == PathName(it_entry->path).pop_right()) {
|
||||
PathName curr_subdir(it_entry->path);
|
||||
if (it_entry->is_dir) {
|
||||
hash_dir(it_entry, parEnd, curr_subdir, parItemDoneCallback);
|
||||
hash_dir(it_entry, parBegin, parEnd, curr_subdir, parNextItemCallback);
|
||||
|
||||
std::string relpath = make_relative_path(parCurrDir, curr_subdir).path();
|
||||
const auto old_size = dir_blob.size();
|
||||
|
@ -136,8 +141,8 @@ namespace din {
|
|||
#if defined(INDEXER_VERBOSE)
|
||||
std::cout << "Hashing file " << it_entry->path << "...";
|
||||
#endif
|
||||
parNextItemCallback(it_entry - parBegin);
|
||||
tiger_file(it_entry->path, it_entry->hash, curr_entry_it->hash, it_entry->file_size);
|
||||
parItemDoneCallback();
|
||||
#if defined(INDEXER_VERBOSE)
|
||||
std::cout << ' ' << tiger_to_string(it_entry->hash) << '\n';
|
||||
#endif
|
||||
|
@ -148,8 +153,12 @@ namespace din {
|
|||
#if defined(INDEXER_VERBOSE)
|
||||
std::cout << "Final hash for dir " << parCurrDir << " is " << tiger_to_string(curr_entry_it->hash) << '\n';
|
||||
#endif
|
||||
//parItemDoneCallback();
|
||||
}
|
||||
|
||||
template <bool FileTrue=true>
|
||||
struct IsFile {
|
||||
bool operator() ( const FileEntry& parEntry ) const { return parEntry.is_dir xor FileTrue; }
|
||||
};
|
||||
} //unnamed namespace
|
||||
|
||||
struct Indexer::LocalData {
|
||||
|
@ -159,6 +168,7 @@ namespace din {
|
|||
PathList paths;
|
||||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
std::atomic<std::size_t> done_count;
|
||||
std::atomic<std::size_t> processing_index;
|
||||
std::condition_variable step_notify;
|
||||
#endif
|
||||
std::size_t file_count;
|
||||
|
@ -198,6 +208,7 @@ namespace din {
|
|||
#endif
|
||||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
m_local_data->done_count = 0;
|
||||
m_local_data->processing_index = 0;
|
||||
#endif
|
||||
m_local_data->file_count = 0;
|
||||
m_local_data->db_settings = parDBSettings;
|
||||
|
@ -237,11 +248,13 @@ namespace din {
|
|||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
m_local_data->done_count = 0;
|
||||
hash_dir(
|
||||
m_local_data->paths.begin(),
|
||||
m_local_data->paths.begin(),
|
||||
m_local_data->paths.end(),
|
||||
base_path,
|
||||
[=]() {
|
||||
[=](std::size_t parNext) {
|
||||
++m_local_data->done_count;
|
||||
m_local_data->processing_index = parNext;
|
||||
m_local_data->step_notify.notify_all();
|
||||
}
|
||||
);
|
||||
|
@ -249,10 +262,11 @@ namespace din {
|
|||
assert(m_local_data->done_count == m_local_data->paths.size());
|
||||
#else
|
||||
hash_dir(
|
||||
m_local_data->paths.begin(),
|
||||
m_local_data->paths.begin(),
|
||||
m_local_data->paths.end(),
|
||||
base_path,
|
||||
[]() {}
|
||||
[](std::size_t) {}
|
||||
);
|
||||
#endif
|
||||
|
||||
|
@ -323,4 +337,28 @@ namespace din {
|
|||
return m_local_data->step_notify;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
std::string Indexer::current_item() const {
|
||||
if (m_local_data->paths.empty() or 0 == m_local_data->processing_index)
|
||||
return std::string();
|
||||
|
||||
PathName base_path(m_local_data->paths.front().path);
|
||||
PathName ret_path(m_local_data->paths[m_local_data->processing_index].path);
|
||||
return make_relative_path(base_path, ret_path).path();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string Indexer::operator[] (std::size_t parIndex) const {
|
||||
if (parIndex >= m_local_data->file_count) {
|
||||
std::ostringstream oss;
|
||||
oss << "Requested index " << parIndex << " is out of range: only " << m_local_data->file_count << " items are available";
|
||||
throw std::out_of_range(oss.str());
|
||||
}
|
||||
|
||||
auto it = boost::make_filter_iterator<IsFile<>>(m_local_data->paths.begin(), m_local_data->paths.end());
|
||||
assert(not m_local_data->paths.empty());
|
||||
std::advance(it, parIndex);
|
||||
return make_relative_path(PathName(m_local_data->paths.front().path), PathName(it->path)).path();
|
||||
}
|
||||
} //namespace din
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define idE555EF56730442C1ADDC7B2AE7A9340E
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
# define INDEXER_VERBOSE
|
||||
|
@ -46,8 +47,10 @@ namespace din {
|
|||
#endif
|
||||
|
||||
std::size_t total_items ( void ) const;
|
||||
std::string operator[] ( std::size_t parIndex ) const;
|
||||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
std::size_t processed_items ( void ) const;
|
||||
std::string current_item ( void ) const;
|
||||
std::condition_variable& step_notify ( void );
|
||||
#endif
|
||||
void calculate_hash ( void );
|
||||
|
|
51
src/main.cpp
51
src/main.cpp
|
@ -16,7 +16,11 @@
|
|||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <ciso646>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
# include <thread>
|
||||
# include <mutex>
|
||||
|
@ -49,6 +53,11 @@ int main (int parArgc, char* parArgv[]) {
|
|||
return 2;
|
||||
}
|
||||
const std::string search_path(vm["search-path"].as<std::string>());
|
||||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
const bool verbose = (0 == vm.count("quiet"));
|
||||
#else
|
||||
const bool verbose = false;
|
||||
#endif
|
||||
|
||||
din::DinDBSettings settings;
|
||||
{
|
||||
|
@ -65,18 +74,19 @@ int main (int parArgc, char* parArgv[]) {
|
|||
searcher.SetFollowSymlinks(true);
|
||||
searcher.SetCallback(fastf::FileSearcher::CallbackType(std::bind(&din::Indexer::add_path, &indexer, _1, _2, _3, _4)));
|
||||
searcher.Search(ext, ignore);
|
||||
if (verbose) {
|
||||
std::cout << "Fetching items list...\n";
|
||||
}
|
||||
|
||||
if (indexer.empty()) {
|
||||
std::cerr << "Nothing found at the given location, quitting\n";
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
const bool verbose = (0 == vm.count("quiet"));
|
||||
#else
|
||||
const bool verbose = false;
|
||||
#endif
|
||||
run_hash_calculation(indexer, verbose);
|
||||
if (verbose) {
|
||||
std::cout << "Writing to database...\n";
|
||||
}
|
||||
indexer.add_to_db(vm["setname"].as<std::string>(), vm["type"].as<char>());
|
||||
}
|
||||
return 0;
|
||||
|
@ -84,6 +94,10 @@ int main (int parArgc, char* parArgv[]) {
|
|||
|
||||
namespace {
|
||||
void run_hash_calculation (din::Indexer& parIndexer, bool parShowProgress) {
|
||||
if (parIndexer.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(WITH_PROGRESS_FEEDBACK)
|
||||
parShowProgress = false;
|
||||
#endif
|
||||
|
@ -92,16 +106,33 @@ namespace {
|
|||
}
|
||||
#if defined(WITH_PROGRESS_FEEDBACK)
|
||||
else {
|
||||
std::cout << "Fetching items list...\n";
|
||||
typedef std::ostream_iterator<char> cout_iterator;
|
||||
|
||||
std::cout << "Processing";
|
||||
std::cout.flush();
|
||||
const auto total_items = parIndexer.total_items();
|
||||
std::thread hash_thread(&din::Indexer::calculate_hash, &parIndexer);
|
||||
std::mutex progress_print;
|
||||
while (parIndexer.processed_items() != total_items) {
|
||||
std::size_t clear_size = 0;
|
||||
const auto digit_count = static_cast<std::size_t>(std::log10(static_cast<double>(total_items))) + 1;
|
||||
do {
|
||||
std::unique_lock<std::mutex> lk(progress_print);
|
||||
parIndexer.step_notify().wait(lk);
|
||||
std::cout << "Processed " << parIndexer.processed_items() << " of " << total_items << '\r';
|
||||
std::cout.flush();
|
||||
};
|
||||
std::cout << '\r';
|
||||
std::fill_n(cout_iterator(std::cout), clear_size, ' ');
|
||||
std::cout << '\r';
|
||||
{
|
||||
std::ostringstream oss;
|
||||
const auto item_index = std::min(total_items - 1, parIndexer.processed_items());
|
||||
oss << "Processing file "
|
||||
<< std::setw(digit_count) << std::setfill(' ') << (item_index + 1)
|
||||
<< " of " << total_items << " \"" << parIndexer.current_item() << '"';
|
||||
const auto msg(oss.str());
|
||||
clear_size = msg.size();
|
||||
std::cout << msg;
|
||||
std::cout.flush();
|
||||
}
|
||||
} while (parIndexer.processed_items() != total_items);
|
||||
|
||||
hash_thread.join();
|
||||
if (parIndexer.processed_items() > 0) {
|
||||
|
|
Loading…
Reference in a new issue