this function is a modification of rocksdb's StringToMap: 1) accepts ' \n ; as separators 2) leaves compound options with enclosing { and }
| 249 | // 1) accepts ' \n ; as separators |
| 250 | // 2) leaves compound options with enclosing { and } |
| 251 | rocksdb::Status StringToMap(const std::string& opts_str, |
| 252 | std::unordered_map<std::string, std::string>* opts_map) |
| 253 | { |
| 254 | using rocksdb::Status; |
| 255 | using rocksdb::trim; |
| 256 | assert(opts_map); |
| 257 | // Example: |
| 258 | // opts_str = "write_buffer_size=1024;max_write_buffer_number=2;" |
| 259 | // "nested_opt={opt1=1;opt2=2};max_bytes_for_level_base=100" |
| 260 | size_t pos = 0; |
| 261 | std::string opts = trim(opts_str); |
| 262 | while (pos < opts.size()) { |
| 263 | size_t eq_pos = opts.find('=', pos); |
| 264 | if (eq_pos == std::string::npos) { |
| 265 | return Status::InvalidArgument("Mismatched key value pair, '=' expected"); |
| 266 | } |
| 267 | std::string key = trim(opts.substr(pos, eq_pos - pos)); |
| 268 | if (key.empty()) { |
| 269 | return Status::InvalidArgument("Empty key found"); |
| 270 | } |
| 271 | |
| 272 | // skip space after '=' and look for '{' for possible nested options |
| 273 | pos = eq_pos + 1; |
| 274 | while (pos < opts.size() && isspace(opts[pos])) { |
| 275 | ++pos; |
| 276 | } |
| 277 | // Empty value at the end |
| 278 | if (pos >= opts.size()) { |
| 279 | (*opts_map)[key] = ""; |
| 280 | break; |
| 281 | } |
| 282 | if (opts[pos] == '{') { |
| 283 | int count = 1; |
| 284 | size_t brace_pos = pos + 1; |
| 285 | while (brace_pos < opts.size()) { |
| 286 | if (opts[brace_pos] == '{') { |
| 287 | ++count; |
| 288 | } else if (opts[brace_pos] == '}') { |
| 289 | --count; |
| 290 | if (count == 0) { |
| 291 | break; |
| 292 | } |
| 293 | } |
| 294 | ++brace_pos; |
| 295 | } |
| 296 | // found the matching closing brace |
| 297 | if (count == 0) { |
| 298 | //include both '{' and '}' |
| 299 | (*opts_map)[key] = trim(opts.substr(pos, brace_pos - pos + 1)); |
| 300 | // skip all whitespace and move to the next ';,' |
| 301 | // brace_pos points to the matching '}' |
| 302 | pos = brace_pos + 1; |
| 303 | while (pos < opts.size() && isspace(opts[pos])) { |
| 304 | ++pos; |
| 305 | } |
| 306 | if (pos < opts.size() && opts[pos] != ';' && opts[pos] != ',') { |
| 307 | return Status::InvalidArgument( |
| 308 | "Unexpected chars after nested options"); |
no test coverage detected