Merge "libmeminfo: librank optimization using maps instead of vectors"
This commit is contained in:
commit
924eec9518
1 changed files with 24 additions and 23 deletions
|
|
@ -26,6 +26,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -122,30 +123,22 @@ struct LibRecord {
|
||||||
|
|
||||||
const std::string& name() const { return name_; }
|
const std::string& name() const { return name_; }
|
||||||
const MemUsage& usage() const { return usage_; }
|
const MemUsage& usage() const { return usage_; }
|
||||||
const std::vector<ProcessRecord>& processes() const { return procs_; }
|
const std::map<pid_t, ProcessRecord>& processes() const { return procs_; }
|
||||||
uint64_t pss() const { return usage_.pss; }
|
uint64_t pss() const { return usage_.pss; }
|
||||||
void AddUsage(const ProcessRecord& proc, const MemUsage& mem_usage) {
|
void AddUsage(const ProcessRecord& proc, const MemUsage& mem_usage) {
|
||||||
auto process = std::find_if(procs_.begin(), procs_.end(),
|
auto [it, inserted] = procs_.insert(std::pair<pid_t, ProcessRecord>(proc.pid(), proc));
|
||||||
[&](auto p) -> bool { return p.pid() == proc.pid(); });
|
it->second.AddUsage(mem_usage);
|
||||||
if (process == procs_.end()) {
|
|
||||||
process = procs_.emplace(procs_.end(), proc.pid());
|
|
||||||
}
|
|
||||||
process->AddUsage(mem_usage);
|
|
||||||
add_mem_usage(&usage_, mem_usage);
|
add_mem_usage(&usage_, mem_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sort(std::function<bool(const ProcessRecord&, const ProcessRecord&)>& sorter) {
|
|
||||||
std::sort(procs_.begin(), procs_.end(), sorter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
MemUsage usage_;
|
MemUsage usage_;
|
||||||
std::vector<ProcessRecord> procs_;
|
std::map<pid_t, ProcessRecord> procs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// List of every library / map
|
// List of every library / map
|
||||||
static std::vector<LibRecord> g_libs;
|
static std::map<std::string, LibRecord> g_libs;
|
||||||
|
|
||||||
// List of library/map names that we don't want to show by default
|
// List of library/map names that we don't want to show by default
|
||||||
static const std::vector<std::string> g_blacklisted_libs = {"[heap]", "[stack]"};
|
static const std::vector<std::string> g_blacklisted_libs = {"[heap]", "[stack]"};
|
||||||
|
|
@ -204,13 +197,10 @@ static bool scan_libs_per_process(pid_t pid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lib = std::find_if(g_libs.begin(), g_libs.end(),
|
auto [it, inserted] =
|
||||||
[&](auto l) -> bool { return map.name == l.name(); });
|
g_libs.insert(std::pair<std::string, LibRecord>(map.name, LibRecord(map.name)));
|
||||||
if (lib == g_libs.end()) {
|
it->second.AddUsage(proc, map.usage);
|
||||||
lib = g_libs.emplace(g_libs.end(), map.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
lib->AddUsage(proc, map.usage);
|
|
||||||
if (!g_has_swap && map.usage.swap) {
|
if (!g_has_swap && map.usage.swap) {
|
||||||
g_has_swap = true;
|
g_has_swap = true;
|
||||||
}
|
}
|
||||||
|
|
@ -321,11 +311,16 @@ int main(int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
printf("Name/PID\n");
|
printf("Name/PID\n");
|
||||||
|
|
||||||
|
std::vector<LibRecord> v_libs;
|
||||||
|
v_libs.reserve(g_libs.size());
|
||||||
|
std::transform(g_libs.begin(), g_libs.end(), std::back_inserter(v_libs),
|
||||||
|
[] (std::pair<std::string, LibRecord> const& pair) { return pair.second; });
|
||||||
|
|
||||||
// sort the libraries by their pss
|
// sort the libraries by their pss
|
||||||
std::sort(g_libs.begin(), g_libs.end(),
|
std::sort(v_libs.begin(), v_libs.end(),
|
||||||
[](const LibRecord& l1, const LibRecord& l2) { return l1.pss() > l2.pss(); });
|
[](const LibRecord& l1, const LibRecord& l2) { return l1.pss() > l2.pss(); });
|
||||||
|
|
||||||
for (auto& lib : g_libs) {
|
for (auto& lib : v_libs) {
|
||||||
printf("%6" PRIu64 "K %7s %6s %6s %6s ", lib.pss() / 1024, "", "", "", "");
|
printf("%6" PRIu64 "K %7s %6s %6s %6s ", lib.pss() / 1024, "", "", "", "");
|
||||||
if (g_has_swap) {
|
if (g_has_swap) {
|
||||||
printf(" %6s ", "");
|
printf(" %6s ", "");
|
||||||
|
|
@ -333,9 +328,15 @@ int main(int argc, char* argv[]) {
|
||||||
printf("%s\n", lib.name().c_str());
|
printf("%s\n", lib.name().c_str());
|
||||||
|
|
||||||
// sort all mappings first
|
// sort all mappings first
|
||||||
lib.Sort(sort_func);
|
|
||||||
|
|
||||||
for (auto& p : lib.processes()) {
|
std::vector<ProcessRecord> procs;
|
||||||
|
procs.reserve(lib.processes().size());
|
||||||
|
std::transform(lib.processes().begin(), lib.processes().end(), std::back_inserter(procs),
|
||||||
|
[] (std::pair<pid_t, ProcessRecord> const& pair) { return pair.second; });
|
||||||
|
|
||||||
|
std::sort(procs.begin(), procs.end(), sort_func);
|
||||||
|
|
||||||
|
for (auto& p : procs) {
|
||||||
const MemUsage& usage = p.usage();
|
const MemUsage& usage = p.usage();
|
||||||
printf(" %6s %7" PRIu64 "K %6" PRIu64 "K %6" PRIu64 "K %6" PRIu64 "K ", "",
|
printf(" %6s %7" PRIu64 "K %6" PRIu64 "K %6" PRIu64 "K %6" PRIu64 "K ", "",
|
||||||
usage.vss / 1024, usage.rss / 1024, usage.pss / 1024, usage.uss / 1024);
|
usage.vss / 1024, usage.rss / 1024, usage.pss / 1024, usage.uss / 1024);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue