diff --git a/include/ada/scheme-inl.h b/include/ada/scheme-inl.h index 196f95092..9cffb72ea 100644 --- a/include/ada/scheme-inl.h +++ b/include/ada/scheme-inl.h @@ -22,22 +22,31 @@ constexpr std::string_view is_special_list[] = {"http", " ", "https", "ws", constexpr uint16_t special_ports[] = {80, 0, 443, 80, 21, 443, 0, 0}; } // namespace details +/**** + * In is_special, get_scheme_type, and get_special_port, we + * use a standard hashing technique to find the index of the scheme in the + * is_special_list. The hashing technique is based on the size of the scheme + * and the first character of the scheme. It ensures that we do at most one + * string comparison per call. If the protocol is predictible (e.g., it is + * always "http"), we can get a better average performance by using a a + * simpler approach where we loop and compare scheme with all possible + * protocol. In this instance, we choose a potentially slightly lower + * best-case performance for a better worst-case performance. + * + * Reference: + * Schmidt, Douglas C. "Gperf: A perfect hash function generator." More C++ + * gems 17 (2000). + * + * Reference: https://en.wikipedia.org/wiki/Perfect_hash_function + * + * Reference: https://github.com/ada-url/ada/issues/617 + ****/ + + ada_really_inline constexpr bool is_special(std::string_view scheme) { if (scheme.empty()) { return false; } - /** - * We use a standard hashing technique to find the index of the scheme in the - * is_special_list. The hashing technique is based on the size of the scheme - * and the first character of the scheme. It ensures that we do at most one - * string comparison per call. If the protocol is predictible (e.g., it is - * always "http"), we can get a better average performance by using a a - * simpler approach where we loop and compare scheme with all possible - * protocol. In this instance, we choose a potentially slightly lower - * best-case performance for a better worst-case performance. Reference: - * Schmidt, Douglas C. "Gperf: A perfect hash function generator." More C++ - * gems 17 (2000). - */ int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7; const std::string_view target = details::is_special_list[hash_value]; return (target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1)); @@ -46,18 +55,6 @@ constexpr uint16_t get_special_port(std::string_view scheme) noexcept { if (scheme.empty()) { return 0; } - /** - * We use a standard hashing technique to find the index of the scheme in the - * is_special_list. The hashing technique is based on the size of the scheme - * and the first character of the scheme. It ensures that we do at most one - * string comparison per call. If the protocol is predictible (e.g., it is - * always "http"), we can get a better average performance by using a a - * simpler approach where we loop and compare scheme with all possible - * protocol. In this instance, we choose a potentially slightly lower - * best-case performance for a better worst-case performance. Reference: - * Schmidt, Douglas C. "Gperf: A perfect hash function generator." More C++ - * gems 17 (2000). - */ int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7; const std::string_view target = details::is_special_list[hash_value]; if ((target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1))) { @@ -73,18 +70,6 @@ constexpr ada::scheme::type get_scheme_type(std::string_view scheme) noexcept { if (scheme.empty()) { return ada::scheme::NOT_SPECIAL; } - /** - * We use a standard hashing technique to find the index of the scheme in the - * is_special_list. The hashing technique is based on the size of the scheme - * and the first character of the scheme. It ensures that we do at most one - * string comparison per call. If the protocol is predictible (e.g., it is - * always "http"), we can get a better average performance by using a a - * simpler approach where we loop and compare scheme with all possible - * protocol. In this instance, we choose a potentially slightly lower - * best-case performance for a better worst-case performance. Reference: - * Schmidt, Douglas C. "Gperf: A perfect hash function generator." More C++ - * gems 17 (2000). - */ int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7; const std::string_view target = details::is_special_list[hash_value]; if ((target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1))) {