Revert "Replace robin_hood map and set with STD alternative and add safeVal() function for map/vector access with fallback"

This reverts commit 6c87ab6196.
This commit is contained in:
aristocratos 2023-12-25 02:27:38 +01:00
parent 6c87ab6196
commit e15e0b7188
19 changed files with 214 additions and 261 deletions

View file

@ -61,10 +61,6 @@ CLANG_WORKS = false
GCC_WORKS = false
MIN_CLANG_VERSION = 16
ifeq ($(DEBUG),true)
override ADDFLAGS += -DBTOP_DEBUG
endif
#? Supported is Clang 16.0.0 and later
ifeq ($(CXX_IS_CLANG),true)
ifeq ($(shell $(CXX) --version | grep Apple >/dev/null 2>&1; echo $$?),0)
@ -283,13 +279,13 @@ directories:
clean:
@printf "\033[1;91mRemoving: \033[1;97mbuilt objects...\033[0m\n"
@rm -rf $(BUILDDIR)
@test -e lib/rocm_smi_lib/build && cmake --build lib/rocm_smi_lib/build --target clean &> /dev/null || true
@cmake --build lib/rocm_smi_lib/build --target clean &> /dev/null || true
#? Clean Objects and Binaries
distclean: clean
@printf "\033[1;91mRemoving: \033[1;97mbuilt binaries...\033[0m\n"
@rm -rf $(TARGETDIR)
@test -e lib/rocm_smi_lib/build && rm -rf lib/rocm_smi_lib/build || true
@rm -rf lib/rocm_smi_lib/build
install:
@printf "\033[1;92mInstalling binary to: \033[1;97m$(DESTDIR)$(PREFIX)/bin/btop\n"

View file

@ -32,7 +32,6 @@ tab-size = 4
#include <tuple>
#include <regex>
#include <chrono>
#include <utility>
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#include <mach-o/dyld.h>
@ -417,7 +416,7 @@ namespace Runner {
};
string debug_bg;
std::unordered_map<string, array<uint64_t, 2>> debug_times;
unordered_flat_map<string, array<uint64_t, 2>> debug_times;
class MyNumPunct : public std::numpunct<char>
{

View file

@ -21,7 +21,6 @@ tab-size = 4
#include <fstream>
#include <ranges>
#include <string_view>
#include <utility>
#include <fmt/core.h>
@ -216,7 +215,7 @@ namespace Config {
#endif
};
std::unordered_map<std::string_view, string> strings = {
unordered_flat_map<std::string_view, string> strings = {
{"color_theme", "Default"},
{"shown_boxes", "cpu mem net proc"},
{"graph_symbol", "braille"},
@ -252,9 +251,9 @@ namespace Config {
{"show_gpu_info", "Auto"}
#endif
};
std::unordered_map<std::string_view, string> stringsTmp;
unordered_flat_map<std::string_view, string> stringsTmp;
std::unordered_map<std::string_view, bool> bools = {
unordered_flat_map<std::string_view, bool> bools = {
{"theme_background", true},
{"truecolor", true},
{"rounded_corners", true},
@ -305,9 +304,9 @@ namespace Config {
{"gpu_mirror_graph", true},
#endif
};
std::unordered_map<std::string_view, bool> boolsTmp;
unordered_flat_map<std::string_view, bool> boolsTmp;
std::unordered_map<std::string_view, int> ints = {
unordered_flat_map<std::string_view, int> ints = {
{"update_ms", 2000},
{"net_download", 100},
{"net_upload", 100},
@ -318,7 +317,7 @@ namespace Config {
{"proc_selected", 0},
{"proc_last_selected", 0},
};
std::unordered_map<std::string_view, int> intsTmp;
unordered_flat_map<std::string_view, int> intsTmp;
bool _locked(const std::string_view name) {
atomic_wait(writelock, true);

View file

@ -22,10 +22,11 @@ tab-size = 4
#include <vector>
#include <filesystem>
#include <unordered_map>
#include <robin_hood.h>
using std::string;
using std::vector;
using robin_hood::unordered_flat_map;
//* Functions and variables for reading and writing the btop config file
namespace Config {
@ -33,12 +34,12 @@ namespace Config {
extern std::filesystem::path conf_dir;
extern std::filesystem::path conf_file;
extern std::unordered_map<std::string_view, string> strings;
extern std::unordered_map<std::string_view, string> stringsTmp;
extern std::unordered_map<std::string_view, bool> bools;
extern std::unordered_map<std::string_view, bool> boolsTmp;
extern std::unordered_map<std::string_view, int> ints;
extern std::unordered_map<std::string_view, int> intsTmp;
extern unordered_flat_map<std::string_view, string> strings;
extern unordered_flat_map<std::string_view, string> stringsTmp;
extern unordered_flat_map<std::string_view, bool> bools;
extern unordered_flat_map<std::string_view, bool> boolsTmp;
extern unordered_flat_map<std::string_view, int> ints;
extern unordered_flat_map<std::string_view, int> intsTmp;
const vector<string> valid_graph_symbols = { "braille", "block", "tty" };
const vector<string> valid_graph_symbols_def = { "default", "braille", "block", "tty" };

View file

@ -22,7 +22,6 @@ tab-size = 4
#include <ranges>
#include <stdexcept>
#include <string>
#include <utility>
#include "btop_draw.hpp"
#include "btop_config.hpp"
@ -55,7 +54,7 @@ namespace Symbols {
const array<string, 10> superscript = { "", "¹", "²", "³", "", "", "", "", "", "" };
const std::unordered_map<string, vector<string>> graph_symbols = {
const unordered_flat_map<string, vector<string>> graph_symbols = {
{ "braille_up", {
" ", "", "", "", "",
"", "", "", "", "",
@ -301,7 +300,7 @@ namespace Draw {
return false;
}
static const std::unordered_map<string, string> clock_custom_format = {
static const unordered_flat_map<string, string> clock_custom_format = {
{"/user", Tools::username()},
{"/host", Tools::hostname()},
{"/uptime", ""}
@ -561,12 +560,12 @@ namespace Cpu {
const string& title_left = Theme::c("cpu_box") + (cpu_bottom ? Symbols::title_left_down : Symbols::title_left);
const string& title_right = Theme::c("cpu_box") + (cpu_bottom ? Symbols::title_right_down : Symbols::title_right);
static int bat_pos = 0, bat_len = 0;
if (safeVal(cpu.cpu_percent, "total"s).empty()
or safeVal(cpu.core_percent, 0).empty()
or (show_temps and safeVal(cpu.temp, 0).empty())) return "";
if (safeVal(cpu.cpu_percent, "total"s).empty()
or safeVal(cpu.core_percent, 0).empty()
or (show_temps and safeVal(cpu.temp, 0).empty())) return "";
if (cpu.cpu_percent.at("total").empty()
or cpu.core_percent.at(0).empty()
or (show_temps and cpu.temp.at(0).empty())) return "";
if (cpu.cpu_percent.at("total").empty()
or cpu.core_percent.at(0).empty()
or (show_temps and cpu.temp.at(0).empty())) return "";
string out;
out.reserve(width * height);
@ -609,7 +608,7 @@ namespace Cpu {
if (gpu.supported_functions.temp_info)
gpu_temp_graphs[i] = Draw::Graph{ 5, 1, "temp", gpu.temp, graph_symbol, false, false, gpu.temp_max, -23 };
if (gpu.supported_functions.mem_used and gpu.supported_functions.mem_total)
gpu_mem_graphs[i] = Draw::Graph{ 5, 1, "used", safeVal(gpu.gpu_percent, "gpu-vram-totals"s), graph_symbol };
gpu_mem_graphs[i] = Draw::Graph{ 5, 1, "used", gpu.gpu_percent.at("gpu-vram-totals"), graph_symbol };
if (gpu.supported_functions.gpu_utilization) {
gpu_meter_width = b_width - 12 - (int)floating_humanizer(gpu.mem_total, true).size() - (show_temps ? 24 : 12) - (int)to_string(i).size() + (gpus.size() == 1)*2 - (gpus.size() > 9 and i <= 9);
gpu_meters[i] = Draw::Meter{gpu_meter_width, "cpu" };
@ -618,12 +617,12 @@ namespace Cpu {
bool utilization_support = gpu.supported_functions.gpu_utilization;
if (++i < gpus.size()) {
if (utilization_support)
graph = Draw::Graph{graph_width, graph_height, "cpu", safeVal(gpu.gpu_percent, graph_field), graph_symbol, invert, true};
graph = Draw::Graph{graph_width, graph_height, "cpu", gpu.gpu_percent.at(graph_field), graph_symbol, invert, true};
} else {
if (utilization_support)
graph = Draw::Graph{
graph_width + graph_default_width%graph_width - (int)gpus.size() + 1,
graph_height, "cpu", safeVal(gpu.gpu_percent, graph_field), graph_symbol, invert, true
graph_height, "cpu", gpu.gpu_percent.at(graph_field), graph_symbol, invert, true
};
break;
}
@ -631,7 +630,7 @@ namespace Cpu {
} else {
graphs.resize(1);
graph_width = graph_default_width;
graphs[0] = Draw::Graph{ graph_width, graph_height, "cpu", safeVal(Gpu::shared_gpu_percent, graph_field), graph_symbol, invert, true };
graphs[0] = Draw::Graph{ graph_width, graph_height, "cpu", Gpu::shared_gpu_percent.at(graph_field), graph_symbol, invert, true };
gpu_temp_graphs.resize(gpus.size());
gpu_mem_graphs.resize(gpus.size());
gpu_meters.resize(gpus.size());
@ -639,7 +638,7 @@ namespace Cpu {
if (gpus[i].supported_functions.temp_info)
gpu_temp_graphs[i] = Draw::Graph{ 5, 1, "temp", gpus[i].temp, graph_symbol, false, false, gpus[i].temp_max, -23 };
if (gpus[i].supported_functions.mem_used and gpus[i].supported_functions.mem_total)
gpu_mem_graphs[i] = Draw::Graph{ 5, 1, "used", safeVal(gpus[i].gpu_percent, "gpu-vram-totals"s), graph_symbol };
gpu_mem_graphs[i] = Draw::Graph{ 5, 1, "used", gpus[i].gpu_percent.at("gpu-vram-totals"), graph_symbol };
if (gpus[i].supported_functions.gpu_utilization) {
gpu_meter_width = b_width - 12 - (int)floating_humanizer(gpus[i].mem_total, true).size() - (show_temps ? 24 : 12) - (int)to_string(i).size() + (gpus.size() == 1)*2 - (gpus.size() > 9 and i <= 9);
gpu_meters[i] = Draw::Meter{gpu_meter_width, "cpu" };
@ -650,7 +649,7 @@ namespace Cpu {
#endif
graphs.resize(1);
graph_width = graph_default_width;
graphs[0] = Draw::Graph{ graph_width, graph_height, "cpu", safeVal(cpu.cpu_percent, graph_field), graph_symbol, invert, true };
graphs[0] = Draw::Graph{ graph_width, graph_height, "cpu", cpu.cpu_percent.at(graph_field), graph_symbol, invert, true };
#ifdef GPU_SUPPORT
if (std::cmp_less(Gpu::shown, gpus.size())) {
gpu_temp_graphs.resize(gpus.size());
@ -660,7 +659,7 @@ namespace Cpu {
if (gpus[i].supported_functions.temp_info)
gpu_temp_graphs[i] = Draw::Graph{ 5, 1, "temp", gpus[i].temp, graph_symbol, false, false, gpus[i].temp_max, -23 };
if (gpus[i].supported_functions.mem_used and gpus[i].supported_functions.mem_total)
gpu_mem_graphs[i] = Draw::Graph{ 5, 1, "used", safeVal(gpus[i].gpu_percent, "gpu-vram-totals"s), graph_symbol };
gpu_mem_graphs[i] = Draw::Graph{ 5, 1, "used", gpus[i].gpu_percent.at("gpu-vram-totals"), graph_symbol };
if (gpus[i].supported_functions.gpu_utilization) {
gpu_meter_width = b_width - 12 - (int)floating_humanizer(gpus[i].mem_total, true).size() - (show_temps ? 24 : 12) - (int)to_string(i).size() + (gpus.size() == 1)*2 - (gpus.size() > 9 and i <= 9);
gpu_meters[i] = Draw::Meter{gpu_meter_width, "cpu" };
@ -693,10 +692,10 @@ namespace Cpu {
if (show_temps) {
temp_graphs.clear();
temp_graphs.emplace_back(5, 1, "temp", safeVal(cpu.temp, 0), graph_symbol, false, false, cpu.temp_max, -23);
temp_graphs.emplace_back(5, 1, "temp", cpu.temp.at(0), graph_symbol, false, false, cpu.temp_max, -23);
if (not hide_cores and b_column_size > 1) {
for (const auto& i : iota((size_t)1, cpu.temp.size())) {
temp_graphs.emplace_back(5, 1, "temp", safeVal(cpu.temp, i), graph_symbol, false, false, cpu.temp_max, -23);
temp_graphs.emplace_back(5, 1, "temp", cpu.temp.at(i), graph_symbol, false, false, cpu.temp_max, -23);
}
}
}
@ -708,7 +707,7 @@ namespace Cpu {
static long old_seconds{}; // defaults to = 0
static string old_status;
static Draw::Meter bat_meter {10, "cpu", true};
static const std::unordered_map<string, string> bat_symbols = {
static const unordered_flat_map<string, string> bat_symbols = {
{"charging", ""},
{"discharging", ""},
{"full", ""},
@ -750,7 +749,7 @@ namespace Cpu {
if (graph_field.starts_with("gpu"))
if (graph_field.find("totals") != string::npos)
for (unsigned long i = 0;;) {
out += graphs[i](safeVal(gpus[i].gpu_percent, graph_field), (data_same or redraw));
out += graphs[i](gpus[i].gpu_percent.at(graph_field), (data_same or redraw));
if (gpus.size() > 1) {
auto i_str = to_string(i);
out += Mv::l(graph_width-1) + Mv::u(graph_height/2) + (graph_width > 5 ? "GPU " : "") + i_str
@ -762,13 +761,13 @@ namespace Cpu {
else break;
}
else
out += graphs[0](safeVal(Gpu::shared_gpu_percent, graph_field), (data_same or redraw));
out += graphs[0](Gpu::shared_gpu_percent.at(graph_field), (data_same or redraw));
else
#else
(void)graph_height;
(void)graph_width;
#endif
out += graphs[0](safeVal(cpu.cpu_percent, graph_field), (data_same or redraw));
out += graphs[0](cpu.cpu_percent.at(graph_field), (data_same or redraw));
};
draw_graphs(graphs_upper, graph_up_height, graph_up_width, graph_up_field);
@ -793,14 +792,14 @@ namespace Cpu {
out += Mv::to(b_y, b_x + b_width - 10) + Fx::ub + Theme::c("div_line") + Symbols::h_line * (7 - cpuHz.size())
+ Symbols::title_left + Fx::b + Theme::c("title") + cpuHz + Fx::ub + Theme::c("div_line") + Symbols::title_right;
out += Mv::to(b_y + 1, b_x + 1) + Theme::c("main_fg") + Fx::b + "CPU " + cpu_meter(safeVal(cpu.cpu_percent, "total"s).back())
+ Theme::g("cpu").at(clamp(safeVal(cpu.cpu_percent, "total"s).back(), 0ll, 100ll)) + rjust(to_string(safeVal(cpu.cpu_percent, "total"s).back()), 4) + Theme::c("main_fg") + '%';
out += Mv::to(b_y + 1, b_x + 1) + Theme::c("main_fg") + Fx::b + "CPU " + cpu_meter(cpu.cpu_percent.at("total").back())
+ Theme::g("cpu").at(clamp(cpu.cpu_percent.at("total").back(), 0ll, 100ll)) + rjust(to_string(cpu.cpu_percent.at("total").back()), 4) + Theme::c("main_fg") + '%';
if (show_temps) {
const auto [temp, unit] = celsius_to(safeVal(cpu.temp, 0).back(), temp_scale);
const auto& temp_color = Theme::g("temp").at(clamp(safeVal(cpu.temp, 0).back() * 100 / cpu.temp_max, 0ll, 100ll));
const auto [temp, unit] = celsius_to(cpu.temp.at(0).back(), temp_scale);
const auto& temp_color = Theme::g("temp").at(clamp(cpu.temp.at(0).back() * 100 / cpu.temp_max, 0ll, 100ll));
if (b_column_size > 1 or b_columns > 1)
out += ' ' + Theme::c("inactive_fg") + graph_bg * 5 + Mv::l(5) + temp_color
+ safeVal(temp_graphs, 0)(safeVal(cpu.temp, 0), data_same or redraw);
+ temp_graphs.at(0)(cpu.temp.at(0), data_same or redraw);
out += rjust(to_string(temp), 4) + Theme::c("main_fg") + unit;
}
out += Theme::c("div_line") + Symbols::v_line;
@ -815,17 +814,17 @@ namespace Cpu {
+ ljust(to_string(n), core_width);
if (b_column_size > 0 or extra_width > 0)
out += Theme::c("inactive_fg") + graph_bg * (5 * b_column_size + extra_width) + Mv::l(5 * b_column_size + extra_width)
+ safeVal(core_graphs, n)(safeVal(cpu.core_percent, n), data_same or redraw);
+ core_graphs.at(n)(cpu.core_percent.at(n), data_same or redraw);
out += Theme::g("cpu").at(clamp(safeVal(cpu.core_percent, n).back(), 0ll, 100ll));
out += rjust(to_string(safeVal(cpu.core_percent, n).back()), (b_column_size < 2 ? 3 : 4)) + Theme::c("main_fg") + '%';
out += Theme::g("cpu").at(clamp(cpu.core_percent.at(n).back(), 0ll, 100ll));
out += rjust(to_string(cpu.core_percent.at(n).back()), (b_column_size < 2 ? 3 : 4)) + Theme::c("main_fg") + '%';
if (show_temps and not hide_cores) {
const auto [temp, unit] = celsius_to(safeVal(cpu.temp, n+1).back(), temp_scale);
const auto& temp_color = Theme::g("temp").at(clamp(safeVal(cpu.temp, n+1).back() * 100 / cpu.temp_max, 0ll, 100ll));
const auto [temp, unit] = celsius_to(cpu.temp.at(n+1).back(), temp_scale);
const auto& temp_color = Theme::g("temp").at(clamp(cpu.temp.at(n+1).back() * 100 / cpu.temp_max, 0ll, 100ll));
if (b_column_size > 1)
out += ' ' + Theme::c("inactive_fg") + graph_bg * 5 + Mv::l(5)
+ safeVal(temp_graphs, n+1)(safeVal(cpu.temp, n+1), data_same or redraw);
+ temp_graphs.at(n+1)(cpu.temp.at(n+1), data_same or redraw);
out += temp_color + rjust(to_string(temp), 4) + Theme::c("main_fg") + unit;
}
@ -883,14 +882,14 @@ namespace Cpu {
}
if (gpus.size() > 1) out += rjust(to_string(i), 1 + (gpus.size() > 9));
if (gpus[i].supported_functions.gpu_utilization) {
string meter = gpu_meters[i](safeVal(gpus[i].gpu_percent, "gpu-totals"s).back());
string meter = gpu_meters[i](gpus[i].gpu_percent.at("gpu-totals").back());
out += (meter.size() > 1 ? " " : "") + meter
+ Theme::g("cpu").at(clamp(safeVal(gpus[i].gpu_percent, "gpu-totals"s).back(), 0ll, 100ll)) + rjust(to_string(safeVal(gpus[i].gpu_percent, "gpu-totals"s).back()), 4) + Theme::c("main_fg") + '%';
+ Theme::g("cpu").at(gpus[i].gpu_percent.at("gpu-totals").back()) + rjust(to_string(gpus[i].gpu_percent.at("gpu-totals").back()), 4) + Theme::c("main_fg") + '%';
} else out += Mv::r(gpu_meter_width);
if (gpus[i].supported_functions.mem_used) {
out += ' ' + Theme::c("inactive_fg") + graph_bg * 6 + Mv::l(6) + Theme::g("used").at(safeVal(gpus[i].gpu_percent, "gpu-vram-totals"s).back())
+ gpu_mem_graphs[i](safeVal(gpus[i].gpu_percent, "gpu-vram-totals"s), data_same or redraw) + Theme::c("main_fg")
out += ' ' + Theme::c("inactive_fg") + graph_bg * 6 + Mv::l(6) + Theme::g("used").at(gpus[i].gpu_percent.at("gpu-vram-totals").back())
+ gpu_mem_graphs[i](gpus[i].gpu_percent.at("gpu-vram-totals"), data_same or redraw) + Theme::c("main_fg")
+ rjust(floating_humanizer(gpus[i].mem_used, true), 5);
if (gpus[i].supported_functions.mem_total)
out += Theme::c("inactive_fg") + '/' + Theme::c("main_fg") + floating_humanizer(gpus[i].mem_total, true);
@ -968,12 +967,12 @@ namespace Gpu {
out += box[index];
if (gpu.supported_functions.gpu_utilization) {
graph_upper = Draw::Graph{x + width - b_width - 3, graph_up_height, "cpu", safeVal(gpu.gpu_percent, "gpu-totals"s), graph_symbol, false, true}; // TODO cpu -> gpu
graph_upper = Draw::Graph{x + width - b_width - 3, graph_up_height, "cpu", gpu.gpu_percent.at("gpu-totals"), graph_symbol, false, true}; // TODO cpu -> gpu
if (not single_graph) {
graph_lower = Draw::Graph{
x + width - b_width - 3,
graph_low_height, "cpu",
safeVal(gpu.gpu_percent, "gpu-totals"s),
gpu.gpu_percent.at("gpu-totals"),
graph_symbol,
Config::getB("cpu_invert_lower"), true
};
@ -987,7 +986,7 @@ namespace Gpu {
if (gpu.supported_functions.mem_utilization)
mem_util_graph = Draw::Graph{b_width/2 - 1, 2, "free", gpu.mem_utilization_percent, graph_symbol, 0, 0, 100, 4}; // offset so the graph isn't empty at 0-5% utilization
if (gpu.supported_functions.mem_used and gpu.supported_functions.mem_total)
mem_used_graph = Draw::Graph{b_width/2 - 2, 2 + 2*(gpu.supported_functions.mem_utilization), "used", safeVal(gpu.gpu_percent, "gpu-vram-totals"s), graph_symbol};
mem_used_graph = Draw::Graph{b_width/2 - 2, 2 + 2*(gpu.supported_functions.mem_utilization), "used", gpu.gpu_percent.at("gpu-vram-totals"), graph_symbol};
}
@ -995,12 +994,12 @@ namespace Gpu {
//? Gpu graph, meter & clock speed
if (gpu.supported_functions.gpu_utilization) {
out += Fx::ub + Mv::to(y + 1, x + 1) + graph_upper(safeVal(gpu.gpu_percent, "gpu-totals"s), (data_same or redraw[index]));
out += Fx::ub + Mv::to(y + 1, x + 1) + graph_upper(gpu.gpu_percent.at("gpu-totals"), (data_same or redraw[index]));
if (not single_graph)
out += Mv::to(y + graph_up_height + 1, x + 1) + graph_lower(safeVal(gpu.gpu_percent, "gpu-totals"s), (data_same or redraw[index]));
out += Mv::to(y + graph_up_height + 1, x + 1) + graph_lower(gpu.gpu_percent.at("gpu-totals"), (data_same or redraw[index]));
out += Mv::to(b_y + 1, b_x + 1) + Theme::c("main_fg") + Fx::b + "GPU " + gpu_meter(safeVal(gpu.gpu_percent, "gpu-totals"s).back())
+ Theme::g("cpu").at(clamp(safeVal(gpu.gpu_percent, "gpu-totals"s).back(), 0ll, 100ll)) + rjust(to_string(safeVal(gpu.gpu_percent, "gpu-totals"s).back()), 4) + Theme::c("main_fg") + '%';
out += Mv::to(b_y + 1, b_x + 1) + Theme::c("main_fg") + Fx::b + "GPU " + gpu_meter(gpu.gpu_percent.at("gpu-totals").back())
+ Theme::g("cpu").at(gpu.gpu_percent.at("gpu-totals").back()) + rjust(to_string(gpu.gpu_percent.at("gpu-totals").back()), 4) + Theme::c("main_fg") + '%';
//? Temperature graph, I assume the device supports utilization if it supports temperature
if (show_temps) {
@ -1020,10 +1019,10 @@ namespace Gpu {
//? Power usage meter, power state
if (gpu.supported_functions.pwr_usage) {
out += Mv::to(b_y + 2, b_x + 1) + Theme::c("main_fg") + Fx::b + "PWR " + pwr_meter(safeVal(gpu.gpu_percent, "gpu-pwr-totals"s).back())
+ Theme::g("cached").at(clamp(safeVal(gpu.gpu_percent, "gpu-pwr-totals"s).back(), 0ll, 100ll)) + rjust(to_string(gpu.pwr_usage/1000), 4) + Theme::c("main_fg") + 'W';
out += Mv::to(b_y + 2, b_x + 1) + Theme::c("main_fg") + Fx::b + "PWR " + pwr_meter(gpu.gpu_percent.at("gpu-pwr-totals").back())
+ Theme::g("cached").at(gpu.gpu_percent.at("gpu-pwr-totals").back()) + rjust(to_string(gpu.pwr_usage/1000), 4) + Theme::c("main_fg") + 'W';
if (gpu.supported_functions.pwr_state and gpu.pwr_state != 32) // NVML_PSTATE_UNKNOWN; unsupported or non-nvidia card
out += std::string(" P-state: ") + (gpu.pwr_state > 9 ? "" : " ") + 'P' + Theme::g("cached").at(clamp(gpu.pwr_state, 0ll, 100ll)) + to_string(gpu.pwr_state);
out += std::string(" P-state: ") + (gpu.pwr_state > 9 ? "" : " ") + 'P' + Theme::g("cached").at(gpu.pwr_state) + to_string(gpu.pwr_state);
}
if (gpu.supported_functions.mem_total or gpu.supported_functions.mem_used) {
@ -1039,9 +1038,9 @@ namespace Gpu {
+ Symbols::h_line*(b_width/2-8) + Symbols::div_up + Mv::d(offset)+Mv::l(1) + Symbols::div_down + Mv::l(1)+Mv::u(1) + (Symbols::v_line + Mv::l(1)+Mv::u(1))*(offset-1) + Symbols::div_up
+ Symbols::h_line + Theme::c("title") + "Used:" + Theme::c("div_line")
+ Symbols::h_line*(b_width/2+b_width%2-9-used_memory_string.size()) + Theme::c("title") + used_memory_string + Theme::c("div_line") + Symbols::h_line + Symbols::div_right
+ Mv::d(1) + Mv::l(b_width/2-1) + mem_used_graph(safeVal(gpu.gpu_percent, "gpu-vram-totals"s), (data_same or redraw[index]))
+ Mv::d(1) + Mv::l(b_width/2-1) + mem_used_graph(gpu.gpu_percent.at("gpu-vram-totals"), (data_same or redraw[index]))
+ Mv::l(b_width-3) + Mv::u(1+2*gpu.supported_functions.mem_utilization) + Theme::c("main_fg") + Fx::b + "Total:" + rjust(floating_humanizer(gpu.mem_total), b_width/2-9) + Fx::ub
+ Mv::r(3) + rjust(to_string(safeVal(gpu.gpu_percent, "gpu-vram-totals"s).back()), 3) + '%';
+ Mv::r(3) + rjust(to_string(gpu.gpu_percent.at("gpu-vram-totals").back()), 3) + '%';
//? Memory utilization
if (gpu.supported_functions.mem_utilization)
@ -1097,11 +1096,11 @@ namespace Mem {
int disks_io_half = 0;
bool shown = true, redraw = true;
string box;
std::unordered_map<string, Draw::Meter> mem_meters;
std::unordered_map<string, Draw::Graph> mem_graphs;
std::unordered_map<string, Draw::Meter> disk_meters_used;
std::unordered_map<string, Draw::Meter> disk_meters_free;
std::unordered_map<string, Draw::Graph> io_graphs;
unordered_flat_map<string, Draw::Meter> mem_meters;
unordered_flat_map<string, Draw::Graph> mem_graphs;
unordered_flat_map<string, Draw::Meter> disk_meters_used;
unordered_flat_map<string, Draw::Meter> disk_meters_free;
unordered_flat_map<string, Draw::Graph> io_graphs;
string draw(const mem_info& mem, bool force_redraw, bool data_same) {
if (Runner::stopping) return "";
@ -1133,14 +1132,14 @@ namespace Mem {
for (const auto& name : mem_names) {
if (use_graphs)
mem_graphs[name] = Draw::Graph{mem_meter, graph_height, name, safeVal(mem.percent, name), graph_symbol};
mem_graphs[name] = Draw::Graph{mem_meter, graph_height, name, mem.percent.at(name), graph_symbol};
else
mem_meters[name] = Draw::Meter{mem_meter, name};
}
if (show_swap and has_swap) {
for (const auto& name : swap_names) {
if (use_graphs)
mem_graphs[name] = Draw::Graph{mem_meter, graph_height, name.substr(5), safeVal(mem.percent, name), graph_symbol};
mem_graphs[name] = Draw::Graph{mem_meter, graph_height, name.substr(5), mem.percent.at(name), graph_symbol};
else
mem_meters[name] = Draw::Meter{mem_meter, name.substr(5)};
}
@ -1149,7 +1148,7 @@ namespace Mem {
//? Disk meters and io graphs
if (show_disks) {
if (show_io_stat or io_mode) {
std::unordered_map<string, int> custom_speeds;
unordered_flat_map<string, int> custom_speeds;
int half_height = 0;
if (io_mode) {
disks_io_h = max((int)floor((double)(height - 2 - (disk_ios * 2)) / max(1, disk_ios)), (io_graph_combined ? 1 : 2));
@ -1231,7 +1230,7 @@ namespace Mem {
if (graph_height > 0) out += Mv::to(y+1+cy, x+1+cx) + divider;
cy += 1;
}
out += Mv::to(y+1+cy, x+1+cx) + Theme::c("title") + Fx::b + "Swap:" + rjust(floating_humanizer(safeVal(mem.stats, "swap_total"s)), mem_width - 8)
out += Mv::to(y+1+cy, x+1+cx) + Theme::c("title") + Fx::b + "Swap:" + rjust(floating_humanizer(mem.stats.at("swap_total")), mem_width - 8)
+ Theme::c("main_fg") + Fx::ub;
cy += 1;
title = "Used";
@ -1240,13 +1239,13 @@ namespace Mem {
title = "Free";
if (title.empty()) title = capitalize(name);
const string humanized = floating_humanizer(safeVal(mem.stats, name));
const string humanized = floating_humanizer(mem.stats.at(name));
const int offset = max(0, divider.empty() ? 9 - (int)humanized.size() : 0);
const string graphics = (use_graphs ? safeVal(mem_graphs, name)(safeVal(mem.percent, name), redraw or data_same) : safeVal(mem_meters, name)(safeVal(mem.percent, name).back()));
const string graphics = (use_graphs ? mem_graphs.at(name)(mem.percent.at(name), redraw or data_same) : mem_meters.at(name)(mem.percent.at(name).back()));
if (mem_size > 2) {
out += Mv::to(y+1+cy, x+1+cx) + divider + title.substr(0, big_mem ? 10 : 5) + ":"
+ Mv::to(y+1+cy, x+cx + mem_width - 2 - humanized.size()) + (divider.empty() ? Mv::l(offset) + string(" ") * offset + humanized : trans(humanized))
+ Mv::to(y+2+cy, x+cx + (graph_height >= 2 ? 0 : 1)) + graphics + up + rjust(to_string(safeVal(mem.percent, name).back()) + "%", 4);
+ Mv::to(y+2+cy, x+cx + (graph_height >= 2 ? 0 : 1)) + graphics + up + rjust(to_string(mem.percent.at(name).back()) + "%", 4);
cy += (graph_height == 0 ? 2 : graph_height + 1);
}
else {
@ -1269,7 +1268,7 @@ namespace Mem {
for (const auto& mount : mem.disks_order) {
if (not disks.contains(mount)) continue;
if (cy > height - 3) break;
const auto& disk = safeVal(disks, mount);
const auto& disk = disks.at(mount);
if (disk.io_read.empty()) continue;
const string total = floating_humanizer(disk.total, not big_disk);
out += Mv::to(y+1+cy, x+1+cx) + divider + Theme::c("title") + Fx::b + uresize(disk.name, disks_width - 8) + Mv::to(y+1+cy, x+cx + disks_width - total.size())
@ -1279,14 +1278,14 @@ namespace Mem {
out += Mv::to(y+1+cy, x+1+cx + round((double)disks_width / 2) - round((double)used_percent.size() / 2) - 1) + hu_div + used_percent + '%' + hu_div;
}
out += Mv::to(y+2+cy++, x+1+cx) + (big_disk ? " IO% " : " IO " + Mv::l(2)) + Theme::c("inactive_fg") + graph_bg * (disks_width - 6)
+ Mv::l(disks_width - 6) + safeVal(io_graphs, mount + "_activity")(disk.io_activity, redraw or data_same) + Theme::c("main_fg");
+ Mv::l(disks_width - 6) + io_graphs.at(mount + "_activity")(disk.io_activity, redraw or data_same) + Theme::c("main_fg");
if (++cy > height - 3) break;
if (io_graph_combined) {
auto comb_val = disk.io_read.back() + disk.io_write.back();
const string humanized = (disk.io_write.back() > 0 ? ""s : ""s) + (disk.io_read.back() > 0 ? ""s : ""s)
+ (comb_val > 0 ? Mv::r(1) + floating_humanizer(comb_val, true) : "RW");
if (disks_io_h == 1) out += Mv::to(y+1+cy, x+1+cx) + string(5, ' ');
out += Mv::to(y+1+cy, x+1+cx) + safeVal(io_graphs, mount)({comb_val}, redraw or data_same)
out += Mv::to(y+1+cy, x+1+cx) + io_graphs.at(mount)({comb_val}, redraw or data_same)
+ Mv::to(y+1+cy, x+1+cx) + Theme::c("main_fg") + humanized;
cy += disks_io_h;
}
@ -1294,8 +1293,8 @@ namespace Mem {
const string human_read = (disk.io_read.back() > 0 ? "" + floating_humanizer(disk.io_read.back(), true) : "R");
const string human_write = (disk.io_write.back() > 0 ? "" + floating_humanizer(disk.io_write.back(), true) : "W");
if (disks_io_h <= 3) out += Mv::to(y+1+cy, x+1+cx) + string(5, ' ') + Mv::to(y+cy + disks_io_h, x+1+cx) + string(5, ' ');
out += Mv::to(y+1+cy, x+1+cx) + safeVal(io_graphs, mount + "_read")(disk.io_read, redraw or data_same) + Mv::l(disks_width)
+ Mv::d(1) + safeVal(io_graphs, mount + "_write")(disk.io_write, redraw or data_same)
out += Mv::to(y+1+cy, x+1+cx) + io_graphs.at(mount + "_read")(disk.io_read, redraw or data_same) + Mv::l(disks_width)
+ Mv::d(1) + io_graphs.at(mount + "_write")(disk.io_write, redraw or data_same)
+ Mv::to(y+1+cy, x+1+cx) + human_read + Mv::to(y+cy + disks_io_h, x+1+cx) + human_write;
cy += disks_io_h;
}
@ -1305,7 +1304,7 @@ namespace Mem {
for (const auto& mount : mem.disks_order) {
if (not disks.contains(mount)) continue;
if (cy > height - 3) break;
const auto& disk = safeVal(disks, mount);
const auto& disk = disks.at(mount);
auto comb_val = (not disk.io_read.empty() ? disk.io_read.back() + disk.io_write.back() : 0ll);
const string human_io = (comb_val > 0 ? (disk.io_write.back() > 0 and big_disk ? ""s : ""s) + (disk.io_read.back() > 0 and big_disk ? ""s : ""s)
+ floating_humanizer(comb_val, true) : "");
@ -1320,18 +1319,18 @@ namespace Mem {
if (++cy > height - 3) break;
if (show_io_stat and io_graphs.contains(mount + "_activity")) {
out += Mv::to(y+1+cy, x+1+cx) + (big_disk ? " IO% " : " IO " + Mv::l(2)) + Theme::c("inactive_fg") + graph_bg * (disks_width - 6) + Theme::g("available").at(clamp(disk.io_activity.back(), 50ll, 100ll))
+ Mv::l(disks_width - 6) + safeVal(io_graphs, mount + "_activity")(disk.io_activity, redraw or data_same) + Theme::c("main_fg");
+ Mv::l(disks_width - 6) + io_graphs.at(mount + "_activity")(disk.io_activity, redraw or data_same) + Theme::c("main_fg");
if (not big_disk) out += Mv::to(y+1+cy, x+cx+1) + Theme::c("main_fg") + human_io;
if (++cy > height - 3) break;
}
out += Mv::to(y+1+cy, x+1+cx) + (big_disk ? " Used:" + rjust(to_string(disk.used_percent) + '%', 4) : "U") + ' '
+ safeVal(disk_meters_used, mount)(disk.used_percent) + rjust(human_used, (big_disk ? 9 : 5));
+ disk_meters_used.at(mount)(disk.used_percent) + rjust(human_used, (big_disk ? 9 : 5));
if (++cy > height - 3) break;
if (cmp_less_equal(disks.size() * 3 + (show_io_stat ? disk_ios : 0), height - 1)) {
out += Mv::to(y+1+cy, x+1+cx) + (big_disk ? " Free:" + rjust(to_string(disk.free_percent) + '%', 4) : "F") + ' '
+ safeVal(disk_meters_free, mount)(disk.free_percent) + rjust(human_free, (big_disk ? 9 : 5));
+ disk_meters_free.at(mount)(disk.free_percent) + rjust(human_free, (big_disk ? 9 : 5));
cy++;
if (cmp_less_equal(disks.size() * 4 + (show_io_stat ? disk_ios : 0), height - 1)) cy++;
}
@ -1354,7 +1353,7 @@ namespace Net {
int b_x, b_y, b_width, b_height, d_graph_height, u_graph_height;
bool shown = true, redraw = true;
string old_ip;
std::unordered_map<string, Draw::Graph> graphs;
unordered_flat_map<string, Draw::Graph> graphs;
string box;
string draw(const net_info& net, bool force_redraw, bool data_same) {
@ -1374,15 +1373,15 @@ namespace Net {
const string title_left = Theme::c("net_box") + Fx::ub + Symbols::title_left;
const string title_right = Theme::c("net_box") + Fx::ub + Symbols::title_right;
const int i_size = min((int)selected_iface.size(), 10);
const long long down_max = (net_auto ? safeVal(graph_max, "download"s) : ((long long)(Config::getI("net_download")) << 20) / 8);
const long long up_max = (net_auto ? safeVal(graph_max, "upload"s) : ((long long)(Config::getI("net_upload")) << 20) / 8);
const long long down_max = (net_auto ? graph_max.at("download") : ((long long)(Config::getI("net_download")) << 20) / 8);
const long long up_max = (net_auto ? graph_max.at("upload") : ((long long)(Config::getI("net_upload")) << 20) / 8);
//* Redraw elements not needed to be updated every cycle
if (redraw) {
out = box;
//? Graphs
graphs.clear();
if (safeVal(net.bandwidth, "download"s).empty() or safeVal(net.bandwidth, "upload"s).empty())
if (net.bandwidth.at("download").empty() or net.bandwidth.at("upload").empty())
return out + Fx::reset;
graphs["download"] = Draw::Graph{
width - b_width - 2, u_graph_height, "download",
@ -1396,7 +1395,7 @@ namespace Net {
out += Mv::to(y, x+width - i_size - 9) + title_left + Fx::b + Theme::c("hi_fg") + "<b " + Theme::c("title")
+ uresize(selected_iface, 10) + Theme::c("hi_fg") + " n>" + title_right
+ Mv::to(y, x+width - i_size - 15) + title_left + Theme::c("hi_fg") + (safeVal(net.stat, "download"s).offset + safeVal(net.stat, "upload"s).offset > 0 ? Fx::b : "") + 'z'
+ Mv::to(y, x+width - i_size - 15) + title_left + Theme::c("hi_fg") + (net.stat.at("download").offset + net.stat.at("upload").offset > 0 ? Fx::b : "") + 'z'
+ Theme::c("title") + "ero" + title_right;
Input::mouse_mappings["b"] = {y, x+width - i_size - 8, 1, 3};
Input::mouse_mappings["n"] = {y, x+width - 6, 1, 3};
@ -1420,13 +1419,13 @@ namespace Net {
//? Graphs and stats
int cy = 0;
for (const string dir : {"download", "upload"}) {
out += Mv::to(y+1 + (dir == "upload" ? u_graph_height : 0), x + 1) + safeVal(graphs, dir)(safeVal(net.bandwidth, dir), redraw or data_same or not net.connected)
out += Mv::to(y+1 + (dir == "upload" ? u_graph_height : 0), x + 1) + graphs.at(dir)(net.bandwidth.at(dir), redraw or data_same or not net.connected)
+ Mv::to(y+1 + (dir == "upload" ? height - 3: 0), x + 1) + Fx::ub + Theme::c("graph_text")
+ floating_humanizer((dir == "upload" ? up_max : down_max), true);
const string speed = floating_humanizer(safeVal(net.stat, dir).speed, false, 0, false, true);
const string speed_bits = (b_width >= 20 ? floating_humanizer(safeVal(net.stat, dir).speed, false, 0, true, true) : "");
const string top = floating_humanizer(safeVal(net.stat, dir).top, false, 0, true, true);
const string total = floating_humanizer(safeVal(net.stat, dir).total);
const string speed = floating_humanizer(net.stat.at(dir).speed, false, 0, false, true);
const string speed_bits = (b_width >= 20 ? floating_humanizer(net.stat.at(dir).speed, false, 0, true, true) : "");
const string top = floating_humanizer(net.stat.at(dir).top, false, 0, true, true);
const string total = floating_humanizer(net.stat.at(dir).total);
const string symbol = (dir == "upload" ? "" : "");
out += Mv::to(b_y+1+cy, b_x+1) + Fx::ub + Theme::c("main_fg") + symbol + ' ' + ljust(speed, 10) + (b_width >= 20 ? rjust('(' + speed_bits + ')', 13) : "");
cy += (b_height == 5 ? 2 : 1);
@ -1454,9 +1453,9 @@ namespace Proc {
bool shown = true, redraw = true;
int selected_pid = 0, selected_depth = 0;
string selected_name;
std::unordered_map<size_t, Draw::Graph> p_graphs;
std::unordered_map<size_t, bool> p_wide_cmd;
std::unordered_map<size_t, int> p_counters;
unordered_flat_map<size_t, Draw::Graph> p_graphs;
unordered_flat_map<size_t, bool> p_wide_cmd;
unordered_flat_map<size_t, int> p_counters;
int counter = 0;
Draw::TextEdit filter;
Draw::Graph detailed_cpu_graph;
@ -1795,7 +1794,7 @@ namespace Proc {
p_counters.erase(p.pid);
}
else
p_counters[p.pid] = 0;
p_counters.at(p.pid) = 0;
}
out += Fx::reset;
@ -1891,7 +1890,7 @@ namespace Proc {
+ g_color + ljust((cmp_greater(p.user.size(), user_size) ? p.user.substr(0, user_size - 1) + '+' : p.user), user_size) + ' '
+ m_color + rjust(mem_str, 5) + end + ' '
+ (is_selected ? "" : Theme::c("inactive_fg")) + (show_graphs ? graph_bg * 5: "")
+ (p_graphs.contains(p.pid) ? Mv::l(5) + c_color + safeVal(p_graphs, p.pid)({(p.cpu_p >= 0.1 and p.cpu_p < 5 ? 5ll : (long long)round(p.cpu_p))}, data_same) : "") + end + ' '
+ (p_graphs.contains(p.pid) ? Mv::l(5) + c_color + p_graphs.at(p.pid)({(p.cpu_p >= 0.1 and p.cpu_p < 5 ? 5ll : (long long)round(p.cpu_p))}, data_same) : "") + end + ' '
+ c_color + rjust(cpu_str, 4) + " " + end;
if (lc++ > height - 5) break;
}
@ -1927,6 +1926,8 @@ namespace Proc {
else
++element;
}
p_graphs.compact();
p_counters.compact();
for (auto element = p_wide_cmd.begin(); element != p_wide_cmd.end();) {
if (rng::find(plist, element->first, &proc_info::pid) == plist.end()) {
@ -1935,6 +1936,7 @@ namespace Proc {
else
++element;
}
p_wide_cmd.compact();
}
if (selected == 0 and selected_pid != 0) {

View file

@ -21,9 +21,10 @@ tab-size = 4
#include <string>
#include <vector>
#include <array>
#include <unordered_map>
#include <robin_hood.h>
#include <deque>
using robin_hood::unordered_flat_map;
using std::array;
using std::deque;
using std::string;
@ -107,7 +108,7 @@ namespace Draw {
long long offset;
long long last = 0, max_value = 0;
bool current = true, tty_mode = false;
std::unordered_map<bool, vector<string>> graphs = { {true, {}}, {false, {}}};
unordered_flat_map<bool, vector<string>> graphs = { {true, {}}, {false, {}}};
//* Create two representations of the graph to switch between to represent two values for each braille character
void _create(const deque<long long>& data, int data_offset);
@ -134,6 +135,6 @@ namespace Draw {
namespace Proc {
extern Draw::TextEdit filter;
extern std::unordered_map<size_t, Draw::Graph> p_graphs;
extern std::unordered_map<size_t, int> p_counters;
extern unordered_flat_map<size_t, Draw::Graph> p_graphs;
extern unordered_flat_map<size_t, int> p_counters;
}

View file

@ -49,7 +49,7 @@ namespace rng = std::ranges;
namespace Input {
//* Map for translating key codes to readable values
const std::unordered_map<string, string> Key_escapes = {
const unordered_flat_map<string, string> Key_escapes = {
{"\033", "escape"},
{"\n", "enter"},
{" ", "space"},
@ -92,7 +92,7 @@ namespace Input {
std::atomic<bool> interrupt (false);
std::atomic<bool> polling (false);
array<int, 2> mouse_pos;
std::unordered_map<string, Mouse_loc> mouse_mappings;
unordered_flat_map<string, Mouse_loc> mouse_mappings;
deque<string> history(50, "");
string old_filter;

View file

@ -21,9 +21,10 @@ tab-size = 4
#include <string>
#include <atomic>
#include <array>
#include <unordered_map>
#include <robin_hood.h>
#include <deque>
using robin_hood::unordered_flat_map;
using std::array;
using std::atomic;
using std::deque;
@ -43,7 +44,7 @@ namespace Input {
};
//? line, col, height, width
extern std::unordered_map<string, Mouse_loc> mouse_mappings;
extern unordered_flat_map<string, Mouse_loc> mouse_mappings;
extern atomic<bool> interrupt;
extern atomic<bool> polling;

View file

@ -17,7 +17,7 @@ tab-size = 4
*/
#include <deque>
#include <unordered_map>
#include <robin_hood.h>
#include <array>
#include <signal.h>
#include <errno.h>
@ -31,6 +31,7 @@ tab-size = 4
#include "btop_draw.hpp"
#include "btop_shared.hpp"
using robin_hood::unordered_flat_map;
using std::array;
using std::ceil;
using std::max;
@ -122,7 +123,7 @@ namespace Menu {
#endif
};
std::unordered_map<string, Input::Mouse_loc> mouse_mappings;
unordered_flat_map<string, Input::Mouse_loc> mouse_mappings;
const array<array<string, 3>, 3> menu_normal = {
array<string, 3>{
@ -1164,7 +1165,7 @@ namespace Menu {
static Draw::TextEdit editor;
static string warnings;
static bitset<8> selPred;
static const std::unordered_map<string, std::reference_wrapper<const vector<string>>> optionsList = {
static const unordered_flat_map<string, std::reference_wrapper<const vector<string>>> optionsList = {
{"color_theme", std::cref(Theme::themes)},
{"log_level", std::cref(Logger::log_levels)},
{"temp_scale", std::cref(Config::temp_scales)},

View file

@ -38,7 +38,7 @@ namespace Menu {
extern bool redraw;
//? line, col, height, width
extern std::unordered_map<string, Input::Mouse_loc> mouse_mappings;
extern unordered_flat_map<string, Input::Mouse_loc> mouse_mappings;
//* Creates a message box centered on screen
//? Height of box is determined by size of content vector

View file

@ -29,7 +29,7 @@ using namespace Tools;
namespace Gpu {
vector<string> gpu_names;
vector<int> gpu_b_height_offsets;
std::unordered_map<string, deque<long long>> shared_gpu_percent = {
unordered_flat_map<string, deque<long long>> shared_gpu_percent = {
{"gpu-average", {}},
{"gpu-vram-total", {}},
{"gpu-pwr-total", {}},

View file

@ -26,9 +26,10 @@ tab-size = 4
#include <tuple>
#include <vector>
#include <ifaddrs.h>
#include <unordered_map>
#include <robin_hood.h>
#include <unistd.h>
using robin_hood::unordered_flat_map;
using std::array;
using std::atomic;
using std::deque;
@ -97,7 +98,7 @@ namespace Gpu {
extern vector<int> gpu_b_height_offsets;
extern long long gpu_pwr_total_max;
extern std::unordered_map<string, deque<long long>> shared_gpu_percent; // averages, power/vram total
extern unordered_flat_map<string, deque<long long>> shared_gpu_percent; // averages, power/vram total
const array mem_names { "used"s, "free"s };
@ -123,7 +124,7 @@ namespace Gpu {
//* Per-device container for GPU info
struct gpu_info {
std::unordered_map<string, deque<long long>> gpu_percent = {
unordered_flat_map<string, deque<long long>> gpu_percent = {
{"gpu-totals", {}},
{"gpu-vram-totals", {}},
{"gpu-pwr-totals", {}},
@ -180,7 +181,7 @@ namespace Cpu {
extern tuple<int, long, string> current_bat;
struct cpu_info {
std::unordered_map<string, deque<long long>> cpu_percent = {
unordered_flat_map<string, deque<long long>> cpu_percent = {
{"total", {}},
{"user", {}},
{"nice", {}},
@ -206,8 +207,8 @@ namespace Cpu {
string draw(const cpu_info& cpu, const vector<Gpu::gpu_info>& gpu, bool force_redraw = false, bool data_same = false);
//* Parse /proc/cpu info for mapping of core ids
auto get_core_mapping() -> std::unordered_map<int, int>;
extern std::unordered_map<int, int> core_mapping;
auto get_core_mapping() -> unordered_flat_map<int, int>;
extern unordered_flat_map<int, int> core_mapping;
auto get_cpuHz() -> string;
@ -241,13 +242,13 @@ namespace Mem {
};
struct mem_info {
std::unordered_map<string, uint64_t> stats =
unordered_flat_map<string, uint64_t> stats =
{{"used", 0}, {"available", 0}, {"cached", 0}, {"free", 0},
{"swap_total", 0}, {"swap_used", 0}, {"swap_free", 0}};
std::unordered_map<string, deque<long long>> percent =
unordered_flat_map<string, deque<long long>> percent =
{{"used", {}}, {"available", {}}, {"cached", {}}, {"free", {}},
{"swap_total", {}}, {"swap_used", {}}, {"swap_free", {}}};
std::unordered_map<string, disk_info> disks;
unordered_flat_map<string, disk_info> disks;
vector<string> disks_order;
};
@ -269,7 +270,7 @@ namespace Net {
extern string selected_iface;
extern vector<string> interfaces;
extern bool rescale;
extern std::unordered_map<string, uint64_t> graph_max;
extern unordered_flat_map<string, uint64_t> graph_max;
struct net_stat {
uint64_t speed{}; // defaults to 0
@ -281,14 +282,14 @@ namespace Net {
};
struct net_info {
std::unordered_map<string, deque<long long>> bandwidth = { {"download", {}}, {"upload", {}} };
std::unordered_map<string, net_stat> stat = { {"download", {}}, {"upload", {}} };
unordered_flat_map<string, deque<long long>> bandwidth = { {"download", {}}, {"upload", {}} };
unordered_flat_map<string, net_stat> stat = { {"download", {}}, {"upload", {}} };
string ipv4{}; // defaults to ""
string ipv6{}; // defaults to ""
bool connected{}; // defaults to false
};
extern std::unordered_map<string, net_info> current_net;
extern unordered_flat_map<string, net_info> current_net;
//* Collect net upload/download stats
auto collect(bool no_update=false) -> net_info&;
@ -321,7 +322,7 @@ namespace Proc {
};
//? Translation from process state char to explanative string
const std::unordered_map<char, string> proc_states = {
const unordered_flat_map<char, string> proc_states = {
{'R', "Running"},
{'S', "Sleeping"},
{'D', "Waiting"},

View file

@ -42,11 +42,11 @@ namespace Theme {
fs::path theme_dir;
fs::path user_theme_dir;
vector<string> themes;
std::unordered_map<string, string> colors;
std::unordered_map<string, array<int, 3>> rgbs;
std::unordered_map<string, array<string, 101>> gradients;
unordered_flat_map<string, string> colors;
unordered_flat_map<string, array<int, 3>> rgbs;
unordered_flat_map<string, array<string, 101>> gradients;
const std::unordered_map<string, string> Default_theme = {
const unordered_flat_map<string, string> Default_theme = {
{ "main_bg", "#00" },
{ "main_fg", "#cc" },
{ "title", "#ee" },
@ -91,7 +91,7 @@ namespace Theme {
{ "process_end", "#d45454" }
};
const std::unordered_map<string, string> TTY_theme = {
const unordered_flat_map<string, string> TTY_theme = {
{ "main_bg", "\x1b[0;40m" },
{ "main_fg", "\x1b[37m" },
{ "title", "\x1b[97m" },
@ -224,7 +224,7 @@ namespace Theme {
}
//* Generate colors and rgb decimal vectors for the theme
void generateColors(const std::unordered_map<string, string>& source) {
void generateColors(const unordered_flat_map<string, string>& source) {
vector<string> t_rgb;
string depth;
bool t_to_256 = Config::getB("lowcolor");
@ -372,7 +372,7 @@ namespace Theme {
//* Load a .theme file from disk
auto loadFile(const string& filename) {
std::unordered_map<string, string> theme_out;
unordered_flat_map<string, string> theme_out;
const fs::path filepath = filename;
if (not fs::exists(filepath))
return Default_theme;

View file

@ -22,11 +22,12 @@ tab-size = 4
#include <filesystem>
#include <string>
#include <vector>
#include <unordered_map>
#include <robin_hood.h>
using std::array;
using std::string;
using std::vector;
using robin_hood::unordered_flat_map;
namespace Theme {
extern std::filesystem::path theme_dir;
@ -53,9 +54,9 @@ namespace Theme {
//* Set current theme from current "color_theme" value in config
void setTheme();
extern std::unordered_map<string, string> colors;
extern std::unordered_map<string, array<int, 3>> rgbs;
extern std::unordered_map<string, array<string, 101>> gradients;
extern unordered_flat_map<string, string> colors;
extern unordered_flat_map<string, array<int, 3>> rgbs;
extern unordered_flat_map<string, array<string, 101>> gradients;
//* Return escape code for color <name>
inline const string& c(const string& name) { return colors.at(name); }

View file

@ -30,7 +30,7 @@ tab-size = 4
#include <termios.h>
#include <sys/ioctl.h>
#include "unordered_map"
#include "robin_hood.h"
#include "widechar_width.hpp"
#include "btop_shared.hpp"
#include "btop_tools.hpp"
@ -43,6 +43,7 @@ using std::flush;
using std::max;
using std::string_view;
using std::to_string;
using robin_hood::unordered_flat_map;
using namespace std::literals; // to use operator""s

View file

@ -31,10 +31,6 @@ tab-size = 4
#include <vector>
#include <pthread.h>
#include <limits.h>
#include <unordered_map>
#ifdef BTOP_DEBUG
#include <source_location>
#endif
#ifndef HOST_NAME_MAX
#ifdef __APPLE__
#define HOST_NAME_MAX 255
@ -150,35 +146,6 @@ namespace Term {
void restore();
}
//* Simple logging implementation
namespace Logger {
const vector<string> log_levels = {
"DISABLED",
"ERROR",
"WARNING",
"INFO",
"DEBUG",
};
extern std::filesystem::path logfile;
enum Level : size_t {
DISABLED = 0,
ERROR = 1,
WARNING = 2,
INFO = 3,
DEBUG = 4,
};
//* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG"
void set(const string& level);
void log_write(const Level level, const string& msg);
inline void error(const string msg) { log_write(ERROR, msg); }
inline void warning(const string msg) { log_write(WARNING, msg); }
inline void info(const string msg) { log_write(INFO, msg); }
inline void debug(const string msg) { log_write(DEBUG, msg); }
}
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
namespace Tools {
@ -337,50 +304,6 @@ namespace Tools {
//* Add std::string operator * : Repeat string <str> <n> number of times
std::string operator*(const string& str, int64_t n);
template <typename K, typename T>
#ifdef BTOP_DEBUG
T safeVal(const std::unordered_map<K, T>& map, const K& key, T fallback = T(), std::source_location loc = std::source_location::current()) {
if (map.contains(key)) {
return map.at(key);
} else {
Logger::error(fmt::format("safeVal() called with invalid key: [{}] in file: {} on line: {}", key, loc.file_name(), loc.line()));
return fallback;
}
};
#else
T safeVal(const std::unordered_map<K, T>& map, const K& key, T fallback = T()) {
if (map.contains(key)) {
return map.at(key);
} else {
Logger::error(fmt::format("safeVal() called with invalid key: [{}] (Compile btop with DEBUG=true for more extensive logging!)", key));
return fallback;
}
};
#endif
template <typename T>
#ifdef BTOP_DEBUG
T safeVal(const std::vector<T>& vec, const size_t& index, T fallback = T(), std::source_location loc = std::source_location::current()) {
if (index < vec.size()) {
return vec.at(index);
} else {
Logger::error(fmt::format("safeVal() called with invalid index: [{}] in file: {} on line: {}", index, loc.file_name(), loc.line()));
return fallback;
}
};
#else
T safeVal(const std::vector<T>& vec, const size_t& index, T fallback = T()) {
if (index < vec.size()) {
return vec.at(index);
} else {
Logger::error(fmt::format("safeVal() called with invalid index: [{}] (Compile btop with DEBUG=true for more extensive logging!)", index));
return fallback;
}
};
#endif
//* Return current time in <strf> format
string strf_time(const string& strf);
@ -419,6 +342,35 @@ namespace Tools {
auto celsius_to(const long long& celsius, const string& scale) -> tuple<long long, string>;
}
//* Simple logging implementation
namespace Logger {
const vector<string> log_levels = {
"DISABLED",
"ERROR",
"WARNING",
"INFO",
"DEBUG",
};
extern std::filesystem::path logfile;
enum Level : size_t {
DISABLED = 0,
ERROR = 1,
WARNING = 2,
INFO = 3,
DEBUG = 4,
};
//* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG"
void set(const string& level);
void log_write(const Level level, const string& msg);
inline void error(const string msg) { log_write(ERROR, msg); }
inline void warning(const string msg) { log_write(WARNING, msg); }
inline void info(const string msg) { log_write(INFO, msg); }
inline void debug(const string msg) { log_write(DEBUG, msg); }
}
namespace Tools {
//* Creates a named timer that is started on construct (by default) and reports elapsed time in microseconds to Logger::debug() on destruct if running
//* Unless delayed_report is set to false, all reporting is buffered and delayed until DebugTimer is destructed or .force_report() is called

View file

@ -98,7 +98,7 @@ namespace Cpu {
string cpu_sensor;
vector<string> core_sensors;
std::unordered_map<int, int> core_mapping;
unordered_flat_map<int, int> core_mapping;
} // namespace Cpu
namespace Mem {
@ -204,7 +204,7 @@ namespace Cpu {
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
std::unordered_map<string, long long> cpu_old = {
unordered_flat_map<string, long long> cpu_old = {
{"totals", 0},
{"idles", 0},
{"user", 0},
@ -323,8 +323,8 @@ namespace Cpu {
return std::to_string(freq / 1000.0 ).substr(0, 3); // seems to be in MHz
}
auto get_core_mapping() -> std::unordered_map<int, int> {
std::unordered_map<int, int> core_map;
auto get_core_mapping() -> unordered_flat_map<int, int> {
unordered_flat_map<int, int> core_map;
if (cpu_temp_only) return core_map;
for (long i = 0; i < Shared::coreCount; i++) {
@ -557,7 +557,7 @@ namespace Mem {
}
}
void collect_disk(std::unordered_map<string, disk_info> &disks, std::unordered_map<string, string> &mapping) {
void collect_disk(unordered_flat_map<string, disk_info> &disks, unordered_flat_map<string, string> &mapping) {
// this bit is for 'regular' mounts
static struct statinfo cur;
long double etime = 0;
@ -691,7 +691,7 @@ namespace Mem {
}
if (show_disks) {
std::unordered_map<string, string> mapping; // keep mapping from device -> mountpoint, since IOKit doesn't give us the mountpoint
unordered_flat_map<string, string> mapping; // keep mapping from device -> mountpoint, since IOKit doesn't give us the mountpoint
double uptime = system_uptime();
auto &disks_filter = Config::getS("disks_filter");
bool filter_exclude = false;
@ -807,13 +807,13 @@ namespace Mem {
} // namespace Mem
namespace Net {
std::unordered_map<string, net_info> current_net;
unordered_flat_map<string, net_info> current_net;
net_info empty_net = {};
vector<string> interfaces;
string selected_iface;
int errors = 0;
std::unordered_map<string, uint64_t> graph_max = {{"download", {}}, {"upload", {}}};
std::unordered_map<string, array<int, 2>> max_count = {{"download", {}}, {"upload", {}}};
unordered_flat_map<string, uint64_t> graph_max = {{"download", {}}, {"upload", {}}};
unordered_flat_map<string, array<int, 2>> max_count = {{"download", {}}, {"upload", {}}};
bool rescale = true;
uint64_t timestamp = 0;
@ -892,7 +892,7 @@ namespace Net {
} //else, ignoring family==AF_LINK (see man 3 getifaddrs)
}
std::unordered_map<string, std::tuple<uint64_t, uint64_t>> ifstats;
unordered_flat_map<string, std::tuple<uint64_t, uint64_t>> ifstats;
int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
size_t len;
if (sysctl(mib, 6, nullptr, &len, nullptr, 0) < 0) {
@ -1037,7 +1037,7 @@ namespace Net {
namespace Proc {
vector<proc_info> current_procs;
std::unordered_map<string, string> uid_user;
unordered_flat_map<string, string> uid_user;
string current_sort;
string current_filter;
bool current_rev = false;

View file

@ -17,8 +17,7 @@ tab-size = 4
*/
#include <cstdlib>
#include <unordered_map>
#include <unordered_set>
#include <robin_hood.h>
#include <fstream>
#include <ranges>
#include <cmath>
@ -32,8 +31,6 @@ tab-size = 4
#include <filesystem>
#include <future>
#include <dlfcn.h>
#include <unordered_map>
#include <utility>
#if defined(RSMI_STATIC)
#include <rocm_smi/rocm_smi.h>
@ -97,10 +94,10 @@ namespace Cpu {
int64_t crit{}; // defaults to 0
};
std::unordered_map<string, Sensor> found_sensors;
unordered_flat_map<string, Sensor> found_sensors;
string cpu_sensor;
vector<string> core_sensors;
std::unordered_map<int, int> core_mapping;
unordered_flat_map<int, int> core_mapping;
}
namespace Gpu {
@ -301,7 +298,7 @@ namespace Cpu {
"irq"s, "softirq"s, "steal"s, "guest"s, "guest_nice"s
};
std::unordered_map<string, long long> cpu_old = {
unordered_flat_map<string, long long> cpu_old = {
{"totals", 0},
{"idles", 0},
{"user", 0},
@ -598,8 +595,8 @@ namespace Cpu {
return cpuhz;
}
auto get_core_mapping() -> std::unordered_map<int, int> {
std::unordered_map<int, int> core_map;
auto get_core_mapping() -> unordered_flat_map<int, int> {
unordered_flat_map<int, int> core_map;
if (cpu_temp_only) return core_map;
//? Try to get core mapping from /proc/cpuinfo
@ -672,7 +669,7 @@ namespace Cpu {
auto get_battery() -> tuple<int, long, string> {
if (not has_battery) return {0, 0, ""};
static string auto_sel;
static std::unordered_map<string, battery> batteries;
static unordered_flat_map<string, battery> batteries;
//? Get paths to needed files and check for valid values on first run
if (batteries.empty() and has_battery) {
@ -1616,7 +1613,7 @@ namespace Mem {
auto only_physical = Config::getB("only_physical");
auto zfs_hide_datasets = Config::getB("zfs_hide_datasets");
auto& disks = mem.disks;
static std::unordered_map<string, future<pair<disk_info, int>>> disks_stats_promises;
static unordered_flat_map<string, future<pair<disk_info, int>>> disks_stats_promises;
ifstream diskread;
vector<string> filter;
@ -2051,13 +2048,13 @@ namespace Mem {
}
namespace Net {
std::unordered_map<string, net_info> current_net;
unordered_flat_map<string, net_info> current_net;
net_info empty_net = {};
vector<string> interfaces;
string selected_iface;
int errors{}; // defaults to 0
std::unordered_map<string, uint64_t> graph_max = { {"download", {}}, {"upload", {}} };
std::unordered_map<string, array<int, 2>> max_count = { {"download", {}}, {"upload", {}} };
unordered_flat_map<string, uint64_t> graph_max = { {"download", {}}, {"upload", {}} };
unordered_flat_map<string, array<int, 2>> max_count = { {"download", {}}, {"upload", {}} };
bool rescale{true};
uint64_t timestamp{}; // defaults to 0
@ -2196,6 +2193,7 @@ namespace Net {
else
it++;
}
net.compact();
}
timestamp = new_timestamp;
@ -2265,7 +2263,7 @@ namespace Net {
namespace Proc {
vector<proc_info> current_procs;
std::unordered_map<string, string> uid_user;
unordered_flat_map<string, string> uid_user;
string current_sort;
string current_filter;
bool current_rev{}; // defaults to false
@ -2280,7 +2278,7 @@ namespace Proc {
detail_container detailed;
constexpr size_t KTHREADD = 2;
static std::unordered_set<size_t> kernels_procs = {KTHREADD};
static robin_hood::unordered_set<size_t> kernels_procs = {KTHREADD};
//* Get detailed info for selected process
void _collect_details(const size_t pid, const uint64_t uptime, vector<proc_info>& procs) {

View file

@ -98,7 +98,7 @@ namespace Cpu {
string cpu_sensor;
vector<string> core_sensors;
std::unordered_map<int, int> core_mapping;
unordered_flat_map<int, int> core_mapping;
} // namespace Cpu
namespace Mem {
@ -194,7 +194,7 @@ namespace Cpu {
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
std::unordered_map<string, long long> cpu_old = {
unordered_flat_map<string, long long> cpu_old = {
{"totals", 0},
{"idles", 0},
{"user", 0},
@ -337,8 +337,8 @@ namespace Cpu {
return std::to_string(freq / 1000.0 / 1000.0 / 1000.0).substr(0, 3);
}
auto get_core_mapping() -> std::unordered_map<int, int> {
std::unordered_map<int, int> core_map;
auto get_core_mapping() -> unordered_flat_map<int, int> {
unordered_flat_map<int, int> core_map;
if (cpu_temp_only) return core_map;
natural_t cpu_count;
@ -599,7 +599,7 @@ namespace Mem {
io_object_t &object;
};
void collect_disk(std::unordered_map<string, disk_info> &disks, std::unordered_map<string, string> &mapping) {
void collect_disk(unordered_flat_map<string, disk_info> &disks, unordered_flat_map<string, string> &mapping) {
io_registry_entry_t drive;
io_iterator_t drive_list;
@ -716,7 +716,7 @@ namespace Mem {
}
if (show_disks) {
std::unordered_map<string, string> mapping; // keep mapping from device -> mountpoint, since IOKit doesn't give us the mountpoint
unordered_flat_map<string, string> mapping; // keep mapping from device -> mountpoint, since IOKit doesn't give us the mountpoint
double uptime = system_uptime();
auto &disks_filter = Config::getS("disks_filter");
bool filter_exclude = false;
@ -829,13 +829,13 @@ namespace Mem {
} // namespace Mem
namespace Net {
std::unordered_map<string, net_info> current_net;
unordered_flat_map<string, net_info> current_net;
net_info empty_net = {};
vector<string> interfaces;
string selected_iface;
int errors = 0;
std::unordered_map<string, uint64_t> graph_max = {{"download", {}}, {"upload", {}}};
std::unordered_map<string, array<int, 2>> max_count = {{"download", {}}, {"upload", {}}};
unordered_flat_map<string, uint64_t> graph_max = {{"download", {}}, {"upload", {}}};
unordered_flat_map<string, array<int, 2>> max_count = {{"download", {}}, {"upload", {}}};
bool rescale = true;
uint64_t timestamp = 0;
@ -912,7 +912,7 @@ namespace Net {
} // else, ignoring family==AF_LINK (see man 3 getifaddrs)
}
std::unordered_map<string, std::tuple<uint64_t, uint64_t>> ifstats;
unordered_flat_map<string, std::tuple<uint64_t, uint64_t>> ifstats;
int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0};
size_t len;
if (sysctl(mib, 6, nullptr, &len, nullptr, 0) < 0) {
@ -1057,7 +1057,7 @@ namespace Net {
namespace Proc {
vector<proc_info> current_procs;
std::unordered_map<string, string> uid_user;
unordered_flat_map<string, string> uid_user;
string current_sort;
string current_filter;
bool current_rev = false;