Merge lp:~vikoadi/pantheon-files/fix-1041633 into lp:~elementary-apps/pantheon-files/trunk

Proposed by Viko Adi Rahmawan
Status: Merged
Approved by: Victor Martinez
Approved revision: 1474
Merged at revision: 1499
Proposed branch: lp:~vikoadi/pantheon-files/fix-1041633
Merge into: lp:~elementary-apps/pantheon-files/trunk
Diff against target: 89 lines (+40/-1)
3 files modified
libcore/marlin-icon-info.c (+16/-0)
libcore/marlin-icon-info.h (+1/-0)
src/fm-directory-view.c (+23/-1)
To merge this branch: bzr merge lp:~vikoadi/pantheon-files/fix-1041633
Reviewer Review Type Date Requested Status
Victor Martinez (community) Approve
Sergey "Shnatsel" Davidoff (community) Abstain
Review via email: mp+215547@code.launchpad.net

Commit message

Update thumbnails after file changes. Fixes lp:1041633.

This code removes outdated icons from the cache in icon_info when a file deletion or change occurs.

Description of the change

clear thumbnail cache in icon_info on every file deletion and changes

To post a comment you must log in.
Revision history for this message
Danielle Foré (danrabbit) wrote :

This works great for me. The effect is instantaneous!

Revision history for this message
Sergey "Shnatsel" Davidoff (shnatsel) wrote :

I can't tell from the code if it deletes the thumbnail on every file change. If so, we've tried that approach already and gave up on it because it yeilds 100% CPU load on continuously written files (e.g. large downloads).

Instead, inotify provides a "close_write" event, which is emitted when *closing* a file that was written to. Please use such an event instead.

review: Needs Information
Revision history for this message
Viko Adi Rahmawan (vikoadi) wrote :

i think you misunderstood the cache cleaning here. the cache is only in memory (see it in marlin-icon-info.c) not the thumbnail file in .thumbnail that is being managed by tumbler.
before this cache cleaning, thumbnail file is already generated by tumbler but the cache in marlin-icon-info is not updated because because there is already with same name.
i dont know whether it will cause 100% load i will checked it later, because right know i just call the cleaning function from fm-directory-view, (just before tumbler update get requested). if it cause overload, ill try to move it to close_write

Revision history for this message
Viko Adi Rahmawan (vikoadi) wrote :

Okay so the cache cleaning is only done in every FileMonitorEvent.CHANGES_DONE_HINT. it should not be as often as FileMonitor.changed but it wouldnot be as good as inotify close_write one. (I still dont understand how CHANGES_DONE_HINT supposed to work).
I dont think its worth it to convert FileMonitor to inotify, and i have test it and its not overload the CPU in my i3 2GB-ram laptop.

Revision history for this message
Victor Martinez (victored) wrote :

Make sure 'icon_file' and 'icon' are freed before returning from 'remove_all_size_cache'. You only need to call g_object_unref:

[...]

ret_val = g_icon_equal (lookup_key->icon, icon);

g_object_unref (icon_file);
g_object_unref (icon);

return ret_val;

[...]

Regarding the implementation, traversing the _whole_ icon Hash Table every time a thumbnail update occurs just to determine whether an item should be removed is too inefficient. Please consider that 'reap_cache' is already doing that to free cache elements older than 30 secs. If we wanted linear access time we'd have used a linked list from the beginning.

You can lookup the GFileIcon you want directly in constant time from marlin_icon_info_remove_updated_icon:

MarlinIconInfo *icon_info;
LoadableIconKey lookup_key;

lookup_key.icon = icon;

/* desired icon size should be requested as parameter */
lookup_key.size = size;

/* if the underlying GFileIcon file is the same, this lookup will return the icon info corresponding to icon->file */
icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key);

if (icon_info != NULL)
    g_hash_table_remove (loadable_icon_cache, &lookup_key);

Avoid 'g_hash_table_foreach_remove' at all costs, and make sure the code style is consistent with the rest of the file.

review: Needs Fixing
1469. By Viko Adi Rahmawan

dont iterate through all hast table

1470. By Viko Adi Rahmawan

iterate through all ZOOM_LEVEL

Revision history for this message
Viko Adi Rahmawan (vikoadi) wrote :

everythings changed.
no more iterating through hash table

Revision history for this message
Sergey "Shnatsel" Davidoff (shnatsel) :
review: Abstain
1471. By Viko Adi Rahmawan

remove uneeded include, fix style

Revision history for this message
Victor Martinez (victored) wrote :

Thanks for your great work!

Some suggestions:

marlin_icon_info_remove_cache: it's OK to try to remove things that don't exist in the Hash Table. So the function can call 'g_hash_table_remove' directly without calling 'marlin_icon_info_lookup' first. 'icon_info' is not necessary either.

Since the code is using 'loadable_icon_key_new' we need to call 'loadable_icon_key_free' after using the 'lookup_key'. Otherwise the memory for 'lookup_key' and 'lookup_key->icon' is leaked.

fm-directory-view.c:

Duplicate code should be merged in a single function.

Coding style doesn't try to match the rest of the file. This is important. You'll notice opening braces go on a separate line.

1472. By Viko Adi Rahmawan

combine duplicated code, code style cleaning, no nore marlin_icon_info_lookup, memory freeing

Revision history for this message
Viko Adi Rahmawan (vikoadi) wrote :

sorry for bothering alot, im not familiar with c and memory management, but this bug is really annoy me.
would love to see more suggestions.

Revision history for this message
Viko Adi Rahmawan (vikoadi) wrote :

why its alwasy "\ No newline at end of file" everytime i changed file? i use Scratch
and should i just commit to fix conlicts?

Revision history for this message
Victor Martinez (victored) wrote :

This looks great!

It appears to work for me, after solving the merge conflicts.

Using Scratch:

1) Delete diff lines 80 and 81
2) Diff line 88 should use "const char* path = ..." instead of "char* path = ..."
3) Make sure diff line 98 only has a single character: '}'

Suggestions:

'remove_marlin_icon_info_cache' should be 'static void' so that it's private to 'fm-directory-view.c'.

Commit the changes with bzr.

Merge trunk again with 'bzr merge'

Push the changes here :)

Revision history for this message
Victor Martinez (victored) wrote :

I agree it's kind of annoying Scratch always changes the EOF character. Gedit seems to keep the one in the original file before saving. Not a big deal for us though. We prefer Scratch anytime.

1473. By Viko Adi Rahmawan

use static void remove_marlin_icon_info_cache

1474. By Viko Adi Rahmawan

merge with trunk

Revision history for this message
Victor Martinez (victored) wrote :

Great work Viko!

The bugs described in the bug report have indeed been fixed, even after changing the zoom level :D

I can confirm this fix doesn't introduce a performance penalty.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libcore/marlin-icon-info.c'
2--- libcore/marlin-icon-info.c 2014-03-12 23:46:52 +0000
3+++ libcore/marlin-icon-info.c 2014-05-10 16:08:52 +0000
4@@ -730,3 +730,19 @@
5 }
6 }
7
8+void marlin_icon_info_remove_cache (const char *path, int size)
9+{
10+ GFile *icon_file;
11+ GIcon *icon;
12+ LoadableIconKey *lookup_key;
13+
14+ icon_file = g_file_new_for_path (path);
15+ icon = g_file_icon_new (icon_file);
16+ lookup_key = loadable_icon_key_new (icon, size);
17+
18+ g_hash_table_remove (loadable_icon_cache, lookup_key);
19+
20+ g_object_unref (icon_file);
21+ g_object_unref (icon);
22+ loadable_icon_key_free (lookup_key);
23+}
24
25=== modified file 'libcore/marlin-icon-info.h'
26--- libcore/marlin-icon-info.h 2013-08-10 20:20:23 +0000
27+++ libcore/marlin-icon-info.h 2014-05-10 16:08:52 +0000
28@@ -65,6 +65,7 @@
29
30 void marlin_icon_info_clear_caches (void);
31 void marlin_icon_info_infos_caches (void);
32+void marlin_icon_info_remove_cache (const char *path, int size);
33
34 G_END_DECLS
35
36
37=== modified file 'src/fm-directory-view.c'
38--- src/fm-directory-view.c 2014-04-18 00:56:20 +0000
39+++ src/fm-directory-view.c 2014-05-10 16:08:52 +0000
40@@ -213,6 +213,8 @@
41
42 void dir_action_set_sensitive (FMDirectoryView *view, const gchar *action_name, gboolean sensitive);
43
44+static void remove_marlin_icon_info_cache (GOFFile *file);
45+
46 G_DEFINE_TYPE (FMDirectoryView, fm_directory_view, GTK_TYPE_SCROLLED_WINDOW);
47 #define parent_class fm_directory_view_parent_class
48
49@@ -289,6 +291,8 @@
50 g_return_if_fail (file->exists);
51
52 g_debug ("%s %s %d\n", G_STRFUNC, file->uri, file->flags);
53+ //remove thumbnail cache so new thumbnail would be generated
54+ remove_marlin_icon_info_cache (file);
55 fm_list_model_file_changed (view->model, file, directory);
56 guint id;
57 marlin_thumbnailer_queue_file (view->details->thumbnailer, file, &id, /* large */ FALSE);
58@@ -298,6 +302,8 @@
59 file_deleted_callback (GOFDirectoryAsync *directory, GOFFile *file, FMDirectoryView *view)
60 {
61 g_debug ("%s %s", G_STRFUNC, file->uri);
62+ //remove thumbnail cache so new thumbnail would be generated
63+ remove_marlin_icon_info_cache (file);
64 fm_list_model_remove_file (view->model, file, directory);
65 /* Remove from gof-directory-async cache */
66 if (gof_file_is_folder (file)) {
67@@ -4031,4 +4037,20 @@
68 //view->details->templates_invalid = TRUE;
69
70 update_menus (view);
71-}
72\ No newline at end of file
73+}
74+
75+static void
76+remove_marlin_icon_info_cache (GOFFile *file)
77+{
78+ if (gof_file_get_thumbnail_path (file) != NULL){
79+ const char* path = gof_file_get_thumbnail_path (file);
80+ MarlinZoomLevel zoom_level;
81+ for (zoom_level = MARLIN_ZOOM_LEVEL_SMALLEST;
82+ zoom_level <= MARLIN_ZOOM_LEVEL_LARGEST;
83+ zoom_level++)
84+ {
85+ int icon_size = marlin_zoom_level_to_icon_size (zoom_level);
86+ marlin_icon_info_remove_cache (path, icon_size);
87+ }
88+ }
89+}

Subscribers

People subscribed via source and target branches

to all changes: