Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2015-03-10 16:33:44 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-03-12 17:55:49 +0300
commita8f6d51ebce6e94bd953492f01600d51871f2757 (patch)
tree3cece2f22c4cee23c04e42e9fc4447ce81a22fda /source
parentf2d4f6b086506c491b0f2efbacfcd0ef8c9b72ce (diff)
D1171: Use GHash for BHead idname lookups
This patch avoids looping over bhead's linked list when looking up values by name. Used during appaned and library loading. Gives noticeable overall speedup loading files that used libraries. (nearly 2x on some Mango files)
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenloader/intern/readfile.c71
-rw-r--r--source/blender/blenloader/intern/readfile.h3
2 files changed, 74 insertions, 0 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 36a8309db4d..6b4d45a85dc 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -206,6 +206,9 @@
* - initialize FileGlobal and copy pointers to Global
*/
+/* use GHash for BHead name-based lookups (speeds up linking) */
+#define USE_GHASH_BHEAD
+
/***/
typedef struct OldNew {
@@ -225,6 +228,8 @@ typedef struct OldNewMap {
static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static void direct_link_modifiers(FileData *fd, ListBase *lb);
static void convert_tface_mt(FileData *fd, Main *main);
+static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
+static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
/* this function ensures that reports are printed,
* in the case of libraray linking errors this is important!
@@ -502,6 +507,44 @@ static void read_file_version(FileData *fd, Main *main)
}
}
+#ifdef USE_GHASH_BHEAD
+static void read_file_bhead_idname_map_create(FileData *fd)
+{
+ BHead *bhead;
+
+ /* dummy values */
+ bool is_link = false;
+ int code_prev = ENDB;
+ unsigned int reserve = 0;
+
+ for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
+ if (code_prev != bhead->code) {
+ code_prev = bhead->code;
+ is_link = BKE_idcode_is_valid(code_prev) ? BKE_idcode_is_linkable(code_prev) : false;
+ }
+
+ if (is_link) {
+ reserve += 1;
+ }
+ }
+
+ BLI_assert(fd->bhead_idname_hash == NULL);
+
+ fd->bhead_idname_hash = BLI_ghash_str_new_ex(__func__, reserve);
+
+ for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
+ if (code_prev != bhead->code) {
+ code_prev = bhead->code;
+ is_link = BKE_idcode_is_valid(code_prev) ? BKE_idcode_is_linkable(code_prev) : false;
+ }
+
+ if (is_link) {
+ BLI_ghash_insert(fd->bhead_idname_hash, (void *)bhead_id_name(fd, bhead), bhead);
+ }
+ }
+}
+#endif
+
static Main *blo_find_main(FileData *fd, const char *filepath, const char *relabase)
{
@@ -1127,6 +1170,12 @@ void blo_freefiledata(FileData *fd)
if (fd->bheadmap)
MEM_freeN(fd->bheadmap);
+#ifdef USE_GHASH_BHEAD
+ if (fd->bhead_idname_hash) {
+ BLI_ghash_free(fd->bhead_idname_hash, NULL, NULL);
+ }
+#endif
+
MEM_freeN(fd);
}
}
@@ -8031,6 +8080,16 @@ static BHead *find_bhead(FileData *fd, void *old)
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name)
{
+#ifdef USE_GHASH_BHEAD
+
+ char idname_full[MAX_ID_NAME];
+
+ *((short *)idname_full) = idcode;
+ BLI_strncpy(idname_full + 2, name, sizeof(idname_full) - 2);
+
+ return BLI_ghash_lookup(fd->bhead_idname_hash, idname_full);
+
+#else
BHead *bhead;
for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
@@ -8046,11 +8105,16 @@ static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const
}
return NULL;
+#endif
}
static BHead *find_bhead_from_idname(FileData *fd, const char *idname)
{
+#ifdef USE_GHASH_BHEAD
+ return BLI_ghash_lookup(fd->bhead_idname_hash, idname);
+#else
return find_bhead_from_code_name(fd, GS(idname), idname + 2);
+#endif
}
const char *bhead_id_name(const FileData *fd, const BHead *bhead)
@@ -9285,6 +9349,9 @@ static Main *library_append_begin(Main *mainvar, FileData **fd, const char *file
/* needed for do_version */
mainl->versionfile = (*fd)->fileversion;
read_file_version(*fd, mainl);
+#ifdef USE_GHASH_BHEAD
+ read_file_bhead_idname_map_create(*fd);
+#endif
return mainl;
}
@@ -9491,6 +9558,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
/* subversion */
read_file_version(fd, mainptr);
+#ifdef USE_GHASH_BHEAD
+ read_file_bhead_idname_map_create(fd);
+#endif
+
}
else {
mainptr->curlib->filedata = NULL;
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index 281b5e56acf..51a68926455 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -93,6 +93,9 @@ typedef struct FileData {
struct BHeadSort *bheadmap;
int tot_bheadmap;
+
+ /* see: USE_GHASH_BHEAD */
+ struct GHash *bhead_idname_hash;
ListBase *mainlist;