changeset 1227:2df7be0cd20b

optimized get_mark_func fixed reference counting bug
author nadvornik
date Fri, 26 Dec 2008 19:04:36 +0000
parents 9dae588b8d5e
children 4d5587c4bf56
files src/filedata.c src/typedefs.h
diffstat 2 files changed, 32 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/filedata.c	Fri Dec 26 18:54:07 2008 +0000
+++ b/src/filedata.c	Fri Dec 26 19:04:36 2008 +0000
@@ -142,7 +142,12 @@
 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 @@
 
 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 @@
 
 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);
 	
--- a/src/typedefs.h	Fri Dec 26 18:54:07 2008 +0000
+++ b/src/typedefs.h	Fri Dec 26 19:04:36 2008 +0000
@@ -424,7 +424,11 @@
 	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 ... */