From: Kefu Chai Date: Sun, 19 Dec 2021 04:25:50 +0000 (+0800) Subject: common/str_map: reimplement get_str_list() using for_each_pair X-Git-Tag: v17.1.0~180^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b5d638dc0f3045f1e9c9a796b6271a84ac5ed393;p=ceph.git common/str_map: reimplement get_str_list() using for_each_pair to avoid creating a temporary list and then dropping it on the floor after iterating through it for collecting the kv pairs in it. Signed-off-by: Kefu Chai --- diff --git a/src/common/str_map.cc b/src/common/str_map.cc index 2ce9b541c213..638a307845cb 100644 --- a/src/common/str_map.cc +++ b/src/common/str_map.cc @@ -59,12 +59,15 @@ int get_json_str_map( return 0; } -string trim(const string& str) { - return boost::algorithm::trim_copy_if( - str, - [](unsigned char c) { - return std::isspace(c); - }); +static std::string_view trim(std::string_view str) +{ + static const char* whitespaces = "\t\n "; + auto beg = str.find_first_not_of(whitespaces); + if (beg == str.npos) { + return {}; + } + auto end = str.find_last_not_of(whitespaces); + return str.substr(beg, end - beg + 1); } int get_str_map( @@ -72,18 +75,15 @@ int get_str_map( str_map_t* str_map, const char *delims) { - auto pairs = get_str_list(str, delims); - for (const auto& pr : pairs) { - size_t equal = pr.find('='); - if (equal == string::npos) - (*str_map)[pr] = string(); - else { - const string key = trim(pr.substr(0, equal)); - equal++; - const string value = trim(pr.substr(equal)); - (*str_map)[key] = value; + for_each_pair(str, delims, [str_map](std::string_view key, + std::string_view val) { + // is the format 'K=V' or just 'K'? + if (val.empty()) { + str_map->emplace(std::string(key), ""); + } else { + str_map->emplace(std::string(trim(key)), std::string(trim(val))); } - } + }); return 0; } @@ -91,23 +91,8 @@ str_map_t get_str_map( const string& str, const char* delim) { - auto pairs = get_str_list(str, delim); str_map_t str_map; - - for (const auto& pr : pairs) { - auto equal = pr.find('='); - - // is the format 'K=V' or just 'K'? - if (equal == std::string::npos) { - str_map[pr] = std::string{}; - } else { - const string key = trim(pr.substr(0, equal)); - equal++; - const string value = trim(pr.substr(equal)); - str_map[key] = value; - } - } - + get_str_map(str, &str_map, delim); return str_map; } diff --git a/src/include/str_map.h b/src/include/str_map.h index f8bef0579021..7f354fd46960 100644 --- a/src/include/str_map.h +++ b/src/include/str_map.h @@ -23,6 +23,23 @@ #include #include +template +void for_each_pair(std::string_view s, const char* delims, Func&& f) +{ + auto pos = s.find_first_not_of(delims); + while (pos != s.npos) { + s.remove_prefix(pos); // trim delims from the front + auto end = s.find_first_of(delims); + auto kv = s.substr(0, end); + if (auto equal = kv.find('='); equal != kv.npos) { + f(kv.substr(0, equal), kv.substr(equal + 1)); + } else { + f(kv.substr(0, equal), std::string_view()); + } + pos = s.find_first_not_of(delims, end); + } +} + using str_map_t = std::map; /**