mirror of
https://github.com/CHN-beta/nixos.git
synced 2024-10-23 05:18:44 +08:00
localPackages.hpcstat: 统计磁盘使用情况时只扫描一次
This commit is contained in:
parent
5a07c21eac
commit
c3647caacc
@ -25,39 +25,52 @@ bool hpcstat::disk::stat(boost::interprocess::file_lock &lock)
|
||||
{ std::cerr << "HOME not set\n"; return false; }
|
||||
else
|
||||
{
|
||||
auto get_size = [](std::string path) -> std::optional<double>
|
||||
auto all_size = [&] -> std::optional<std::map<std::string, double>>
|
||||
{
|
||||
if (auto result = exec("/usr/bin/du", { "-s", path }); !result)
|
||||
{ std::cerr << fmt::format("failed to stat {}\n", path); return std::nullopt; }
|
||||
if
|
||||
(
|
||||
auto result =
|
||||
exec("/usr/bin/du", { "-a", "--max-depth=2", *homedir });
|
||||
!result
|
||||
)
|
||||
{ std::cerr << fmt::format("failed to stat home.\n"); return std::nullopt; }
|
||||
else
|
||||
{
|
||||
std::smatch match;
|
||||
if (!std::regex_search(*result, match, std::regex(R"((\d+))")))
|
||||
{ std::cerr << fmt::format("failed to parse {}\n", *result); return std::nullopt; }
|
||||
return std::stod(match[1]) / 1024 / 1024;
|
||||
std::map<std::string, double> size;
|
||||
std::regex re(R"((\d+)\s+(.*)\n)");
|
||||
for (auto i = std::sregex_iterator(result->begin(), result->end(), re);
|
||||
i != std::sregex_iterator(); ++i)
|
||||
{
|
||||
if (i->str(2).find(*homedir) != 0)
|
||||
{ std::cerr << fmt::format("invalid path: {}\n", i->str(2)); return std::nullopt; }
|
||||
else size[i->str(2).substr(homedir->size())] = std::stoul(i->str(1)) / 1024. / 1024;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
};
|
||||
auto get_subdir = [](std::string path) -> std::vector<std::string>
|
||||
{
|
||||
std::filesystem::directory_iterator it(path);
|
||||
std::vector<std::string> result;
|
||||
for (const auto& entry : it)
|
||||
if (entry.is_directory()) result.push_back(entry.path().filename().string());
|
||||
return result;
|
||||
};
|
||||
}();
|
||||
if (!all_size) return false;
|
||||
Usage usage;
|
||||
usage.Time = now();
|
||||
if (auto size = get_size(*homedir); size) usage.Total = *size; else return false;
|
||||
if (!all_size->contains("")) { std::cerr << "Failed to get size of home\n"; return false; }
|
||||
usage.Total = (*all_size)[""];
|
||||
for (const auto& [dir, recursive] : Directories)
|
||||
{
|
||||
if (auto size = get_size(*homedir + "/" + dir); size)
|
||||
usage.Teacher.push_back({ dir, *size });
|
||||
else return false;
|
||||
if (!all_size->contains(dir))
|
||||
{ std::cerr << fmt::format("Failed to get size of {}\n", dir); return false; }
|
||||
else usage.Teacher.push_back({ dir, (*all_size)[dir] });
|
||||
auto get_subdir = [](std::string path) -> std::vector<std::string>
|
||||
{
|
||||
std::filesystem::directory_iterator it(path);
|
||||
std::vector<std::string> result;
|
||||
for (const auto& entry : it)
|
||||
if (entry.is_directory()) result.push_back(entry.path().filename().string());
|
||||
return result;
|
||||
};
|
||||
if (recursive) for (const auto& subdir : get_subdir(*homedir + "/" + dir))
|
||||
{
|
||||
if (auto size = get_size(*homedir + "/" + dir + "/" + subdir); size)
|
||||
usage.Student.push_back({ dir + "/" + subdir, *size });
|
||||
else return false;
|
||||
if (!all_size->contains(dir + "/" + subdir))
|
||||
{ std::cerr << fmt::format("Failed to get size of {}/{}\n", dir, subdir); return false; }
|
||||
else usage.Student.push_back({ dir + "/" + subdir, (*all_size)[dir + "/" + subdir] });
|
||||
}
|
||||
}
|
||||
std::sort(usage.Teacher.begin(), usage.Teacher.end(),
|
||||
|
Loading…
Reference in New Issue
Block a user