update: avoid duplicate stat() calls
Pass a pointer to the stat struct to more functions.
This commit is contained in:
parent
953f186c8a
commit
9935ef4034
62
src/update.c
62
src/update.c
@ -227,7 +227,7 @@ inodeFoundInParent(struct directory *parent, ino_t inode, dev_t device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum update_return
|
static enum update_return
|
||||||
updateDirectory(struct directory *directory);
|
updateDirectory(struct directory *directory, const struct stat *st);
|
||||||
|
|
||||||
static enum update_return
|
static enum update_return
|
||||||
addSubDirectoryToDirectory(struct directory *directory,
|
addSubDirectoryToDirectory(struct directory *directory,
|
||||||
@ -239,9 +239,7 @@ addSubDirectoryToDirectory(struct directory *directory,
|
|||||||
return UPDATE_RETURN_NOUPDATE;
|
return UPDATE_RETURN_NOUPDATE;
|
||||||
|
|
||||||
subDirectory = directory_new(name, directory);
|
subDirectory = directory_new(name, directory);
|
||||||
directory_set_stat(subDirectory, st);
|
if (updateDirectory(subDirectory, st) != UPDATE_RETURN_UPDATED) {
|
||||||
|
|
||||||
if (updateDirectory(subDirectory) != UPDATE_RETURN_UPDATED) {
|
|
||||||
directory_free(subDirectory);
|
directory_free(subDirectory);
|
||||||
return UPDATE_RETURN_NOUPDATE;
|
return UPDATE_RETURN_NOUPDATE;
|
||||||
}
|
}
|
||||||
@ -252,15 +250,12 @@ addSubDirectoryToDirectory(struct directory *directory,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum update_return
|
static enum update_return
|
||||||
updateInDirectory(struct directory *directory, const char *name)
|
updateInDirectory(struct directory *directory,
|
||||||
|
const char *name, const struct stat *st)
|
||||||
{
|
{
|
||||||
struct song *song;
|
struct song *song;
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (myStat(name, &st))
|
if (S_ISREG(st->st_mode) && hasMusicSuffix(name, 0)) {
|
||||||
return UPDATE_RETURN_ERROR;
|
|
||||||
|
|
||||||
if (S_ISREG(st.st_mode) && hasMusicSuffix(name, 0)) {
|
|
||||||
const char *shortname = mpd_basename(name);
|
const char *shortname = mpd_basename(name);
|
||||||
|
|
||||||
if (!(song = songvec_find(&directory->songs, shortname))) {
|
if (!(song = songvec_find(&directory->songs, shortname))) {
|
||||||
@ -271,27 +266,26 @@ updateInDirectory(struct directory *directory, const char *name)
|
|||||||
songvec_add(&directory->songs, song);
|
songvec_add(&directory->songs, song);
|
||||||
LOG("added %s\n", name);
|
LOG("added %s\n", name);
|
||||||
return UPDATE_RETURN_UPDATED;
|
return UPDATE_RETURN_UPDATED;
|
||||||
} else if (st.st_mtime != song->mtime) {
|
} else if (st->st_mtime != song->mtime) {
|
||||||
LOG("updating %s\n", name);
|
LOG("updating %s\n", name);
|
||||||
if (!song_file_update(song))
|
if (!song_file_update(song))
|
||||||
delete_song(directory, song);
|
delete_song(directory, song);
|
||||||
return UPDATE_RETURN_UPDATED;
|
return UPDATE_RETURN_UPDATED;
|
||||||
}
|
}
|
||||||
} else if (S_ISDIR(st.st_mode)) {
|
} else if (S_ISDIR(st->st_mode)) {
|
||||||
struct directory *subdir = directory_get_child(directory, name);
|
struct directory *subdir = directory_get_child(directory, name);
|
||||||
if (subdir) {
|
if (subdir) {
|
||||||
enum update_return ret;
|
enum update_return ret;
|
||||||
|
|
||||||
assert(directory == subdir->parent);
|
assert(directory == subdir->parent);
|
||||||
directory_set_stat(subdir, &st);
|
|
||||||
|
|
||||||
ret = updateDirectory(subdir);
|
ret = updateDirectory(subdir, st);
|
||||||
if (ret == UPDATE_RETURN_ERROR)
|
if (ret == UPDATE_RETURN_ERROR)
|
||||||
delete_directory(subdir);
|
delete_directory(subdir);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
return addSubDirectoryToDirectory(directory, name, &st);
|
return addSubDirectoryToDirectory(directory, name, st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,20 +301,21 @@ static int skip_path(const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum update_return
|
static enum update_return
|
||||||
updateDirectory(struct directory *directory)
|
updateDirectory(struct directory *directory, const struct stat *st)
|
||||||
{
|
{
|
||||||
bool was_empty = directory_is_empty(directory);
|
bool was_empty = directory_is_empty(directory);
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
const char *dirname = directory_get_path(directory);
|
const char *dirname = directory_get_path(directory);
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
char path_max_tmp[MPD_PATH_MAX];
|
char path_max_tmp[MPD_PATH_MAX];
|
||||||
enum update_return ret = UPDATE_RETURN_NOUPDATE;
|
enum update_return ret = UPDATE_RETURN_NOUPDATE, ret2;
|
||||||
|
|
||||||
if (!directory->stat && statDirectory(directory) < 0)
|
assert(S_ISDIR(st->st_mode));
|
||||||
return UPDATE_RETURN_ERROR;
|
|
||||||
else if (inodeFoundInParent(directory->parent,
|
directory_set_stat(directory, st);
|
||||||
directory->inode,
|
|
||||||
directory->device))
|
if (inodeFoundInParent(directory->parent,
|
||||||
|
directory->inode, directory->device))
|
||||||
return UPDATE_RETURN_ERROR;
|
return UPDATE_RETURN_ERROR;
|
||||||
|
|
||||||
dir = opendir(opendir_path(path_max_tmp, dirname));
|
dir = opendir(opendir_path(path_max_tmp, dirname));
|
||||||
@ -333,6 +328,8 @@ updateDirectory(struct directory *directory)
|
|||||||
|
|
||||||
while ((ent = readdir(dir))) {
|
while ((ent = readdir(dir))) {
|
||||||
char *utf8;
|
char *utf8;
|
||||||
|
struct stat st2;
|
||||||
|
|
||||||
if (skip_path(ent->d_name))
|
if (skip_path(ent->d_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -343,9 +340,14 @@ updateDirectory(struct directory *directory)
|
|||||||
if (!isRootDirectory(directory->path))
|
if (!isRootDirectory(directory->path))
|
||||||
utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8),
|
utf8 = pfx_dir(path_max_tmp, utf8, strlen(utf8),
|
||||||
dirname, strlen(dirname));
|
dirname, strlen(dirname));
|
||||||
if (updateInDirectory(directory, path_max_tmp) ==
|
|
||||||
UPDATE_RETURN_UPDATED)
|
if (myStat(path_max_tmp, &st2) == 0)
|
||||||
ret = UPDATE_RETURN_UPDATED;
|
ret2 = updateInDirectory(directory, path_max_tmp,
|
||||||
|
&st2);
|
||||||
|
else
|
||||||
|
ret2 = delete_path(path_max_tmp);
|
||||||
|
if (ret == UPDATE_RETURN_NOUPDATE)
|
||||||
|
ret = ret2;
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
@ -406,7 +408,7 @@ static enum update_return updatePath(const char *path)
|
|||||||
if (myStat(path, &st) < 0)
|
if (myStat(path, &st) < 0)
|
||||||
return delete_path(path);
|
return delete_path(path);
|
||||||
|
|
||||||
return updateInDirectory(addParentPathToDB(path), path);
|
return updateInDirectory(addParentPathToDB(path), path, &st);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * update_task(void *_path)
|
static void * update_task(void *_path)
|
||||||
@ -417,7 +419,13 @@ static void * update_task(void *_path)
|
|||||||
ret = updatePath((char *)_path);
|
ret = updatePath((char *)_path);
|
||||||
free(_path);
|
free(_path);
|
||||||
} else {
|
} else {
|
||||||
ret = updateDirectory(db_get_root());
|
struct directory *directory = db_get_root();
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (myStat(directory_get_path(directory), &st) == 0)
|
||||||
|
ret = updateDirectory(directory, &st);
|
||||||
|
else
|
||||||
|
ret = UPDATE_RETURN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == UPDATE_RETURN_UPDATED && db_save() < 0)
|
if (ret == UPDATE_RETURN_UPDATED && db_save() < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user