Created
April 13, 2023 01:54
-
-
Save jcarlosroldan/93cf9f6209ec17db12092706c09edbe4 to your computer and use it in GitHub Desktop.
Iteratively explore every file in a system with multiple workers, build a tree and save it as a text file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <fstream> | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <filesystem> | |
#include <thread> | |
#include <mutex> | |
#include <queue> | |
#include <condition_variable> | |
using namespace std; | |
namespace fs = std::filesystem; | |
const int WORKERS = 8; // Adjust the number of worker threads | |
struct Element { | |
string name; | |
bool is_file; | |
int size; | |
vector<Element> children; | |
}; | |
mutex mtx; | |
condition_variable cv; | |
queue<fs::path> work_queue; | |
Element create_element(const fs::path& path) { | |
Element elem; | |
elem.name = path.filename().string(); | |
try { | |
if (fs::is_directory(path)) { | |
elem.is_file = false; | |
elem.size = 0; | |
for (const auto& entry : fs::directory_iterator(path)) { | |
Element child = create_element(entry.path()); | |
elem.size += child.size; | |
elem.children.push_back(child); | |
} | |
} else if (fs::is_regular_file(path) || fs::is_symlink(path)) { | |
elem.is_file = true; | |
elem.size = static_cast<int>(fs::file_size(path)); | |
} | |
} catch (const fs::filesystem_error& e) { | |
// Handle errors, e.g., permission denied | |
} | |
return elem; | |
} | |
void worker_thread(Element& root) { | |
while (true) { | |
fs::path path; | |
{ | |
unique_lock<mutex> lock(mtx); | |
cv.wait(lock, [] { return !work_queue.empty(); }); | |
path = work_queue.front(); | |
work_queue.pop(); | |
} | |
if (path.empty()) { | |
break; | |
} | |
Element child = create_element(path); | |
{ | |
lock_guard<mutex> lock(mtx); | |
root.size += child.size; | |
root.children.push_back(child); | |
} | |
} | |
} | |
void print_tree(const Element& elem, ofstream& output, int depth = 0) { | |
string indent(depth, ' '); | |
output << indent << elem.name << "\t" << elem.size << endl; | |
for (const auto& child : elem.children) { | |
print_tree(child, output, depth + 1); | |
} | |
} | |
int main() { | |
fs::path root_path = "/"; // Start from the root directory | |
Element root; | |
root.name = root_path.string(); | |
root.is_file = false; | |
root.size = 0; | |
work_queue.push(root_path); | |
vector<thread> worker_threads; | |
for (int i = 0; i < WORKERS; ++i) { | |
worker_threads.emplace_back(worker_thread, ref(root)); | |
} | |
for (auto& worker : worker_threads) { | |
worker.join(); | |
} | |
ofstream output_file("tree.txt"); | |
if (output_file.is_open()) { | |
print_tree(root, output_file); | |
output_file.close(); | |
} else { | |
cerr << "Unable to open file tree.txt for writing." << endl; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment