24 #include <condition_variable>
30 #if __cplusplus >= 201703L
31 # include <filesystem>
32 namespace ffd_internal_fs = std::filesystem;
34 # include <boost/filesystem.hpp>
35 namespace ffd_internal_fs = boost::filesystem;
50 MTDirCrawler() : done_(false), queue_(), workers_(), threads_running_(0), mutex_(), cv_() {}
73 void crawl(ffd_internal_fs::path base_path,
74 std::function<
bool(
const ffd_internal_fs::directory_entry &)> callback,
89 std::function<
bool(
const ffd_internal_fs::directory_entry &)> callback,
92 threads_running_ = threads;
93 for (
int i = 0; i < threads; ++i) {
94 workers_.emplace_back(&MTDirCrawler::worker,
this, callback);
103 for (std::thread &t : workers_) {
111 std::deque<ffd_internal_fs::directory_entry> queue_;
112 std::vector<std::thread> workers_;
113 std::atomic<int> threads_running_;
115 std::condition_variable cv_;
116 void seed(
const ffd_internal_fs::path &base_path) {
117 queue_.emplace_back(base_path);
119 void worker(std::function<
bool(
const ffd_internal_fs::directory_entry &)> callback) {
120 ffd_internal_fs::directory_entry node;
123 std::unique_lock<std::mutex> lk(mutex_);
125 if (threads_running_ <= 0 && queue_.empty()) {
130 while (queue_.empty() && !done_) {
133 if (done_ && queue_.empty())
135 node = queue_.front();
139 if (callback(node) && ffd_internal_fs::is_directory(node)) {
140 #if __cplusplus >= 201703L
141 for (
auto const &node : ffd_internal_fs::directory_iterator{ node }) {
143 for (ffd_internal_fs::directory_iterator ditr{ node };
144 ditr != ffd_internal_fs::directory_iterator{};
148 std::lock_guard<std::mutex> lk(mutex_);
149 #if __cplusplus >= 201703L
150 queue_.emplace_back(node);
152 queue_.emplace_back(*ditr);