[Bf-blender-cvs] [a339a92] staging-D1171-readfile_ghash: D1171: Use GHash for BHead idname lookups

Campbell Barton noreply at git.blender.org
Tue Mar 10 14:37:41 CET 2015


Commit: a339a92c49ce5b09f8b738c7c41841f6086eb2bb
Author: Campbell Barton
Date:   Wed Mar 11 00:33:44 2015 +1100
Branches: staging-D1171-readfile_ghash
https://developer.blender.org/rBa339a92c49ce5b09f8b738c7c41841f6086eb2bb

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)

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

M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/readfile.h

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

diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index cf8bbf0..779c993 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_BHEAD_GHASH
+
 /***/
 
 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!
@@ -508,6 +513,44 @@ static void read_file_version(FileData *fd, Main *main)
 	}
 }
 
+#ifdef USE_BHEAD_GHASH
+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)
 {
@@ -1133,6 +1176,12 @@ void blo_freefiledata(FileData *fd)
 		if (fd->bheadmap)
 			MEM_freeN(fd->bheadmap);
 		
+#ifdef USE_BHEAD_GHASH
+		if (fd->bhead_idname_hash) {
+			BLI_ghash_free(fd->bhead_idname_hash, NULL, NULL);
+		}
+#endif
+
 		MEM_freeN(fd);
 	}
 }
@@ -8036,6 +8085,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_BHEAD_GHASH
+
+	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)) {
@@ -8051,11 +8110,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_BHEAD_GHASH
+	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)
@@ -9290,6 +9354,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_BHEAD_GHASH
+	read_file_bhead_idname_map_create(*fd);
+#endif
 	
 	return mainl;
 }
@@ -9496,6 +9563,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
 						
 						/* subversion */
 						read_file_version(fd, mainptr);
+#ifdef USE_BHEAD_GHASH
+						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 281b5e5..4650847 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_BHEAD_GHASH */
+	struct GHash *bhead_idname_hash;
 	
 	ListBase *mainlist;




More information about the Bf-blender-cvs mailing list