[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