Skip to content

Commit

Permalink
improve performance one step at a time
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Sep 18, 2024
1 parent b431670 commit 266c8a5
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 87 deletions.
6 changes: 3 additions & 3 deletions include/ada/url-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ namespace ada {
return !host.has_value() || host.value().empty() ||
type == ada::scheme::type::FILE;
}
[[nodiscard]] inline bool url::has_empty_hostname() const noexcept {
[[nodiscard]] constexpr bool url::has_empty_hostname() const noexcept {
if (!host.has_value()) {
return false;
}
return host.value().empty();
}
[[nodiscard]] inline bool url::has_hostname() const noexcept {
[[nodiscard]] constexpr bool url::has_hostname() const noexcept {
return host.has_value();
}
inline std::ostream &operator<<(std::ostream &out, const ada::url &u) {
Expand Down Expand Up @@ -188,7 +188,7 @@ inline void url::copy_scheme(const ada::url &u) {
if (has_credentials()) {
output += username;
if (!password.empty()) {
output += ":" + get_password();
output += ":" + std::string(get_password());
}
output += "@";
}
Expand Down
12 changes: 6 additions & 6 deletions include/ada/url.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ struct url : url_base {
std::optional<std::string> hash{};

/** @return true if it has an host but it is the empty string */
[[nodiscard]] inline bool has_empty_hostname() const noexcept;
[[nodiscard]] constexpr bool has_empty_hostname() const noexcept;
/** @return true if the URL has a (non default) port */
[[nodiscard]] inline bool has_port() const noexcept;
/** @return true if it has a host (included an empty host) */
[[nodiscard]] inline bool has_hostname() const noexcept;
[[nodiscard]] constexpr bool has_hostname() const noexcept;
[[nodiscard]] bool has_valid_domain() const noexcept override;

/**
Expand Down Expand Up @@ -141,15 +141,15 @@ struct url : url_base {
* @return a newly allocated string.
* @see https://url.spec.whatwg.org/#dom-url-hostname
*/
[[nodiscard]] std::string get_hostname() const noexcept;
[[nodiscard]] constexpr std::string_view get_hostname() const noexcept;

/**
* The pathname getter steps are to return the result of URL path serializing
* this's URL.
* @return a newly allocated string.
* @see https://url.spec.whatwg.org/#dom-url-pathname
*/
[[nodiscard]] std::string_view get_pathname() const noexcept;
[[nodiscard]] constexpr std::string_view get_pathname() const noexcept;

/**
* Compute the pathname length in bytes without instantiating a view or a
Expand All @@ -171,7 +171,7 @@ struct url : url_base {
* @return a constant reference to the underlying string.
* @see https://url.spec.whatwg.org/#dom-url-username
*/
[[nodiscard]] const std::string &get_username() const noexcept;
[[nodiscard]] constexpr std::string_view get_username() const noexcept;

/**
* @return Returns true on successful operation.
Expand Down Expand Up @@ -237,7 +237,7 @@ struct url : url_base {
* @return a constant reference to the underlying string.
* @see https://url.spec.whatwg.org/#dom-url-password
*/
[[nodiscard]] const std::string &get_password() const noexcept;
[[nodiscard]] constexpr std::string_view get_password() const noexcept;

/**
* Return this's URL's port, serialized.
Expand Down
35 changes: 17 additions & 18 deletions include/ada/url_aggregator-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -451,10 +451,9 @@ inline void url_aggregator::update_base_password(const std::string_view input) {
return;
}

bool password_exists = has_password();
uint32_t difference = uint32_t(input.size());
auto difference = static_cast<uint32_t>(input.size());

if (password_exists) {
if (has_password()) {
uint32_t current_length =
components.host_start - components.username_end - 1;
buffer.erase(components.username_end + 1, current_length);
Expand Down Expand Up @@ -493,7 +492,7 @@ inline void url_aggregator::append_base_password(const std::string_view input) {
ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer));
#if ADA_DEVELOPMENT_CHECKS
// computing the expected password.
std::string password_expected = std::string(get_password());
auto password_expected = std::string(get_password());
password_expected.append(input);
#endif // ADA_DEVELOPMENT_CHECKS
add_authority_slashes_if_needed();
Expand All @@ -503,7 +502,7 @@ inline void url_aggregator::append_base_password(const std::string_view input) {
return;
}

uint32_t difference = uint32_t(input.size());
auto difference = static_cast<uint32_t>(input.size());
if (has_password()) {
buffer.insert(components.host_start, input);
} else {
Expand Down Expand Up @@ -548,7 +547,7 @@ inline void url_aggregator::update_base_port(uint32_t input) {
// calling std::to_string(input.value()) is unfortunate given that the port
// value is probably already available as a string.
std::string value = helpers::concat(":", std::to_string(input));
uint32_t difference = uint32_t(value.size());
auto difference = static_cast<uint32_t>(value.size());

if (components.port != url_components::omitted) {
difference -= components.pathname_start - components.host_end;
Expand Down Expand Up @@ -706,22 +705,22 @@ inline void url_aggregator::clear_hostname() {
ADA_ASSERT_TRUE(validate());
}

[[nodiscard]] inline bool url_aggregator::has_hash() const noexcept {
[[nodiscard]] constexpr bool url_aggregator::has_hash() const noexcept {
ada_log("url_aggregator::has_hash");
return components.hash_start != url_components::omitted;
}

[[nodiscard]] inline bool url_aggregator::has_search() const noexcept {
[[nodiscard]] constexpr bool url_aggregator::has_search() const noexcept {
ada_log("url_aggregator::has_search");
return components.search_start != url_components::omitted;
}

ada_really_inline bool url_aggregator::has_credentials() const noexcept {
ada_really_inline constexpr bool url_aggregator::has_credentials() const noexcept {
ada_log("url_aggregator::has_credentials");
return has_non_empty_username() || has_non_empty_password();
}

inline bool url_aggregator::cannot_have_credentials_or_port() const {
constexpr bool url_aggregator::cannot_have_credentials_or_port() const {
ada_log("url_aggregator::cannot_have_credentials_or_port");
return type == ada::scheme::type::FILE ||
components.host_start == components.host_end;
Expand All @@ -732,7 +731,7 @@ url_aggregator::get_components() const noexcept {
return components;
}

[[nodiscard]] inline bool ada::url_aggregator::has_authority() const noexcept {
[[nodiscard]] constexpr bool ada::url_aggregator::has_authority() const noexcept {
ada_log("url_aggregator::has_authority");
// Performance: instead of doing this potentially expensive check, we could
// have a boolean in the struct.
Expand Down Expand Up @@ -767,28 +766,28 @@ inline void ada::url_aggregator::add_authority_slashes_if_needed() noexcept {
ADA_ASSERT_TRUE(validate());
}

inline void ada::url_aggregator::reserve(uint32_t capacity) {
constexpr void ada::url_aggregator::reserve(uint32_t capacity) {
buffer.reserve(capacity);
}

inline bool url_aggregator::has_non_empty_username() const noexcept {
constexpr bool url_aggregator::has_non_empty_username() const noexcept {
ada_log("url_aggregator::has_non_empty_username");
return components.protocol_end + 2 < components.username_end;
}

inline bool url_aggregator::has_non_empty_password() const noexcept {
constexpr bool url_aggregator::has_non_empty_password() const noexcept {
ada_log("url_aggregator::has_non_empty_password");
return components.host_start - components.username_end > 0;
}

inline bool url_aggregator::has_password() const noexcept {
constexpr bool url_aggregator::has_password() const noexcept {
ada_log("url_aggregator::has_password");
// This function does not care about the length of the password
return components.host_start > components.username_end &&
buffer[components.username_end] == ':';
}

inline bool url_aggregator::has_empty_hostname() const noexcept {
constexpr bool url_aggregator::has_empty_hostname() const noexcept {
if (!has_hostname()) {
return false;
}
Expand All @@ -801,11 +800,11 @@ inline bool url_aggregator::has_empty_hostname() const noexcept {
return components.username_end != components.host_start;
}

inline bool url_aggregator::has_hostname() const noexcept {
constexpr bool url_aggregator::has_hostname() const noexcept {
return has_authority();
}

inline bool url_aggregator::has_port() const noexcept {
constexpr bool url_aggregator::has_port() const noexcept {
ada_log("url_aggregator::has_port");
// A URL cannot have a username/password/port if its host is null or the empty
// string, or its scheme is "file".
Expand Down
32 changes: 16 additions & 16 deletions include/ada/url_aggregator.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,30 +65,30 @@ struct url_aggregator : url_base {
* @return a lightweight std::string_view.
* @see https://url.spec.whatwg.org/#dom-url-username
*/
[[nodiscard]] std::string_view get_username() const noexcept
[[nodiscard]] constexpr std::string_view get_username() const noexcept
ada_lifetime_bound;
/**
* The password getter steps are to return this's URL's password.
* This function does not allocate memory.
* @return a lightweight std::string_view.
* @see https://url.spec.whatwg.org/#dom-url-password
*/
[[nodiscard]] std::string_view get_password() const noexcept
[[nodiscard]] constexpr std::string_view get_password() const noexcept
ada_lifetime_bound;
/**
* Return this's URL's port, serialized.
* This function does not allocate memory.
* @return a lightweight std::string_view.
* @see https://url.spec.whatwg.org/#dom-url-port
*/
[[nodiscard]] std::string_view get_port() const noexcept ada_lifetime_bound;
[[nodiscard]] constexpr std::string_view get_port() const noexcept ada_lifetime_bound;
/**
* Return U+0023 (#), followed by this's URL's fragment.
* This function does not allocate memory.
* @return a lightweight std::string_view..
* @see https://url.spec.whatwg.org/#dom-url-hash
*/
[[nodiscard]] std::string_view get_hash() const noexcept ada_lifetime_bound;
[[nodiscard]] constexpr std::string_view get_hash() const noexcept ada_lifetime_bound;
/**
* Return url's host, serialized, followed by U+003A (:) and url's port,
* serialized.
Expand Down Expand Up @@ -144,7 +144,7 @@ struct url_aggregator : url_base {
* A URL includes credentials if its username or password is not the empty
* string.
*/
[[nodiscard]] ada_really_inline bool has_credentials() const noexcept;
[[nodiscard]] ada_really_inline constexpr bool has_credentials() const noexcept;

/**
* Useful for implementing efficient serialization for the URL.
Expand Down Expand Up @@ -186,21 +186,21 @@ struct url_aggregator : url_base {
[[nodiscard]] bool validate() const noexcept;

/** @return true if it has an host but it is the empty string */
[[nodiscard]] inline bool has_empty_hostname() const noexcept;
[[nodiscard]] constexpr bool has_empty_hostname() const noexcept;
/** @return true if it has a host (included an empty host) */
[[nodiscard]] inline bool has_hostname() const noexcept;
[[nodiscard]] constexpr bool has_hostname() const noexcept;
/** @return true if the URL has a non-empty username */
[[nodiscard]] inline bool has_non_empty_username() const noexcept;
[[nodiscard]] constexpr bool has_non_empty_username() const noexcept;
/** @return true if the URL has a non-empty password */
[[nodiscard]] inline bool has_non_empty_password() const noexcept;
[[nodiscard]] constexpr bool has_non_empty_password() const noexcept;
/** @return true if the URL has a (non default) port */
[[nodiscard]] inline bool has_port() const noexcept;
[[nodiscard]] constexpr bool has_port() const noexcept;
/** @return true if the URL has a password */
[[nodiscard]] inline bool has_password() const noexcept;
[[nodiscard]] constexpr bool has_password() const noexcept;
/** @return true if the URL has a hash component */
[[nodiscard]] inline bool has_hash() const noexcept override;
[[nodiscard]] constexpr bool has_hash() const noexcept override;
/** @return true if the URL has a search component */
[[nodiscard]] inline bool has_search() const noexcept override;
[[nodiscard]] constexpr bool has_search() const noexcept override;

inline void clear_port();
inline void clear_hash();
Expand Down Expand Up @@ -233,7 +233,7 @@ struct url_aggregator : url_base {
* To optimize performance, you may indicate how much memory to allocate
* within this instance.
*/
inline void reserve(uint32_t capacity);
constexpr void reserve(uint32_t capacity);

ada_really_inline size_t parse_port(
std::string_view view, bool check_trailing_content) noexcept override;
Expand Down Expand Up @@ -268,7 +268,7 @@ struct url_aggregator : url_base {
* A URL cannot have a username/password/port if its host is null or the empty
* string, or its scheme is "file".
*/
[[nodiscard]] inline bool cannot_have_credentials_or_port() const;
[[nodiscard]] constexpr bool cannot_have_credentials_or_port() const;

template <bool override_hostname = false>
bool set_host_or_hostname(std::string_view input);
Expand Down Expand Up @@ -301,7 +301,7 @@ struct url_aggregator : url_base {
std::string_view input);
ada_really_inline uint32_t replace_and_resize(uint32_t start, uint32_t end,
std::string_view input);
[[nodiscard]] inline bool has_authority() const noexcept;
[[nodiscard]] constexpr bool has_authority() const noexcept;
inline void set_protocol_as_file();
inline void set_scheme(std::string_view new_scheme) noexcept;
/**
Expand Down
13 changes: 8 additions & 5 deletions src/url-getters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,14 @@ namespace ada {
return host.value();
}

[[nodiscard]] std::string url::get_hostname() const noexcept {
return host.value_or("");
[[nodiscard]] constexpr std::string_view url::get_hostname() const noexcept {
if (host.has_value()) {
return *host;
}
return {};
}

[[nodiscard]] std::string_view url::get_pathname() const noexcept {
[[nodiscard]] constexpr std::string_view url::get_pathname() const noexcept {
return path;
}

Expand All @@ -73,11 +76,11 @@ namespace ada {
: "?" + query.value();
}

[[nodiscard]] const std::string& url::get_username() const noexcept {
[[nodiscard]] constexpr std::string_view url::get_username() const noexcept {
return username;
}

[[nodiscard]] const std::string& url::get_password() const noexcept {
[[nodiscard]] constexpr std::string_view url::get_password() const noexcept {
return password;
}

Expand Down
19 changes: 5 additions & 14 deletions src/url-setters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ bool url::set_host_or_hostname(const std::string_view input) {
// Note: the 'found_colon' value is true if and only if a colon was
// encountered while not inside brackets.
if (found_colon) {
if (override_hostname) {
if constexpr (override_hostname) {
return false;
}
std::string_view buffer = new_host.substr(location + 1);
Expand Down Expand Up @@ -204,8 +204,8 @@ bool url::set_protocol(const std::string_view input) {

view.append(":");

std::string::iterator pointer =
std::find_if_not(view.begin(), view.end(), unicode::is_alnum_plus);
auto pointer =
std::ranges::find_if_not(view, unicode::is_alnum_plus);

if (pointer != view.end() && *pointer == ':') {
return parse_scheme<true>(
Expand All @@ -215,19 +215,10 @@ bool url::set_protocol(const std::string_view input) {
}

bool url::set_href(const std::string_view input) {
ada::result<ada::url> out = ada::parse<ada::url>(input);
auto out = ada::parse<ada::url>(input);

if (out) {
username = out->username;
password = out->password;
host = out->host;
port = out->port;
path = out->path;
query = out->query;
hash = out->hash;
type = out->type;
non_special_scheme = out->non_special_scheme;
has_opaque_path = out->has_opaque_path;
*this = *out;
}

return out.has_value();
Expand Down
Loading

0 comments on commit 266c8a5

Please sign in to comment.