Fixed filtering for processes tree view

This commit is contained in:
aristocratos 2021-06-27 22:13:32 +02:00
parent db3bf06485
commit 331665dc55
8 changed files with 52 additions and 44 deletions

View File

@ -390,7 +390,7 @@ int main(int argc, char **argv){
cout << "\nTheme generation of " << fs::path(Config::getS("color_theme")).filename().replace_extension("") << " took " << time_micros() - thts << "μs" << endl;
cout << "Colors:" << endl;
uint i = 0;
size_t i = 0;
for(auto& item : Theme::test_colors()) {
cout << rjust(item.first, 15) << ":" << item.second << ""s * 10 << Fx::reset << " ";
// << Theme::dec(item.first)[0] << ":" << Theme::dec(item.first)[1] << ":" << Theme::dec(item.first)[2] << ;
@ -596,11 +596,11 @@ int main(int argc, char **argv){
uint lc;
size_t lc;
string ostring;
uint64_t tsl, timestamp2, rcount = 0;
list<uint64_t> avgtimes = {0};
uint timer = 2000;
size_t timer = 2000;
bool filtering = false;
vector<string> greyscale;
string filter;
@ -608,7 +608,7 @@ int main(int argc, char **argv){
string key;
int xc;
for (uint i : iota(0, (int)Term::height - 19)){
for (size_t i : iota(0, (int)Term::height - 19)){
xc = 230 - i * 150 / (Term::height - 20);
greyscale.push_back(Theme::dec_to_color(xc, xc, xc));
}

View File

@ -107,12 +107,12 @@ namespace Draw {
out = Fx::reset + lcolor;
//* Draw horizontal lines
for (uint hpos : {c.y, c.y + c.height - 1}){
for (size_t hpos : {c.y, c.y + c.height - 1}){
out += Mv::to(hpos, c.x) + Symbols::h_line * (c.width - 1);
}
//* Draw vertical lines and fill if enabled
for (uint hpos : iota(c.y + 1, c.y + c.height - 1)){
for (size_t hpos : iota(c.y + 1, c.y + c.height - 1)){
out += Mv::to(hpos, c.x) + Symbols::v_line +
((c.fill) ? string(c.width - 2, ' ') : Mv::r(c.width - 2)) +
Symbols::v_line;

View File

@ -40,12 +40,12 @@ namespace Symbols {
namespace Draw {
struct BoxConf {
uint x=0, y=0;
uint width=0, height=0;
size_t x=0, y=0;
size_t width=0, height=0;
string line_color = "", title = "", title2 = "";
bool fill = true;
uint num=0;
uint w_percent=0, h_percent=0;
size_t num=0;
size_t w_percent=0, h_percent=0;
};
//* Create a box using values from a BoxConf struct and return as a string

View File

@ -26,13 +26,6 @@ tab-size = 4
using std::string, robin_hood::unordered_flat_map, std::cin;
using namespace Tools;
/* The input functions relies on the following std::cin options being set:
cin.sync_with_stdio(false);
cin.tie(NULL);
These will automatically be set when running Term::init() from btop_tools.cpp
*/
//* Functions and variables for handling keyboard and mouse input
namespace Input {
namespace {
//* Map for translating key codes to readable values
@ -102,7 +95,6 @@ namespace Input {
return get();
}
//* Clears last entered key
void clear(){
last.clear();
}

View File

@ -100,10 +100,10 @@ namespace Proc {
size_t depth = 0;
bool collapsed = false;
};
unordered_flat_map<uint, p_cache> cache;
unordered_flat_map<size_t, p_cache> cache;
unordered_flat_map<string, string> uid_user;
uint counter = 0;
int counter = 0;
}
uint64_t old_cputimes = 0;
size_t numpids = 500;
@ -121,22 +121,38 @@ namespace Proc {
};
//* Generate process tree list
void _tree_gen(const proc_info& cur_proc, const vector<proc_info>& in_procs, vector<proc_info>& out_procs, const int cur_depth, const bool collapsed, const string& prefix){
void _tree_gen(const proc_info& cur_proc, const vector<proc_info>& in_procs, vector<proc_info>& out_procs, int cur_depth, const bool collapsed, const string& prefix, const string& filter, bool found){
auto cur_pos = out_procs.size();
if (not collapsed)
bool filtering = false;
//? If filtering, include children of matching processes
if (not filter.empty() and not found) {
if (std::to_string(cur_proc.pid).find(filter) == string::npos
and cur_proc.name.find(filter) == string::npos
and cur_proc.cmd.find(filter) == string::npos
and cur_proc.user.find(filter) == string::npos) {
filtering = true;
}
else {
found = true;
cur_depth = 0;
}
}
if (not collapsed and not filtering)
out_procs.push_back(cur_proc);
int children = 0;
for (auto& p : rng::equal_range(in_procs, cur_proc.pid, rng::less{}, &proc_info::ppid)) {
if (collapsed) {
if (collapsed and not filtering) {
out_procs.back().cpu_p += p.cpu_p;
out_procs.back().mem += p.mem;
out_procs.back().threads += p.threads;
}
else children++;
_tree_gen(p, in_procs, out_procs, cur_depth + 1, (collapsed ? true : cache.at(cur_proc.pid).collapsed), prefix);
_tree_gen(p, in_procs, out_procs, cur_depth + 1, (collapsed ? true : cache.at(cur_proc.pid).collapsed), prefix, filter, found);
}
if (collapsed) return;
if (collapsed or filtering) return;
if (out_procs.size() > cur_pos + 1 and not out_procs.back().prefix.ends_with("] "))
out_procs.back().prefix.replace(out_procs.back().prefix.size() - 8, 8, " └─ ");
@ -248,7 +264,7 @@ namespace Proc {
}
//* Match filter if defined
if (not filter.empty()
if (not tree and not filter.empty()
and pid_str.find(filter) == string::npos
and cache[new_proc.pid].name.find(filter) == string::npos
and cache[new_proc.pid].cmd.find(filter) == string::npos
@ -390,7 +406,7 @@ namespace Proc {
string prefix = " ├─ ";
//? Start recursive iteration over processes with the lowest shared parent pids
for (auto& p : rng::equal_range(procs, procs.at(0).ppid, rng::less{}, &proc_info::ppid)) {
_tree_gen(p, procs, tree_procs, 0, cache.at(p.pid).collapsed, prefix);
_tree_gen(p, procs, tree_procs, 0, cache.at(p.pid).collapsed, prefix, filter, false);
}
procs.swap(tree_procs);
}
@ -399,7 +415,7 @@ namespace Proc {
//* Clear dead processes from cache at a regular interval
if (++counter >= 10000 or ((int)cache.size() > npids + 100)) {
counter = 0;
unordered_flat_map<uint, p_cache> r_cache;
unordered_flat_map<size_t, p_cache> r_cache;
r_cache.reserve(procs.size());
rng::for_each(procs, [&r_cache](const auto &p){
if (cache.contains(p.pid))

View File

@ -49,7 +49,7 @@ namespace Proc {
//* Container for process information
struct proc_info {
uint64_t pid;
size_t pid;
string name = "", cmd = "";
size_t threads = 0;
string user = "";

View File

@ -85,8 +85,8 @@ namespace Term {
bool initialized = false;
bool resized = false;
uint width = 0;
uint height = 0;
size_t width = 0;
size_t height = 0;
string fg, bg, current_tty;
const string hide_cursor = Fx::e + "?25l";
@ -252,7 +252,7 @@ namespace Tools {
return out;
}
void sleep_ms(const uint& ms) {
void sleep_ms(const size_t& ms) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
@ -293,9 +293,9 @@ namespace Tools {
return (newstr.empty()) ? str : newstr + (string)oldstr;
}
string sec_to_dhms(uint sec){
string sec_to_dhms(size_t sec){
string out;
uint d, h, m;
size_t d, h, m;
d = sec / (3600 * 24);
sec %= 3600 * 24;
h = sec / 3600;
@ -309,9 +309,9 @@ namespace Tools {
return out;
}
string floating_humanizer(uint64_t value, bool shorten, uint start, bool bit, bool per_second){
string floating_humanizer(uint64_t value, bool shorten, size_t start, bool bit, bool per_second){
string out;
uint mult = (bit) ? 8 : 1;
size_t mult = (bit) ? 8 : 1;
static const array<string, 11> Units_bit = {"bit", "Kib", "Mib", "Gib", "Tib", "Pib", "Eib", "Zib", "Yib", "Bib", "GEb"};
static const array<string, 11> Units_byte = {"Byte", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", "BiB", "GEB"};
auto& units = (bit) ? Units_bit : Units_byte;
@ -402,7 +402,7 @@ namespace Logger {
loglevel = v_index(log_levels, level);
}
void log_write(uint level, string& msg){
void log_write(size_t level, string& msg){
if (loglevel < level or logfile.empty()) return;
atomic_wait_set(busy, true);
std::error_code ec;

View File

@ -91,8 +91,8 @@ namespace Mv {
namespace Term {
extern bool initialized;
extern bool resized;
extern uint width;
extern uint height;
extern size_t width;
extern size_t height;
extern string fg, bg, current_tty;
//* Hide terminal cursor
@ -198,7 +198,7 @@ namespace Tools {
vector<string> ssplit(const string& str, const char delim = ' ');
//* Put current thread to sleep for <ms> milliseconds
void sleep_ms(const uint& ms);
void sleep_ms(const size_t& ms);
//* Left justify string <str> if <x> is greater than <str> length, limit return size to <x> by default
string ljust(string str, const size_t x, bool utf=false, bool escape=false, bool lim=true);
@ -210,13 +210,13 @@ namespace Tools {
string trans(const string& str);
//* Convert seconds to format "Xd HH:MM:SS" and return string
string sec_to_dhms(uint sec);
string sec_to_dhms(size_t sec);
//* Scales up in steps of 1024 to highest possible unit and returns string with unit suffixed
//* bit=True or defaults to bytes
//* start=int to set 1024 multiplier starting unit
//* short=True always returns 0 decimals and shortens unit to 1 character
string floating_humanizer(uint64_t value, bool shorten=false, uint start=0, bool bit=false, bool per_second=false);
string floating_humanizer(uint64_t value, bool shorten=false, size_t start=0, bool bit=false, bool per_second=false);
//* Add std::string operator "*" : Repeat string <str> <n> number of times
std::string operator*(string str, size_t n);
@ -229,7 +229,7 @@ namespace Tools {
//* Waits for <atom> to not be <val> and then sets it to <val> again
void atomic_wait_set(std::atomic<bool>& atom, bool val=true);
}
//* Simple logging implementation
@ -238,7 +238,7 @@ namespace Logger {
extern std::filesystem::path logfile;
void set(string level); //* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG"
void log_write(uint level, string& msg);
void log_write(size_t level, string& msg);
void error(string msg);
void warning(string msg);
void info(string msg);