Skip to content

Instantly share code, notes, and snippets.

@jcarlosroldan
Created April 13, 2023 01:54
Show Gist options
  • Save jcarlosroldan/93cf9f6209ec17db12092706c09edbe4 to your computer and use it in GitHub Desktop.
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
#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