Verified Commit f020cf23 authored by Marc Vef's avatar Marc Vef
Browse files

optimizing path resolution performance

parent 8f180f29
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <string>
#include <cassert>
#include <climits>
#include <stack>

extern "C" {
#include <sys/stat.h>
@@ -111,7 +112,8 @@ bool resolve(const string& path, string& resolved, bool resolve_last_link) {
    string::size_type comp_size = 0; // size of current component
    string::size_type start = 0; // start index of curr component
    string::size_type end = 0; // end index of curr component (last processed Path Separator "separator")
    string::size_type last_slash_pos = 0; // index of last slash in resolved path
    stack<string::size_type> slash_idx{};
    slash_idx.push(0); // index of all slashes in resolved path (used for rollback due to `..`)
    resolved.clear();
    resolved.reserve(path.size());

@@ -141,12 +143,8 @@ bool resolve(const string& path, string& resolved, bool resolve_last_link) {
        if (comp_size == 2 && path.at(start) == '.' && path.at(start + 1) == '.') {
            // component is '..' we need to rollback resolved path
            if (!resolved.empty()) {
                resolved.erase(last_slash_pos);
                /* TODO     Optimization
                 * the previous slash position should be stored.
                 * The following search could be avoided.
                 */
                last_slash_pos = resolved.find_last_of(path::separator);
                resolved.erase(slash_idx.top());
                slash_idx.pop();
            }
            if (resolved_components > 0) {
                if (matched_components == resolved_components) {
@@ -159,7 +157,7 @@ bool resolve(const string& path, string& resolved, bool resolve_last_link) {

        // add `/<component>` to the reresolved path
        resolved.push_back(path::separator);
        last_slash_pos = resolved.size() - 1;
        slash_idx.push(resolved.size() - 1);
        resolved.append(path, start, comp_size);
        /*
         * This will be true for all path components outside of GKFS and up to the mountdir's parent path
@@ -195,7 +193,12 @@ bool resolve(const string& path, string& resolved, bool resolve_last_link) {
                resolved = link_resolved.get();
                matched_components = match_components(resolved, resolved_components, mnt_components);
                // set matched counter to value coherent with the new path
                last_slash_pos = resolved.find_last_of(path::separator);
                stack<string::size_type> slash_idx_new{};
                for (size_t i = 0; i < resolved.size(); i++) {
                    if (resolved[i] == path::separator)
                        slash_idx_new.push(i);
                }
                slash_idx = slash_idx_new;
                continue;
            } else if ((!S_ISDIR(st.st_mode)) && (end != path.size())) {
                resolved.append(path, end, string::npos);