stat() all files in folder immediately; do not store stat buffer in file structure, to reduce memory consumption
This commit is contained in:
parent
a621681e7f
commit
9389a2ef3a
@ -52,8 +52,7 @@ struct _MooFile
|
|||||||
guint8 icon;
|
guint8 icon;
|
||||||
const char *mime_type;
|
const char *mime_type;
|
||||||
int ref_count;
|
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);
|
const char *dirname);
|
||||||
void _moo_file_stat (MooFile *file,
|
void _moo_file_stat (MooFile *file,
|
||||||
const char *dirname);
|
const char *dirname);
|
||||||
|
void _moo_file_free_statbuf (MooFile *file);
|
||||||
void _moo_file_find_mime_type (MooFile *file,
|
void _moo_file_find_mime_type (MooFile *file,
|
||||||
const char *path);
|
const char *path);
|
||||||
|
|
||||||
|
@ -87,10 +87,7 @@ void
|
|||||||
_moo_file_find_mime_type (MooFile *file,
|
_moo_file_find_mime_type (MooFile *file,
|
||||||
const char *path)
|
const char *path)
|
||||||
{
|
{
|
||||||
if (file->flags & MOO_FILE_HAS_STAT)
|
file->mime_type = xdg_mime_get_mime_type_for_file (path, file->statbuf);
|
||||||
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);
|
|
||||||
|
|
||||||
if (!file->mime_type || !file->mime_type[0])
|
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);
|
g_return_val_if_fail (display_name != NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
file = g_new0 (MooFile, 1);
|
file = _moo_new0 (MooFile);
|
||||||
file->ref_count = 1;
|
file->ref_count = 1;
|
||||||
|
|
||||||
file->name = g_strdup (basename);
|
file->name = g_strdup (basename);
|
||||||
@ -171,7 +168,8 @@ _moo_file_unref (MooFile *file)
|
|||||||
g_free (file->case_display_name);
|
g_free (file->case_display_name);
|
||||||
g_free (file->collation_key);
|
g_free (file->collation_key);
|
||||||
g_free (file->link_target);
|
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;
|
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)
|
if (errno == ENOENT)
|
||||||
{
|
{
|
||||||
@ -219,7 +220,7 @@ _moo_file_stat (MooFile *file,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef S_ISLNK
|
#ifdef S_ISLNK
|
||||||
if (S_ISLNK (file->statbuf.st_mode))
|
if (S_ISLNK (file->statbuf->st_mode))
|
||||||
{
|
{
|
||||||
static char buf[1024];
|
static char buf[1024];
|
||||||
gssize len;
|
gssize len;
|
||||||
@ -227,7 +228,7 @@ _moo_file_stat (MooFile *file,
|
|||||||
file->info |= MOO_FILE_INFO_IS_LINK;
|
file->info |= MOO_FILE_INFO_IS_LINK;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
if (g_stat (fullname, &file->statbuf) != 0)
|
if (g_stat (fullname, file->statbuf) != 0)
|
||||||
{
|
{
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
{
|
{
|
||||||
@ -272,22 +273,22 @@ _moo_file_stat (MooFile *file,
|
|||||||
if ((file->info & MOO_FILE_INFO_EXISTS) &&
|
if ((file->info & MOO_FILE_INFO_EXISTS) &&
|
||||||
!(file->info & MOO_FILE_INFO_IS_LOCKED))
|
!(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;
|
file->info |= MOO_FILE_INFO_IS_DIR;
|
||||||
#ifdef S_ISBLK
|
#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;
|
file->info |= MOO_FILE_INFO_IS_BLOCK_DEV;
|
||||||
#endif
|
#endif
|
||||||
#ifdef S_ISCHR
|
#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;
|
file->info |= MOO_FILE_INFO_IS_CHAR_DEV;
|
||||||
#endif
|
#endif
|
||||||
#ifdef S_ISFIFO
|
#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;
|
file->info |= MOO_FILE_INFO_IS_FIFO;
|
||||||
#endif
|
#endif
|
||||||
#ifdef S_ISSOCK
|
#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;
|
file->info |= MOO_FILE_INFO_IS_SOCKET;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -306,6 +307,15 @@ _moo_file_stat (MooFile *file,
|
|||||||
g_free (fullname);
|
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
|
gboolean
|
||||||
_moo_file_test (const MooFile *file,
|
_moo_file_test (const MooFile *file,
|
||||||
|
@ -47,6 +47,7 @@ struct _MooFileSystemPrivate {
|
|||||||
GHashTable *folders;
|
GHashTable *folders;
|
||||||
MooFileWatch *fam;
|
MooFileWatch *fam;
|
||||||
FoldersCache cache;
|
FoldersCache cache;
|
||||||
|
guint debug_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
static MooFileSystem *fs_instance = NULL;
|
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
|
static void
|
||||||
_moo_file_system_init (MooFileSystem *fs)
|
_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->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.queue = g_queue_new ();
|
||||||
fs->priv->cache.paths = g_hash_table_new (g_str_hash, g_str_equal);
|
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);
|
moo_file_watch_unref (fs->priv->fam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fs->priv->debug_timeout)
|
||||||
|
g_source_remove (fs->priv->debug_timeout);
|
||||||
|
|
||||||
g_free (fs->priv);
|
g_free (fs->priv);
|
||||||
fs->priv = NULL;
|
fs->priv = NULL;
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,8 @@ void _moo_file_system_folder_finalized (MooFileSystem *fs,
|
|||||||
void _moo_file_system_folder_deleted (MooFileSystem *fs,
|
void _moo_file_system_folder_deleted (MooFileSystem *fs,
|
||||||
MooFolderImpl *folder);
|
MooFolderImpl *folder);
|
||||||
|
|
||||||
|
gsize _moo_folder_mem_usage (MooFolder *folder);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -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 *
|
MooFolder *
|
||||||
_moo_folder_new_with_impl (MooFolderImpl *impl)
|
_moo_folder_new_with_impl (MooFolderImpl *impl)
|
||||||
{
|
{
|
||||||
@ -472,6 +497,7 @@ get_names (MooFolderImpl *impl)
|
|||||||
file->icon = _moo_file_icon_blank ();
|
file->icon = _moo_file_icon_blank ();
|
||||||
g_hash_table_insert (impl->files, g_strdup (name), file);
|
g_hash_table_insert (impl->files, g_strdup (name), file);
|
||||||
added = g_slist_prepend (added, file);
|
added = g_slist_prepend (added, file);
|
||||||
|
_moo_file_stat (file, impl->path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -655,6 +681,7 @@ get_icons_a_bit (MooFolderImpl *impl)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_moo_file_free_statbuf (file);
|
||||||
_moo_file_unref (file);
|
_moo_file_unref (file);
|
||||||
g_slist_free (changed);
|
g_slist_free (changed);
|
||||||
|
|
||||||
@ -914,6 +941,8 @@ file_created (MooFolderImpl *impl,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_moo_file_free_statbuf (file);
|
||||||
|
|
||||||
g_hash_table_insert (impl->files, g_strdup (name), file);
|
g_hash_table_insert (impl->files, g_strdup (name), file);
|
||||||
list = g_slist_append (NULL, file);
|
list = g_slist_append (NULL, file);
|
||||||
folder_emit_files (impl, FILES_ADDED, list);
|
folder_emit_files (impl, FILES_ADDED, list);
|
||||||
@ -1011,9 +1040,10 @@ moo_file_get_type_string (MooFile *file)
|
|||||||
|
|
||||||
/* XXX */
|
/* XXX */
|
||||||
static char *
|
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;
|
return NULL;
|
||||||
#endif
|
#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);
|
return g_strdup (buf);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1092,7 +1124,7 @@ _moo_folder_get_file_info (MooFolder *folder,
|
|||||||
if (!(file->info & MOO_FILE_INFO_IS_DIR))
|
if (!(file->info & MOO_FILE_INFO_IS_DIR))
|
||||||
{
|
{
|
||||||
g_ptr_array_add (array, g_strdup ("Size:"));
|
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);
|
mtime = moo_file_get_mtime_string (file);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user