From 2c02a0456661aa79ebd92c9d05b7011b7c1fb147 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 2 Apr 2020 20:14:28 +0200 Subject: [PATCH] db/update/Walk: pass std::string_view to DirectoryMakeUriParentChecked() Split the string into path segments with StringView::Split(). This prepares to eliminate all allocations from the method. --- src/db/update/Walk.cxx | 31 ++++++++++++++++--------------- src/db/update/Walk.hxx | 2 +- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/db/update/Walk.cxx b/src/db/update/Walk.cxx index 7cf792c19..a5840a535 100644 --- a/src/db/update/Walk.cxx +++ b/src/db/update/Walk.cxx @@ -409,28 +409,29 @@ UpdateWalk::DirectoryMakeChildChecked(Directory &parent, inline Directory * UpdateWalk::DirectoryMakeUriParentChecked(Directory &root, - const char *uri) noexcept + std::string_view _uri) noexcept { Directory *directory = &root; - char *duplicated = xstrdup(uri); - char *name_utf8 = duplicated, *slash; + StringView uri(_uri); - while ((slash = strchr(name_utf8, '/')) != nullptr) { - *slash = 0; - - if (StringIsEmpty(name_utf8)) - continue; - - directory = DirectoryMakeChildChecked(*directory, - duplicated, - name_utf8); - if (directory == nullptr) + while (true) { + auto s = uri.Split('/'); + const std::string_view name = s.first; + const auto rest = s.second; + if (rest == nullptr) break; - name_utf8 = slash + 1; + if (!name.empty()) { + directory = DirectoryMakeChildChecked(*directory, + std::string(name).c_str(), + s.first); + if (directory == nullptr) + break; + } + + uri = s.second; } - free(duplicated); return directory; } diff --git a/src/db/update/Walk.hxx b/src/db/update/Walk.hxx index 99253ca47..dfc3e4ed9 100644 --- a/src/db/update/Walk.hxx +++ b/src/db/update/Walk.hxx @@ -166,7 +166,7 @@ private: std::string_view name_utf8) noexcept; Directory *DirectoryMakeUriParentChecked(Directory &root, - const char *uri) noexcept; + std::string_view uri) noexcept; void UpdateUri(Directory &root, const char *uri) noexcept; };