mirror of https://github.com/MidnightCommander/mc
Make VFS faster a bit.
Each VSF entry is added to VFS using vfs_s_insert_entry() via g_list_append(). For long lists, a lot of walking through entire list is performed. To get rid that, change type of vfs_s_inode::subdir from GList to GQueue. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
a5826c3f6e
commit
7ce3ca0991
|
@ -196,7 +196,7 @@ vfs_s_find_entry_tree (struct vfs_class *me, struct vfs_s_inode *root,
|
|||
for (pseg = 0; path[pseg] != '\0' && !IS_PATH_SEP (path[pseg]); pseg++)
|
||||
;
|
||||
|
||||
for (iter = root->subdir; iter != NULL; iter = g_list_next (iter))
|
||||
for (iter = g_queue_peek_head_link (root->subdir); iter != NULL; iter = g_list_next (iter))
|
||||
{
|
||||
ent = VFS_ENTRY (iter->data);
|
||||
if (strlen (ent->name) == pseg && strncmp (ent->name, path, pseg) == 0)
|
||||
|
@ -259,7 +259,7 @@ vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root,
|
|||
return ent;
|
||||
}
|
||||
|
||||
iter = g_list_find_custom (root->subdir, path, (GCompareFunc) vfs_s_entry_compare);
|
||||
iter = g_queue_find_custom (root->subdir, path, (GCompareFunc) vfs_s_entry_compare);
|
||||
ent = iter != NULL ? VFS_ENTRY (iter->data) : NULL;
|
||||
|
||||
if (ent != NULL && !VFS_SUBCLASS (me)->dir_uptodate (me, ent->ino))
|
||||
|
@ -286,7 +286,7 @@ vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root,
|
|||
|
||||
vfs_s_insert_entry (me, root, ent);
|
||||
|
||||
iter = g_list_find_custom (root->subdir, path, (GCompareFunc) vfs_s_entry_compare);
|
||||
iter = g_queue_find_custom (root->subdir, path, (GCompareFunc) vfs_s_entry_compare);
|
||||
ent = iter != NULL ? VFS_ENTRY (iter->data) : NULL;
|
||||
}
|
||||
if (ent == NULL)
|
||||
|
@ -441,7 +441,7 @@ vfs_s_opendir (const vfs_path_t * vpath)
|
|||
}
|
||||
#endif
|
||||
info = g_new (struct dirhandle, 1);
|
||||
info->cur = dir->subdir;
|
||||
info->cur = g_queue_peek_head_link (dir->subdir);
|
||||
info->dir = dir;
|
||||
|
||||
return info;
|
||||
|
@ -888,6 +888,7 @@ vfs_s_new_inode (struct vfs_class *me, struct vfs_s_super *super, struct stat *i
|
|||
if (initstat != NULL)
|
||||
ino->st = *initstat;
|
||||
ino->super = super;
|
||||
ino->subdir = g_queue_new ();
|
||||
ino->st.st_nlink = 0;
|
||||
ino->st.st_ino = VFS_SUBCLASS (me)->inode_counter++;
|
||||
ino->st.st_dev = VFS_SUBCLASS (me)->rdev;
|
||||
|
@ -914,8 +915,16 @@ vfs_s_free_inode (struct vfs_class *me, struct vfs_s_inode *ino)
|
|||
return;
|
||||
}
|
||||
|
||||
while (ino->subdir != NULL)
|
||||
vfs_s_free_entry (me, VFS_ENTRY (ino->subdir->data));
|
||||
while (g_queue_get_length (ino->subdir) != 0)
|
||||
{
|
||||
struct vfs_s_entry *entry;
|
||||
|
||||
entry = VFS_ENTRY (g_queue_peek_head (ino->subdir));
|
||||
vfs_s_free_entry (me, entry);
|
||||
}
|
||||
|
||||
g_queue_free (ino->subdir);
|
||||
ino->subdir = NULL;
|
||||
|
||||
CALL (free_inode) (me, ino);
|
||||
g_free (ino->linkname);
|
||||
|
@ -951,7 +960,7 @@ void
|
|||
vfs_s_free_entry (struct vfs_class *me, struct vfs_s_entry *ent)
|
||||
{
|
||||
if (ent->dir != NULL)
|
||||
ent->dir->subdir = g_list_remove (ent->dir->subdir, ent);
|
||||
g_queue_remove (ent->dir->subdir, ent);
|
||||
|
||||
MC_PTR_FREE (ent->name);
|
||||
|
||||
|
@ -974,7 +983,7 @@ vfs_s_insert_entry (struct vfs_class *me, struct vfs_s_inode *dir, struct vfs_s_
|
|||
ent->dir = dir;
|
||||
|
||||
ent->ino->st.st_nlink++;
|
||||
dir->subdir = g_list_append (dir->subdir, ent);
|
||||
g_queue_push_tail (dir->subdir, ent);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -1708,7 +1717,8 @@ vfs_s_normalize_filename_leading_spaces (struct vfs_s_inode *root_inode, size_t
|
|||
{
|
||||
GList *iter;
|
||||
|
||||
for (iter = root_inode->subdir; iter != NULL; iter = g_list_next (iter))
|
||||
for (iter = g_queue_peek_head_link (root_inode->subdir); iter != NULL;
|
||||
iter = g_list_next (iter))
|
||||
{
|
||||
struct vfs_s_entry *entry = VFS_ENTRY (iter->data);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ struct vfs_s_inode
|
|||
struct vfs_s_entry *ent; /* Our entry in the parent directory -
|
||||
use only for directories because they
|
||||
cannot be hardlinked */
|
||||
GList *subdir; /* If this is a directory, its entry. List of vfs_s_entry */
|
||||
GQueue *subdir; /* If this is a directory, its entry. List of vfs_s_entry */
|
||||
struct stat st; /* Parameters of this inode */
|
||||
char *linkname; /* Symlink's contents */
|
||||
char *localname; /* Filename of local file, if we have one */
|
||||
|
|
|
@ -271,7 +271,7 @@ extfs_find_entry_int (struct vfs_s_inode *dir, const char *name, GSList * list,
|
|||
}
|
||||
|
||||
pdir = pent;
|
||||
pl = g_list_find_custom (pent->ino->subdir, p, vfs_s_entry_compare);
|
||||
pl = g_queue_find_custom (pent->ino->subdir, p, vfs_s_entry_compare);
|
||||
pent = pl != NULL ? VFS_ENTRY (pl->data) : NULL;
|
||||
if (pent != NULL && q + 1 > name_end)
|
||||
{
|
||||
|
@ -512,13 +512,13 @@ extfs_read_archive (FILE * extfsd, struct extfs_super_t *current_archive)
|
|||
{
|
||||
entry = extfs_entry_new (super->me, p, pent->ino);
|
||||
entry->dir = pent->ino;
|
||||
pent->ino->subdir = g_list_append (pent->ino->subdir, entry);
|
||||
g_queue_push_tail (pent->ino->subdir, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = extfs_entry_new (super->me, p, super->root);
|
||||
entry->dir = super->root;
|
||||
super->root->subdir = g_list_append (super->root->subdir, entry);
|
||||
g_queue_push_tail (super->root->subdir, entry);
|
||||
}
|
||||
|
||||
if (!S_ISLNK (hstat.st_mode) && (current_link_name != NULL))
|
||||
|
@ -1014,7 +1014,7 @@ extfs_opendir (const vfs_path_t * vpath)
|
|||
ERRNOR (ENOTDIR, NULL);
|
||||
|
||||
info = g_new (GList *, 1);
|
||||
*info = entry->ino->subdir;
|
||||
*info = g_queue_peek_head_link (entry->ino->subdir);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue