stat() all files in folder immediately; do not store stat buffer in file structure, to reduce memory consumption

This commit is contained in:
Yevgen Muntyan 2007-03-13 01:29:11 -05:00
parent a621681e7f
commit 9389a2ef3a
5 changed files with 90 additions and 20 deletions

View File

@ -52,8 +52,7 @@ struct _MooFile
guint8 icon;
const char *mime_type;
int ref_count;
/* TODO: who needs whole structure? */
struct stat statbuf;
struct stat *statbuf;
};
@ -88,6 +87,7 @@ guint8 _moo_file_get_icon_type (MooFile *file,
const char *dirname);
void _moo_file_stat (MooFile *file,
const char *dirname);
void _moo_file_free_statbuf (MooFile *file);
void _moo_file_find_mime_type (MooFile *file,
const char *path);

View File

@ -87,10 +87,7 @@ void
_moo_file_find_mime_type (MooFile *file,
const char *path)
{
if (file->flags & MOO_FILE_HAS_STAT)
file->mime_type = xdg_mime_get_mime_type_for_file (path, &file->statbuf);
else
file->mime_type = xdg_mime_get_mime_type_for_file (path, NULL);
file->mime_type = xdg_mime_get_mime_type_for_file (path, file->statbuf);
if (!file->mime_type || !file->mime_type[0])
{
@ -131,7 +128,7 @@ _moo_file_new (const char *dirname,
g_return_val_if_fail (display_name != NULL, NULL);
}
file = g_new0 (MooFile, 1);
file = _moo_new0 (MooFile);
file->ref_count = 1;
file->name = g_strdup (basename);
@ -171,7 +168,8 @@ _moo_file_unref (MooFile *file)
g_free (file->case_display_name);
g_free (file->collation_key);
g_free (file->link_target);
g_free (file);
_moo_free (struct stat, file->statbuf);
_moo_free (MooFile, file);
}
}
@ -194,7 +192,10 @@ _moo_file_stat (MooFile *file,
errno = 0;
if (g_lstat (fullname, &file->statbuf) != 0)
if (!file->statbuf)
file->statbuf = _moo_new (struct stat);
if (g_lstat (fullname, file->statbuf) != 0)
{
if (errno == ENOENT)
{
@ -219,7 +220,7 @@ _moo_file_stat (MooFile *file,
else
{
#ifdef S_ISLNK
if (S_ISLNK (file->statbuf.st_mode))
if (S_ISLNK (file->statbuf->st_mode))
{
static char buf[1024];
gssize len;
@ -227,7 +228,7 @@ _moo_file_stat (MooFile *file,
file->info |= MOO_FILE_INFO_IS_LINK;
errno = 0;
if (g_stat (fullname, &file->statbuf) != 0)
if (g_stat (fullname, file->statbuf) != 0)
{
if (errno == ENOENT)
{
@ -272,22 +273,22 @@ _moo_file_stat (MooFile *file,
if ((file->info & MOO_FILE_INFO_EXISTS) &&
!(file->info & MOO_FILE_INFO_IS_LOCKED))
{
if (S_ISDIR (file->statbuf.st_mode))
if (S_ISDIR (file->statbuf->st_mode))
file->info |= MOO_FILE_INFO_IS_DIR;
#ifdef S_ISBLK
else if (S_ISBLK (file->statbuf.st_mode))
else if (S_ISBLK (file->statbuf->st_mode))
file->info |= MOO_FILE_INFO_IS_BLOCK_DEV;
#endif
#ifdef S_ISCHR
else if (S_ISCHR (file->statbuf.st_mode))
else if (S_ISCHR (file->statbuf->st_mode))
file->info |= MOO_FILE_INFO_IS_CHAR_DEV;
#endif
#ifdef S_ISFIFO
else if (S_ISFIFO (file->statbuf.st_mode))
else if (S_ISFIFO (file->statbuf->st_mode))
file->info |= MOO_FILE_INFO_IS_FIFO;
#endif
#ifdef S_ISSOCK
else if (S_ISSOCK (file->statbuf.st_mode))
else if (S_ISSOCK (file->statbuf->st_mode))
file->info |= MOO_FILE_INFO_IS_SOCKET;
#endif
}
@ -306,6 +307,15 @@ _moo_file_stat (MooFile *file,
g_free (fullname);
}
void
_moo_file_free_statbuf (MooFile *file)
{
g_return_if_fail (file != NULL);
_moo_free (struct stat, file->statbuf);
file->statbuf = NULL;
file->flags &= ~MOO_FILE_HAS_STAT;
}
gboolean
_moo_file_test (const MooFile *file,

View File

@ -47,6 +47,7 @@ struct _MooFileSystemPrivate {
GHashTable *folders;
MooFileWatch *fam;
FoldersCache cache;
guint debug_timeout;
};
static MooFileSystem *fs_instance = NULL;
@ -210,6 +211,25 @@ _moo_file_system_folder_finalized (MooFileSystem *fs,
}
static void
calc_mem_hash_cb (G_GNUC_UNUSED const char *name,
MooFolder *folder,
gsize *mem)
{
mem[0] += _moo_folder_mem_usage (folder);
mem[1] += g_hash_table_size (folder->impl->files);
}
static gboolean
debug_timeout (MooFileSystem *fs)
{
gsize mem[2] = {0, 0};
g_hash_table_foreach (fs->priv->folders, (GHFunc) calc_mem_hash_cb, mem);
g_print ("%u bytes in %u files\n", mem[0], mem[1]);
return TRUE;
}
static void
_moo_file_system_init (MooFileSystem *fs)
{
@ -217,6 +237,9 @@ _moo_file_system_init (MooFileSystem *fs)
fs->priv->folders = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
fs->priv->cache.queue = g_queue_new ();
fs->priv->cache.paths = g_hash_table_new (g_str_hash, g_str_equal);
if (0)
fs->priv->debug_timeout = g_timeout_add (5000, (GSourceFunc) debug_timeout, fs);
}
@ -238,6 +261,9 @@ moo_file_system_dispose (GObject *object)
moo_file_watch_unref (fs->priv->fam);
}
if (fs->priv->debug_timeout)
g_source_remove (fs->priv->debug_timeout);
g_free (fs->priv);
fs->priv = NULL;
}

View File

@ -104,6 +104,8 @@ void _moo_file_system_folder_finalized (MooFileSystem *fs,
void _moo_file_system_folder_deleted (MooFileSystem *fs,
MooFolderImpl *folder);
gsize _moo_folder_mem_usage (MooFolder *folder);
G_END_DECLS

View File

@ -231,6 +231,31 @@ moo_folder_dispose (GObject *object)
}
static void
add_file_size (G_GNUC_UNUSED const char *filename,
MooFile *file,
gsize *mem)
{
*mem += sizeof *file;
#define STRING_SIZE(s) ((s) ? (strlen (s) + 1) : 0)
*mem += STRING_SIZE (file->name);
*mem += STRING_SIZE (file->link_target);
*mem += STRING_SIZE (file->display_name);
*mem += STRING_SIZE (file->case_display_name);
*mem += STRING_SIZE (file->collation_key);
#undef STRING_SIZE
}
gsize
_moo_folder_mem_usage (MooFolder *folder)
{
gsize mem = 0;
mem += sizeof (MooFolderImpl);
g_hash_table_foreach (folder->impl->files, (GHFunc) add_file_size, &mem);
return mem;
}
MooFolder *
_moo_folder_new_with_impl (MooFolderImpl *impl)
{
@ -472,6 +497,7 @@ get_names (MooFolderImpl *impl)
file->icon = _moo_file_icon_blank ();
g_hash_table_insert (impl->files, g_strdup (name), file);
added = g_slist_prepend (added, file);
_moo_file_stat (file, impl->path);
}
else
{
@ -655,6 +681,7 @@ get_icons_a_bit (MooFolderImpl *impl)
}
#endif
_moo_file_free_statbuf (file);
_moo_file_unref (file);
g_slist_free (changed);
@ -914,6 +941,8 @@ file_created (MooFolderImpl *impl,
}
#endif
_moo_file_free_statbuf (file);
g_hash_table_insert (impl->files, g_strdup (name), file);
list = g_slist_append (NULL, file);
folder_emit_files (impl, FILES_ADDED, list);
@ -1011,9 +1040,10 @@ moo_file_get_type_string (MooFile *file)
/* XXX */
static char *
moo_file_get_size_string (MooFile *file)
get_size_string (struct stat *statbuf)
{
return g_strdup_printf ("%" G_GINT64_FORMAT, (MooFileSize) file->statbuf.st_size);
g_return_val_if_fail (statbuf != NULL, NULL);
return g_strdup_printf ("%" G_GINT64_FORMAT, (MooFileSize) statbuf->st_size);
}
@ -1031,7 +1061,9 @@ moo_file_get_mtime_string (MooFile *file)
return NULL;
#endif
if (strftime (buf, 1024, "%x %X", localtime ((time_t*)&file->statbuf.st_mtime)))
g_return_val_if_fail (file->statbuf != NULL, NULL);
if (strftime (buf, 1024, "%x %X", localtime ((time_t*)&file->statbuf->st_mtime)))
return g_strdup (buf);
else
return NULL;
@ -1092,7 +1124,7 @@ _moo_folder_get_file_info (MooFolder *folder,
if (!(file->info & MOO_FILE_INFO_IS_DIR))
{
g_ptr_array_add (array, g_strdup ("Size:"));
g_ptr_array_add (array, moo_file_get_size_string (file));
g_ptr_array_add (array, get_size_string (file->statbuf));
}
mtime = moo_file_get_mtime_string (file);