Project

General

Profile

Bug #13167 » 0001-dir.c-performance-fix-with-braces-using-cache.patch

h.shirosaki (Hiroshi Shirosaki), 09/11/2017 02:23 PM

View differences:

dir.c
# error not implemented
#endif
#if defined HAVE_GETATTRLIST || defined _WIN32
struct real_path {
char *path;
rb_pathtype_t type;
};
static char *
replace_real_basename_with_cache(char *path, long base, rb_encoding *enc, int norm_p, int flags,
rb_pathtype_t *type, st_table *cached_paths)
{
struct real_path *real_path;
st_data_t key = (st_data_t)path;
if (cached_paths && st_lookup(cached_paths, key, (st_data_t *)&real_path)) {
path = ruby_strdup(real_path->path);
*type = real_path->type;
}
else {
path = replace_real_basename(path, base, enc, norm_p, flags, type);
if (cached_paths) {
real_path = GLOB_ALLOC(struct real_path);
real_path->path = ruby_strdup(path);
real_path->type = *type;
st_insert(cached_paths, key, (st_data_t)real_path);
}
}
return path;
}
#endif
#ifndef S_ISDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
......
int flags,
const ruby_glob_funcs_t *funcs,
VALUE arg,
st_table *cached_paths,
rb_encoding *enc)
{
struct stat st;
......
}
status = glob_helper(fd, buf, baselen, name - buf - baselen + namlen, 1,
new_pathtype, new_beg, new_end,
flags, funcs, arg, enc);
new_pathtype, new_beg, new_end, flags, funcs,
arg, cached_paths, enc);
GLOB_FREE(buf);
GLOB_FREE(new_beg);
if (status) break;
......
#if USE_NAME_ON_FS == USE_NAME_ON_FS_REAL_BASENAME
if ((*cur)->type == ALPHA) {
long base = pathlen + (dirsep != 0);
buf = replace_real_basename(buf, base, enc, IF_NORMALIZE_UTF8PATH(1)+0,
flags, &new_pathtype);
buf = replace_real_basename_with_cache(buf, base, enc,
IF_NORMALIZE_UTF8PATH(1)+0,
flags, &new_pathtype,
cached_paths);
if (!buf) break;
}
#endif
status = glob_helper(fd, buf, baselen,
namelen + strlen(buf + pathlen), 1,
new_pathtype, new_beg, new_end,
flags, funcs, arg, enc);
flags, funcs, arg, cached_paths, enc);
GLOB_FREE(buf);
GLOB_FREE(new_beg);
if (status) break;
......
static int
ruby_glob0(const char *path, int fd, const char *base, int flags,
const ruby_glob_funcs_t *funcs, VALUE arg,
rb_encoding *enc)
st_table *cached_paths, rb_encoding *enc)
{
struct glob_pattern *list;
const char *root, *start;
......
}
status = glob_helper(fd, buf, baselen, n-baselen, dirsep,
path_unknown, &list, &list + 1,
flags, funcs, arg, enc);
flags, funcs, arg, cached_paths, enc);
glob_free_pattern(list);
GLOB_FREE(buf);
......
funcs.match = func;
funcs.error = NULL;
return ruby_glob0(path, AT_FDCWD, 0, flags & ~GLOB_VERBOSE,
&funcs, arg, rb_ascii8bit_encoding());
&funcs, arg, NULL, rb_ascii8bit_encoding());
}
static int
......
args.enc = rb_ascii8bit_encoding();
status = ruby_glob0(path, AT_FDCWD, 0, GLOB_VERBOSE, &rb_glob_funcs,
(VALUE)&args, args.enc);
(VALUE)&args, NULL, args.enc);
if (status) GLOB_JUMP_TAG(status);
}
......
{
struct brace_args *arg = (struct brace_args *)val;
return ruby_glob0(path, AT_FDCWD, 0, arg->flags, &arg->funcs, arg->value, enc);
return ruby_glob0(path, AT_FDCWD, 0, arg->flags, &arg->funcs, arg->value, NULL, enc);
}
int
......
struct glob_args glob;
int flags;
int fd;
st_table *cached_paths;
};
static int
......
struct push_glob_args *arg = (struct push_glob_args *)val;
return ruby_glob0(path, arg->fd, arg->glob.base, arg->flags, &rb_glob_funcs,
(VALUE)&arg->glob, enc);
(VALUE)&arg->glob, arg->cached_paths, enc);
}
#if defined HAVE_GETATTRLIST || defined _WIN32
static int
free_cached_paths(st_data_t key, st_data_t val, st_data_t arg)
{
GLOB_FREE((struct real_path *)val);
return ST_DELETE;
}
#endif
static int
push_glob(VALUE ary, VALUE str, VALUE base, int flags)
{
struct push_glob_args args;
rb_encoding *enc = rb_enc_get(str);
int status;
#if defined _WIN32 || defined __APPLE__
str = rb_str_encode_ospath(str);
......
enc = rb_utf8_encoding();
#endif
return ruby_brace_expand(RSTRING_PTR(str), flags,
push_caller, (VALUE)&args, enc, str);
#if defined HAVE_GETATTRLIST || defined _WIN32
args.cached_paths = st_init_strtable();
#endif
status = ruby_brace_expand(RSTRING_PTR(str), flags,
push_caller, (VALUE)&args, enc, str);
#if defined HAVE_GETATTRLIST || defined _WIN32
st_foreach(args.cached_paths, free_cached_paths, 0);
st_free_table(args.cached_paths);
#endif
return status;
}
static VALUE
(4-4/12)