зеркало из https://github.com/nextcloud/desktop.git
csync_excluded: Another speedup #3638
Build a list of path components outside of the exclude pattern loop.
This commit is contained in:
Родитель
e71cca128d
Коммит
07ca0be3c5
|
@ -44,24 +44,7 @@
|
||||||
static
|
static
|
||||||
#endif
|
#endif
|
||||||
int _csync_exclude_add(c_strlist_t **inList, const char *string) {
|
int _csync_exclude_add(c_strlist_t **inList, const char *string) {
|
||||||
c_strlist_t *list;
|
return c_strlist_add_grow(inList, string);
|
||||||
|
|
||||||
if (*inList == NULL) {
|
|
||||||
*inList = c_strlist_new(32);
|
|
||||||
if (*inList == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*inList)->count == (*inList)->size) {
|
|
||||||
list = c_strlist_expand(*inList, 2 * (*inList)->size);
|
|
||||||
if (list == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*inList = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c_strlist_add(*inList, string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int csync_exclude_load(const char *fname, c_strlist_t **list) {
|
int csync_exclude_load(const char *fname, c_strlist_t **list) {
|
||||||
|
@ -281,6 +264,31 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Build a list of path components to check. */
|
||||||
|
c_strlist_t *path_components = c_strlist_new(32);
|
||||||
|
char *path_split = strdup(path);
|
||||||
|
size_t len = strlen(path_split);
|
||||||
|
for (int j = len; ; --j) {
|
||||||
|
// read backwards until a path separator is found
|
||||||
|
if (j != 0 && path_split[j-1] != '/') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check 'basename', i.e. for "/foo/bar/fi" we'd check 'fi', 'bar', 'foo'
|
||||||
|
if (path_split[j] != 0) {
|
||||||
|
c_strlist_add_grow(&path_components, path_split + j);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j == 0 || !check_leading_dirs) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check 'dirname', i.e. for "/foo/bar/fi" we'd check '/foo/bar', '/foo'
|
||||||
|
path_split[j-1] = '\0';
|
||||||
|
c_strlist_add_grow(&path_components, path_split);
|
||||||
|
}
|
||||||
|
SAFE_FREE(path_split);
|
||||||
|
|
||||||
/* Loop over all exclude patterns and evaluate the given path */
|
/* Loop over all exclude patterns and evaluate the given path */
|
||||||
for (i = 0; match == CSYNC_NOT_EXCLUDED && i < excludes->count; i++) {
|
for (i = 0; match == CSYNC_NOT_EXCLUDED && i < excludes->count; i++) {
|
||||||
bool match_dirs_only = false;
|
bool match_dirs_only = false;
|
||||||
|
@ -319,41 +327,21 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
|
||||||
|
|
||||||
/* if still not excluded, check each component and leading directory of the path */
|
/* if still not excluded, check each component and leading directory of the path */
|
||||||
if (match == CSYNC_NOT_EXCLUDED) {
|
if (match == CSYNC_NOT_EXCLUDED) {
|
||||||
char *segmented_path = strdup(path);
|
size_t j = 0;
|
||||||
size_t len = strlen(segmented_path);
|
if (match_dirs_only && filetype == CSYNC_FTW_TYPE_FILE) {
|
||||||
bool check_segname = !match_dirs_only || filetype != CSYNC_FTW_TYPE_FILE;
|
j = 1; // skip the first entry, which is bname
|
||||||
for (int j = len; ; --j) {
|
}
|
||||||
// read backwards until a path separator
|
for (; j < path_components->count; ++j) {
|
||||||
if (j != 0 && segmented_path[j-1] != '/') {
|
rc = csync_fnmatch(pattern, path_components->vector[j], 0);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check 'basename', i.e. for "/foo/bar/fi" we'd check 'fi', 'bar', 'foo'
|
|
||||||
if (check_segname && segmented_path[j] != 0) {
|
|
||||||
rc = csync_fnmatch(pattern, segmented_path + j, 0);
|
|
||||||
if (rc == 0) {
|
|
||||||
match = type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
check_segname = true;
|
|
||||||
|
|
||||||
if (j == 0 || !check_leading_dirs) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check 'dirname', i.e. for "/foo/bar/fi" we'd check '/foo/bar', '/foo'
|
|
||||||
segmented_path[j-1] = '\0';
|
|
||||||
rc = csync_fnmatch(pattern, segmented_path, 0);
|
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
match = type;
|
match = type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SAFE_FREE(segmented_path);
|
|
||||||
}
|
}
|
||||||
SAFE_FREE(pattern_stored);
|
SAFE_FREE(pattern_stored);
|
||||||
}
|
}
|
||||||
|
c_strlist_destroy(path_components);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
||||||
|
|
|
@ -215,6 +215,25 @@ int c_strlist_add(c_strlist_t *strlist, const char *string) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int c_strlist_add_grow(c_strlist_t **strlist, const char *string) {
|
||||||
|
if (*strlist == NULL) {
|
||||||
|
*strlist = c_strlist_new(32);
|
||||||
|
if (*strlist == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*strlist)->count == (*strlist)->size) {
|
||||||
|
c_strlist_t *list = c_strlist_expand(*strlist, 2 * (*strlist)->size);
|
||||||
|
if (list == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*strlist = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c_strlist_add(*strlist, string);
|
||||||
|
}
|
||||||
|
|
||||||
void c_strlist_clear(c_strlist_t *strlist) {
|
void c_strlist_clear(c_strlist_t *strlist) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,19 @@ c_strlist_t *c_strlist_expand(c_strlist_t *strlist, size_t size);
|
||||||
*/
|
*/
|
||||||
int c_strlist_add(c_strlist_t *strlist, const char *string);
|
int c_strlist_add(c_strlist_t *strlist, const char *string);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a string to the stringlist, growing it if necessary
|
||||||
|
*
|
||||||
|
* Duplicates the string and stores it in the stringlist.
|
||||||
|
* It also initializes the stringlist if it starts out as null.
|
||||||
|
*
|
||||||
|
* @param strlist Stringlist to add the string.
|
||||||
|
* @param string String to add.
|
||||||
|
*
|
||||||
|
* @return 0 on success, less than 0 and errno set if an error occured.
|
||||||
|
*/
|
||||||
|
int c_strlist_add_grow(c_strlist_t **strlist, const char *string);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Removes all strings from the list.
|
* @brief Removes all strings from the list.
|
||||||
*
|
*
|
||||||
|
|
|
@ -90,6 +90,11 @@ static void check_csync_excluded(void **state)
|
||||||
CSYNC *csync = *state;
|
CSYNC *csync = *state;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
rc = csync_excluded(csync, "", CSYNC_FTW_TYPE_FILE);
|
||||||
|
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||||
|
rc = csync_excluded(csync, "/", CSYNC_FTW_TYPE_FILE);
|
||||||
|
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||||
|
|
||||||
rc = csync_excluded(csync, "krawel_krawel", CSYNC_FTW_TYPE_FILE);
|
rc = csync_excluded(csync, "krawel_krawel", CSYNC_FTW_TYPE_FILE);
|
||||||
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
|
||||||
rc = csync_excluded(csync, ".kde/share/config/kwin.eventsrc", CSYNC_FTW_TYPE_FILE);
|
rc = csync_excluded(csync, ".kde/share/config/kwin.eventsrc", CSYNC_FTW_TYPE_FILE);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче