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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to