[Bf-blender-cvs] [c539aaf] asset-experiments: FileBrowser: internal listing: use own, much lighter struct to store whole list.

Bastien Montagne noreply at git.blender.org
Mon Apr 6 19:57:32 CEST 2015


Commit: c539aaf19dd169c3fa8463d49897d4def84f39e2
Author: Bastien Montagne
Date:   Mon Apr 6 16:56:48 2015 +0200
Branches: asset-experiments
https://developer.blender.org/rBc539aaf19dd169c3fa8463d49897d4def84f39e2

FileBrowser: internal listing: use own, much lighter struct to store whole list.

Since with internal listing we have no choice but to list everything, store
those data in the smallest possible struct - note we do not even store preview
here, these are only handled in full FileDirEntry cache (re-loading them from
cached thumbnails is really quick anyway).

Still not complete, have to re-do ID previews now, among other things...
And some memleaks again with previews, ugh.

===================================================================

M	intern/guardedalloc/intern/mallocn_guarded_impl.c
M	source/blender/editors/space_file/filelist.c

===================================================================

diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index bdcace2..78a5661 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -76,7 +76,7 @@
  * memory block was allocated and print this trace for all
  * unfreed blocks.
  */
-//#define DEBUG_BACKTRACE
+#define DEBUG_BACKTRACE
 
 #ifdef DEBUG_BACKTRACE
 #  define BACKTRACE_SIZE 100
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 0410e3d..6e2af4a 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -35,6 +35,8 @@
 #include <stdlib.h>
 #include <math.h>
 #include <string.h>
+#include <sys/stat.h>
+#include <time.h>
 
 #ifndef WIN32
 #  include <unistd.h>
@@ -203,10 +205,26 @@ ListBase *folderlist_duplicate(ListBase *folderlist)
 
 /* ------------------FILELIST------------------------ */
 
+typedef struct FileListInternEntry {
+	struct FileListInternEntry *next, *prev;
+
+	char uuid[16];  /* ASSET_UUID_LENGTH */
+
+	int typeflag;  /* eFileSel_File_Types */
+	int blentype;  /* ID type, in case typeflag has FILE_TYPE_BLENDERLIB set. */
+
+	char *relpath;
+	char *name;  /* not striclty needed, but used during sorting, avoids to have to recompute it there... */
+
+	struct stat st;
+} FileListInternEntry;
+
 typedef struct FileListIntern {
 	/* XXX This will be reworked to keep 'all entries' storage to a minimum memory space! */
-	ListBase entries;
-	FileDirEntry **filtered;
+	ListBase entries;  /* FileListInternEntry items. */
+	FileListInternEntry **filtered;
+
+	ListBase tmp_entries;  /* FileDirEntry items. */
 } FileListIntern;
 
 #define FILELIST_ENTRYCACHESIZE 1024  /* Keep it a power of two! */
@@ -279,7 +297,7 @@ typedef struct FileList {
 	void (*read_jobf)(struct FileList *, const char *, short *, short *, float *, ThreadMutex *);
 
 	/* Filter an entry of current filelist. */
-	bool (*filterf)(struct FileDirEntry *, const char *, FileListFilter *);
+	bool (*filterf)(struct FileListInternEntry *, const char *, FileListFilter *);
 } FileList;
 
 #define SPECIAL_IMG_SIZE 48
@@ -318,7 +336,7 @@ static void filelist_cache_clear(FileListEntryCache *cache);
 
 /* ********** Sort helpers ********** */
 
-static int compare_direntry_generic(const FileDirEntry *entry1, const FileDirEntry *entry2)
+static int compare_direntry_generic(const FileListInternEntry *entry1, const FileListInternEntry *entry2)
 {
 	/* type is equal to stat.st_mode */
 
@@ -351,20 +369,6 @@ static int compare_direntry_generic(const FileDirEntry *entry1, const FileDirEnt
 	    return 1;
 	}
 
-	/* We get rid of this, this is OS-specific description of file types, not really useful at our level! */
-#if 0
-	if (S_ISREG(entry1->entry->type)) {
-		if (!S_ISREG(entry2->entry->type)) {
-			return -1;
-		}
-	}
-	else if (S_ISREG(entry2->entry->type)) {
-		return 1;
-	}
-	if ((entry1->entry->type & S_IFMT) < (entry2->entry->type & S_IFMT)) return -1;
-	if ((entry1->entry->type & S_IFMT) > (entry2->entry->type & S_IFMT)) return 1;
-#endif
-
 	/* make sure "." and ".." are always first */
 	if (FILENAME_IS_CURRENT(entry1->relpath)) return -1;
 	if (FILENAME_IS_CURRENT(entry2->relpath)) return 1;
@@ -376,8 +380,8 @@ static int compare_direntry_generic(const FileDirEntry *entry1, const FileDirEnt
 
 static int compare_name(void *UNUSED(user_data), const void *a1, const void *a2)
 {
-	const FileDirEntry *entry1 = a1;
-	const FileDirEntry *entry2 = a2;
+	const FileListInternEntry *entry1 = a1;
+	const FileListInternEntry *entry2 = a2;
 	char *name1, *name2;
 	int ret;
 
@@ -393,17 +397,20 @@ static int compare_name(void *UNUSED(user_data), const void *a1, const void *a2)
 
 static int compare_date(void *UNUSED(user_data), const void *a1, const void *a2)
 {
-	const FileDirEntry *entry1 = a1;
-	const FileDirEntry *entry2 = a2;
+	const FileListInternEntry *entry1 = a1;
+	const FileListInternEntry *entry2 = a2;
 	char *name1, *name2;
+	int64_t time1, time2;
 	int ret;
 
 	if ((ret = compare_direntry_generic(entry1, entry2))) {
 		return ret;
 	}
 	
-	if (entry1->entry->time < entry2->entry->time) return 1;
-	if (entry1->entry->time > entry2->entry->time) return -1;
+	time1 = (int64_t)entry1->st.st_mtime;
+	time2 = (int64_t)entry2->st.st_mtime;
+	if (time1 < time2) return 1;
+	if (time1 > time2) return -1;
 
 	name1 = entry1->name;
 	name2 = entry2->name;
@@ -413,17 +420,20 @@ static int compare_date(void *UNUSED(user_data), const void *a1, const void *a2)
 
 static int compare_size(void *UNUSED(user_data), const void *a1, const void *a2)
 {
-	const FileDirEntry *entry1 = a1;
-	const FileDirEntry *entry2 = a2;
+	const FileListInternEntry *entry1 = a1;
+	const FileListInternEntry *entry2 = a2;
 	char *name1, *name2;
+	uint64_t size1, size2;
 	int ret;
 
 	if ((ret = compare_direntry_generic(entry1, entry2))) {
 		return ret;
 	}
 	
-	if (entry1->entry->size < entry2->entry->size) return 1;
-	if (entry1->entry->size > entry2->entry->size) return -1;
+	size1 = entry1->st.st_size;
+	size2 = entry2->st.st_size;
+	if (size1 < size2) return 1;
+	if (size1 > size2) return -1;
 
 	name1 = entry1->name;
 	name2 = entry2->name;
@@ -433,8 +443,8 @@ static int compare_size(void *UNUSED(user_data), const void *a1, const void *a2)
 
 static int compare_extension(void *UNUSED(user_data), const void *a1, const void *a2)
 {
-	const FileDirEntry *entry1 = a1;
-	const FileDirEntry *entry2 = a2;
+	const FileListInternEntry *entry1 = a1;
+	const FileListInternEntry *entry2 = a2;
 	char *name1, *name2;
 	int ret;
 
@@ -556,7 +566,7 @@ static bool is_hidden_file(const char *filename, FileListFilter *filter)
 	return is_hidden;
 }
 
-static bool is_filtered_file(FileDirEntry *file, const char *UNUSED(root), FileListFilter *filter)
+static bool is_filtered_file(FileListInternEntry *file, const char *UNUSED(root), FileListFilter *filter)
 {
 	bool is_filtered = !is_hidden_file(file->relpath, filter);
 
@@ -588,7 +598,7 @@ static bool is_filtered_file(FileDirEntry *file, const char *UNUSED(root), FileL
 	return is_filtered;
 }
 
-static bool is_filtered_lib(FileDirEntry *file, const char *root, FileListFilter *filter)
+static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileListFilter *filter)
 {
 	bool is_filtered;
 	char path[FILE_MAX_LIBEXTRA], dir[FILE_MAXDIR], *group, *name;
@@ -635,7 +645,7 @@ static bool is_filtered_lib(FileDirEntry *file, const char *root, FileListFilter
 	return is_filtered;
 }
 
-static bool is_filtered_main(FileDirEntry *file, const char *UNUSED(dir), FileListFilter *filter)
+static bool is_filtered_main(FileListInternEntry *file, const char *UNUSED(dir), FileListFilter *filter)
 {
 	return !is_hidden_file(file->relpath, filter);
 }
@@ -649,7 +659,7 @@ void filelist_filter(FileList *filelist)
 {
 	int num_filtered = 0;
 	const int num_files = filelist->filelist.nbr_entries;
-	FileDirEntry **filtered_tmp, *file;
+	FileListInternEntry **filtered_tmp, *file;
 
 	if (filelist->filelist.nbr_entries == 0) {
 		return;
@@ -970,7 +980,14 @@ static void filelist_checkdir_main(struct FileList *filelist, char *r_dir)
 	filelist_checkdir_lib(filelist, r_dir);
 }
 
-static void filelist_entry_free(FileDirEntry *entry)
+static void filelist_entry_revision_clear(FileDirEntryRevision *rev)
+{
+	if (rev->comment) {
+		MEM_freeN(rev->comment);
+	}
+}
+
+static void filelist_entry_clear(FileDirEntry *entry)
 {
 	if (entry->name) {
 		MEM_freeN(entry->name);
@@ -1001,9 +1018,7 @@ static void filelist_entry_free(FileDirEntry *entry)
 				FileDirEntryRevision *rev;
 
 				for (rev = var->revisions.first; rev; rev = rev->next) {
-					if (rev->comment) {
-						MEM_freeN(rev->comment);
-					}
+					filelist_entry_revision_clear(rev);
 				}
 
 				BLI_freelistN(&var->revisions);
@@ -1019,13 +1034,11 @@ static void filelist_entry_free(FileDirEntry *entry)
 	}
 }
 
-#if 0  /* UNUSED */
-static void filelist_entry_clear(FileDirEntry *entry)
+static void filelist_entry_free(FileDirEntry *entry)
 {
-	filelist_entry_free(entry);
-	memset(entry, 0, sizeof(*entry));
+	filelist_entry_clear(entry);
+	MEM_freeN(entry);
 }
-#endif
 
 static void filelist_direntryarr_free(FileDirEntryArr *array)
 {
@@ -1034,34 +1047,78 @@ static void filelist_direntryarr_free(FileDirEntryArr *array)
 	for (entry = array->entries.first; entry; entry = entry->next) {
 		filelist_entry_free(entry);
 	}
-	BLI_freelistN(&array->entries);
+	BLI_listbase_clear(&array->entries);
 	array->nbr_entries = 0;
 	array->nbr_entries_filtered = -1;
 	array->entry_idx_start = -1;
 	array->entry_idx_end = -1;
 }
 
+static void filelist_intern_entry_free(FileListInternEntry *entry)
+{
+	if (entry->relpath) {
+		MEM_freeN(entry->relpath);
+	}
+	if (entry->name) {
+		MEM_freeN(entry->name);
+	}
+	MEM_freeN(entry);
+}
+
 static void filelist_intern_free(FileListIntern *filelist_intern)
 {
-	FileDirEntry *entry;
+	FileListInternEntry *entry, *entry_next;
+	FileDirEntry *tmp_entry, *tmp_entry_next;
 
-	for (entry = filelist_intern->entries.first; entry; entry = entry->next) {
-		filelist_entry_free(entry);
+	for (entry = filelist_intern->entries.first; entry; entry = entry_next) {
+		entry_next = entry->next;
+		filelist_intern_entry_free(entry);
 	}
-	BLI_freelistN(&filelist_intern->entries);
+	BLI_listbase_clear(&filelist_intern->entries);
 
 	MEM_SAFE_FREE(filelist_intern->filtered);
+
+	for (tmp_entry = filelist_intern->tmp_entries.first; tmp_entry; tmp_entry = tmp_entry_next) {
+		tmp_entry_next = tmp_entry->next;
+		filelist_entry_free(tmp_entry);
+	}
+	BLI_listbase_clear(&filelist_intern->tmp_entries);
 }
 
 static FileDirEntry *filelist_intern_create_entry(FileList *filelist, const int index)
 {
-	/* Stupid code for now, later we will actually generate a new entry (from mempool)... */
-	return filelist->filelist_intern.filtered[index];
+	FileListInternEntry *entry = filelist->filelist_intern.filtered[index];
+	FileListIntern *intern = &filelist->filelist_intern;
+	FileDirEntry *ret;
+	FileDirEntryRevision *rev;
+
+	ret = MEM_callocN(sizeof(*ret), __func__);
+	rev = MEM_callocN(sizeof(*rev), __func__);
+
+	rev->size = (uint64_t)entry->st.st_si

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list