]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common/str_map: reimplement get_str_list() using for_each_pair
authorKefu Chai <tchaikov@gmail.com>
Sun, 19 Dec 2021 04:25:50 +0000 (12:25 +0800)
committerKefu Chai <tchaikov@gmail.com>
Sun, 19 Dec 2021 07:02:45 +0000 (15:02 +0800)
to avoid creating a temporary list<string> and then dropping it
on the floor after iterating through it for collecting the kv
pairs in it.

Signed-off-by: Kefu Chai <tchaikov@gmail.com>
src/common/str_map.cc
src/include/str_map.h

index 2ce9b541c213546801a6c6666bf02eb854539f5e..638a307845cb8401b72896525b187f8d377a25f3 100644 (file)
@@ -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;
 }
 
index f8bef05790217a800d2c7c84929b31c33b976f0c..7f354fd4696033b6c50809786b6e6094d11ebf51 100644 (file)
 #include <string>
 #include <sstream>
 
+template <typename Func>
+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<std::string,std::string>;
 
 /**