| 37 | namespace impala { |
| 38 | |
| 39 | int64_t ParseUtil::ParseMemSpec(const string& mem_spec_str, bool* is_percent, |
| 40 | int64_t relative_reference) { |
| 41 | *is_percent = false; |
| 42 | if (mem_spec_str.empty()) return 0; |
| 43 | |
| 44 | int64_t multiplier = -1; |
| 45 | int32_t number_str_len = mem_spec_str.size(); |
| 46 | |
| 47 | // Look for an accepted suffix such as "MB", "M", or "%". |
| 48 | string::const_reverse_iterator suffix_char = mem_spec_str.rbegin(); |
| 49 | if (*suffix_char == 'b' || *suffix_char == 'B') { |
| 50 | // Skip "B", the default is bytes anyways. |
| 51 | if (suffix_char == mem_spec_str.rend()) return -1; |
| 52 | suffix_char++; |
| 53 | number_str_len--; |
| 54 | } |
| 55 | switch (*suffix_char) { |
| 56 | case 't': |
| 57 | case 'T': |
| 58 | // Terabytes. |
| 59 | number_str_len--; |
| 60 | multiplier = 1024L * 1024L * 1024L * 1024L; |
| 61 | break; |
| 62 | case 'g': |
| 63 | case 'G': |
| 64 | // Gigabytes. |
| 65 | number_str_len--; |
| 66 | multiplier = 1024L * 1024L * 1024L; |
| 67 | break; |
| 68 | case 'm': |
| 69 | case 'M': |
| 70 | // Megabytes. |
| 71 | number_str_len--; |
| 72 | multiplier = 1024L * 1024L; |
| 73 | break; |
| 74 | case 'k': |
| 75 | case 'K': |
| 76 | // Kilobytes |
| 77 | number_str_len--; |
| 78 | multiplier = 1024L; |
| 79 | break; |
| 80 | case '%': |
| 81 | // Don't allow a suffix of "%B". |
| 82 | if (suffix_char != mem_spec_str.rbegin()) return -1; |
| 83 | number_str_len--; |
| 84 | *is_percent = true; |
| 85 | break; |
| 86 | // The default is bytes. If there was a trailing "B" it was handled above. |
| 87 | } |
| 88 | |
| 89 | StringParser::ParseResult result; |
| 90 | int64_t bytes; |
| 91 | if (multiplier != -1) { |
| 92 | // Parse float - MB or GB |
| 93 | double limit_val = StringParser::StringToFloat<double>(mem_spec_str.data(), |
| 94 | number_str_len, &result); |
| 95 | if (result != StringParser::PARSE_SUCCESS) return -1; |
| 96 | bytes = multiplier * limit_val; |