optimized get_mark_func
authorVladimir Nadvornik <nadvornik@suse.cz>
Fri, 26 Dec 2008 19:04:36 +0000 (19:04 +0000)
committerVladimir Nadvornik <nadvornik@suse.cz>
Fri, 26 Dec 2008 19:04:36 +0000 (19:04 +0000)
fixed reference counting bug

src/filedata.c
src/typedefs.h

index 401499f..3618509 100644 (file)
@@ -142,7 +142,12 @@ FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd);
 void file_data_increment_version(FileData *fd)
 {
        fd->version++;
-       if (fd->parent) fd->parent->version++;
+       fd->valid_marks = 0;
+       if (fd->parent) 
+               {
+               fd->parent->version++;
+               fd->parent->valid_marks = 0;
+               }
 }
 
 static void file_data_set_collate_keys(FileData *fd)
@@ -1094,10 +1099,24 @@ static gpointer file_data_mark_func_data[FILEDATA_MARKS_SIZE];
 
 gboolean file_data_get_mark(FileData *fd, gint n)
 {
-       if (file_data_get_mark_func[n]) 
+       gboolean valid = (fd->valid_marks & (1 << n));
+       if (file_data_get_mark_func[n] && !valid) 
                {
+               guint old = fd->marks;
                gboolean value = (file_data_get_mark_func[n])(fd, n, file_data_mark_func_data[n]);
-               if (!value != !(fd->marks & (1 << n))) fd->marks = fd->marks ^ (1 << n);
+               if (!value != !(fd->marks & (1 << n))) 
+                       {
+                       fd->marks = fd->marks ^ (1 << n);
+                       }
+               fd->valid_marks |= (1 << n);
+               if (old && !fd->marks) /* keep files with non-zero marks in memory */
+                       {
+                       file_data_unref(fd);
+                       }
+               else if (!old && fd->marks)
+                       {
+                       file_data_ref(fd);
+                       }
                }
 
        return !!(fd->marks & (1 << n));
@@ -1112,13 +1131,15 @@ guint file_data_get_marks(FileData *fd)
 
 void file_data_set_mark(FileData *fd, gint n, gboolean value)
 {
-       guint old = fd->marks;
-       if (!value == !(fd->marks & (1 << n))) return;
-
+       guint old;
+       if (!value == !file_data_get_mark(fd, n)) return;
+       
        if (file_data_set_mark_func[n]) 
                {
                (file_data_set_mark_func[n])(fd, n, value, file_data_mark_func_data[n]);
                }
+       
+       old = fd->marks;
 
        fd->marks = fd->marks ^ (1 << n);
        
index 8de91e3..660ab1c 100644 (file)
@@ -424,7 +424,11 @@ struct _FileData {
        gint64 size;
        time_t date;
        mode_t mode; /* this is needed at least for notification in view_dir because it is preserved after the file/directory is deleted */
-       guint marks;
+       
+       guint marks; /* each bit represents one mark */
+       guint valid_marks; /* zero bit means that the corresponding mark needs to be reread */
+
+
        GList *sidecar_files;
        FileData *parent; /* parent file if this is a sidecar file, NULL otherwise */
        FileDataChangeInfo *change; /* for rename, move ... */