summaryrefslogtreecommitdiff
path: root/src/fileops.c
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-02-12 02:34:58 +0100
committerCarlos Martín Nieto <cmn@dwim.me>2015-02-12 02:34:58 +0100
commitd24a5312d8ab6d3cdb259e450ec9f1e2e6f3399d (patch)
tree6bdb4b732e9c14560dcf941bf1cc6a1344e169a3 /src/fileops.c
parent8e29ae7310a731e3a4dc8f952ae2245f83960673 (diff)
parentfa89ff20cd777fafc3e971bbf8081d97ce082c15 (diff)
downloadlibgit2-d24a5312d8ab6d3cdb259e450ec9f1e2e6f3399d.tar.gz
Merge pull request #2866 from ethomson/checkout_perf2
Checkout performance
Diffstat (limited to 'src/fileops.c')
-rw-r--r--src/fileops.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 4a62d210d..eddd5a804 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -7,11 +7,14 @@
#include "common.h"
#include "fileops.h"
#include "global.h"
+#include "strmap.h"
#include <ctype.h>
#if GIT_WIN32
#include "win32/findfile.h"
#endif
+GIT__USE_STRMAP;
+
int git_futils_mkpath2file(const char *file_path, const mode_t mode)
{
return git_futils_mkdir(
@@ -321,12 +324,12 @@ GIT_INLINE(int) validate_existing(
return 0;
}
-int git_futils_mkdir_withperf(
+int git_futils_mkdir_ext(
const char *path,
const char *base,
mode_t mode,
uint32_t flags,
- struct git_futils_mkdir_perfdata *perfdata)
+ struct git_futils_mkdir_options *opts)
{
int error = -1;
git_buf make_path = GIT_BUF_INIT;
@@ -401,11 +404,14 @@ int git_futils_mkdir_withperf(
*tail = '\0';
st.st_mode = 0;
+ if (opts->dir_map && git_strmap_exists(opts->dir_map, make_path.ptr))
+ continue;
+
/* See what's going on with this path component */
- perfdata->stat_calls++;
+ opts->perfdata.stat_calls++;
if (p_lstat(make_path.ptr, &st) < 0) {
- perfdata->mkdir_calls++;
+ opts->perfdata.mkdir_calls++;
if (errno != ENOENT || p_mkdir(make_path.ptr, mode) < 0) {
giterr_set(GITERR_OS, "Failed to make directory '%s'", make_path.ptr);
@@ -423,7 +429,7 @@ int git_futils_mkdir_withperf(
}
if ((error = validate_existing(
- make_path.ptr, &st, mode, flags, perfdata)) < 0)
+ make_path.ptr, &st, mode, flags, &opts->perfdata)) < 0)
goto done;
}
@@ -432,7 +438,7 @@ int git_futils_mkdir_withperf(
(lastch == '\0' && (flags & GIT_MKDIR_CHMOD) != 0)) &&
st.st_mode != mode) {
- perfdata->chmod_calls++;
+ opts->perfdata.chmod_calls++;
if ((error = p_chmod(make_path.ptr, mode)) < 0 &&
lastch == '\0') {
@@ -441,6 +447,17 @@ int git_futils_mkdir_withperf(
goto done;
}
}
+
+ if (opts->dir_map && opts->pool) {
+ char *cache_path = git_pool_malloc(opts->pool, make_path.size + 1);
+ GITERR_CHECK_ALLOC(cache_path);
+
+ memcpy(cache_path, make_path.ptr, make_path.size + 1);
+
+ git_strmap_insert(opts->dir_map, cache_path, cache_path, error);
+ if (error < 0)
+ goto done;
+ }
}
error = 0;
@@ -448,7 +465,7 @@ int git_futils_mkdir_withperf(
/* check that full path really is a directory if requested & needed */
if ((flags & GIT_MKDIR_VERIFY_DIR) != 0 &&
lastch != '\0') {
- perfdata->stat_calls++;
+ opts->perfdata.stat_calls++;
if (p_stat(make_path.ptr, &st) < 0 || !S_ISDIR(st.st_mode)) {
giterr_set(GITERR_OS, "Path is not a directory '%s'",
@@ -468,8 +485,8 @@ int git_futils_mkdir(
mode_t mode,
uint32_t flags)
{
- struct git_futils_mkdir_perfdata perfdata = {0};
- return git_futils_mkdir_withperf(path, base, mode, flags, &perfdata);
+ struct git_futils_mkdir_options options = {0};
+ return git_futils_mkdir_ext(path, base, mode, flags, &options);
}
int git_futils_mkdir_r(const char *path, const char *base, const mode_t mode)