Directory: don't allocate stat information dynamically
This should save a few thousand ops. Not worth it to malloc for such a small (3-words on 32-bit ARM and x86) structures. Signed-off-by: Eric Wong <normalperson@yhbt.net>
This commit is contained in:

committed by
Max Kellermann

parent
3263dbe517
commit
d095d52ed4
@@ -225,19 +225,11 @@ int updateInit(List * pathList)
|
|||||||
return (int)directory_updateJobId;
|
return (int)directory_updateJobId;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DirectoryStat *newDirectoryStat(struct stat *st)
|
static void directory_set_stat(Directory * dir, const struct stat *st)
|
||||||
{
|
{
|
||||||
DirectoryStat *ret = xmalloc(sizeof(DirectoryStat));
|
dir->inode = st->st_ino;
|
||||||
ret->inode = st->st_ino;
|
dir->device = st->st_dev;
|
||||||
ret->device = st->st_dev;
|
dir->stat = 1;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void freeDirectoryStatFromDirectory(Directory * dir)
|
|
||||||
{
|
|
||||||
if (dir->stat)
|
|
||||||
free(dir->stat);
|
|
||||||
dir->stat = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DirectoryList *newDirectoryList(void)
|
static DirectoryList *newDirectoryList(void)
|
||||||
@@ -257,7 +249,9 @@ static Directory *newDirectory(const char *dirname, Directory * parent)
|
|||||||
directory->path = NULL;
|
directory->path = NULL;
|
||||||
directory->subDirectories = newDirectoryList();
|
directory->subDirectories = newDirectoryList();
|
||||||
directory->songs = newSongList();
|
directory->songs = newSongList();
|
||||||
directory->stat = NULL;
|
directory->stat = 0;
|
||||||
|
directory->inode = 0;
|
||||||
|
directory->device = 0;
|
||||||
directory->parent = parent;
|
directory->parent = parent;
|
||||||
|
|
||||||
return directory;
|
return directory;
|
||||||
@@ -269,7 +263,6 @@ static void freeDirectory(Directory * directory)
|
|||||||
freeSongList(directory->songs);
|
freeSongList(directory->songs);
|
||||||
if (directory->path)
|
if (directory->path)
|
||||||
free(directory->path);
|
free(directory->path);
|
||||||
freeDirectoryStatFromDirectory(directory);
|
|
||||||
free(directory);
|
free(directory);
|
||||||
/* this resets last dir returned */
|
/* this resets last dir returned */
|
||||||
/*getDirectoryPath(NULL); */
|
/*getDirectoryPath(NULL); */
|
||||||
@@ -339,8 +332,7 @@ static int updateInDirectory(Directory * directory,
|
|||||||
} else if (S_ISDIR(st.st_mode)) {
|
} else if (S_ISDIR(st.st_mode)) {
|
||||||
if (findInList
|
if (findInList
|
||||||
(directory->subDirectories, shortname, (void **)&subDir)) {
|
(directory->subDirectories, shortname, (void **)&subDir)) {
|
||||||
freeDirectoryStatFromDirectory(subDir);
|
directory_set_stat((Directory *)subDir, &st);
|
||||||
((Directory *) subDir)->stat = newDirectoryStat(&st);
|
|
||||||
return updateDirectory((Directory *) subDir);
|
return updateDirectory((Directory *) subDir);
|
||||||
} else {
|
} else {
|
||||||
return addSubDirectoryToDirectory(directory, shortname,
|
return addSubDirectoryToDirectory(directory, shortname,
|
||||||
@@ -525,8 +517,8 @@ static int updatePath(const char *utf8path)
|
|||||||
}
|
}
|
||||||
/* if this song update is successfull, we are done */
|
/* if this song update is successfull, we are done */
|
||||||
else if (0 == inodeFoundInParent(parentDirectory->parent,
|
else if (0 == inodeFoundInParent(parentDirectory->parent,
|
||||||
parentDirectory->stat->inode,
|
parentDirectory->inode,
|
||||||
parentDirectory->stat->device)
|
parentDirectory->device)
|
||||||
&& song &&
|
&& song &&
|
||||||
isMusic(get_song_url(path_max_tmp, song), &mtime, 0)) {
|
isMusic(get_song_url(path_max_tmp, song), &mtime, 0)) {
|
||||||
free(path);
|
free(path);
|
||||||
@@ -557,9 +549,8 @@ static int updatePath(const char *utf8path)
|
|||||||
if (!parentDirectory || (!parentDirectory->stat &&
|
if (!parentDirectory || (!parentDirectory->stat &&
|
||||||
statDirectory(parentDirectory) < 0)) {
|
statDirectory(parentDirectory) < 0)) {
|
||||||
} else if (0 == inodeFoundInParent(parentDirectory->parent,
|
} else if (0 == inodeFoundInParent(parentDirectory->parent,
|
||||||
parentDirectory->stat->inode,
|
parentDirectory->inode,
|
||||||
parentDirectory->stat->
|
parentDirectory->device)
|
||||||
device)
|
|
||||||
&& addToDirectory(parentDirectory, shortname, path)
|
&& addToDirectory(parentDirectory, shortname, path)
|
||||||
> 0) {
|
> 0) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@@ -595,8 +586,8 @@ static int updateDirectory(Directory * directory)
|
|||||||
if (!directory->stat && statDirectory(directory) < 0)
|
if (!directory->stat && statDirectory(directory) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
else if (inodeFoundInParent(directory->parent,
|
else if (inodeFoundInParent(directory->parent,
|
||||||
directory->stat->inode,
|
directory->inode,
|
||||||
directory->stat->device))
|
directory->device))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
dir = opendir(opendir_path(path_max_tmp, dirname));
|
dir = opendir(opendir_path(path_max_tmp, dirname));
|
||||||
@@ -678,7 +669,7 @@ static int statDirectory(Directory * dir)
|
|||||||
if (myStat(getDirectoryPath(dir), &st) < 0)
|
if (myStat(getDirectoryPath(dir), &st) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
dir->stat = newDirectoryStat(&st);
|
directory_set_stat(dir, &st);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -686,12 +677,9 @@ static int statDirectory(Directory * dir)
|
|||||||
static int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device)
|
static int inodeFoundInParent(Directory * parent, ino_t inode, dev_t device)
|
||||||
{
|
{
|
||||||
while (parent) {
|
while (parent) {
|
||||||
if (!parent->stat) {
|
if (!parent->stat && statDirectory(parent) < 0)
|
||||||
if (statDirectory(parent) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
if (parent->inode == inode && parent->device == device) {
|
||||||
if (parent->stat->inode == inode &&
|
|
||||||
parent->stat->device == device) {
|
|
||||||
DEBUG("recursive directory found\n");
|
DEBUG("recursive directory found\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -711,7 +699,7 @@ static int addSubDirectoryToDirectory(Directory * directory,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
subDirectory = newDirectory(name, directory);
|
subDirectory = newDirectory(name, directory);
|
||||||
subDirectory->stat = newDirectoryStat(st);
|
directory_set_stat(subDirectory, st);
|
||||||
|
|
||||||
if (exploreDirectory(subDirectory) < 1) {
|
if (exploreDirectory(subDirectory) < 1) {
|
||||||
freeDirectory(subDirectory);
|
freeDirectory(subDirectory);
|
||||||
@@ -1228,23 +1216,10 @@ int traverseAllIn(const char *name,
|
|||||||
data);
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeAllDirectoryStats(Directory * directory)
|
|
||||||
{
|
|
||||||
ListNode *node = directory->subDirectories->firstNode;
|
|
||||||
|
|
||||||
while (node != NULL) {
|
|
||||||
freeAllDirectoryStats((Directory *) node->data);
|
|
||||||
node = node->nextNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
freeDirectoryStatFromDirectory(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void initMp3Directory(void)
|
void initMp3Directory(void)
|
||||||
{
|
{
|
||||||
mp3rootDirectory = newDirectory(NULL, NULL);
|
mp3rootDirectory = newDirectory(NULL, NULL);
|
||||||
exploreDirectory(mp3rootDirectory);
|
exploreDirectory(mp3rootDirectory);
|
||||||
freeAllDirectoryStats(mp3rootDirectory);
|
|
||||||
stats.numberOfSongs = countSongsIn(NULL);
|
stats.numberOfSongs = countSongsIn(NULL);
|
||||||
stats.dbPlayTime = sumSongTimesIn(NULL);
|
stats.dbPlayTime = sumSongTimesIn(NULL);
|
||||||
}
|
}
|
||||||
|
@@ -23,17 +23,14 @@
|
|||||||
|
|
||||||
typedef List DirectoryList;
|
typedef List DirectoryList;
|
||||||
|
|
||||||
typedef struct _DirectoryStat {
|
|
||||||
ino_t inode;
|
|
||||||
dev_t device;
|
|
||||||
} DirectoryStat;
|
|
||||||
|
|
||||||
typedef struct _Directory {
|
typedef struct _Directory {
|
||||||
char *path;
|
char *path;
|
||||||
DirectoryList *subDirectories;
|
DirectoryList *subDirectories;
|
||||||
SongList *songs;
|
SongList *songs;
|
||||||
struct _Directory *parent;
|
struct _Directory *parent;
|
||||||
DirectoryStat *stat;
|
ino_t inode;
|
||||||
|
dev_t device;
|
||||||
|
unsigned stat; /* not needed if ino_t == dev_t == 0 is impossible */
|
||||||
} Directory;
|
} Directory;
|
||||||
|
|
||||||
void readDirectoryDBIfUpdateIsFinished(void);
|
void readDirectoryDBIfUpdateIsFinished(void);
|
||||||
|
Reference in New Issue
Block a user