[Bf-blender-cvs] [726e6972160] id-ensure-unique-memory-address: Rework the whole unique ID system to also store ID addresses history in Main's mapping.
Bastien Montagne
noreply at git.blender.org
Fri Feb 21 15:50:53 CET 2020
Commit: 726e6972160159cc9d5b2be9cfb618f7362acc81
Author: Bastien Montagne
Date: Fri Feb 21 15:49:21 2020 +0100
Branches: id-ensure-unique-memory-address
https://developer.blender.org/rB726e6972160159cc9d5b2be9cfb618f7362acc81
Rework the whole unique ID system to also store ID addresses history in Main's mapping.
In the end, since this is a runtime/editing session data only, makes
more sense to store it here than in ID struct itself. And it's probably
also more efficient to handle.
===================================================================
M source/blender/blenkernel/BKE_main.h
M source/blender/blenkernel/intern/blender.c
M source/blender/blenkernel/intern/lib_id.c
M source/blender/blenkernel/intern/main.c
M source/blender/blenloader/intern/readfile.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 702dcb68c5c..dec142624f2 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -100,8 +100,9 @@ typedef struct Main {
*/
char is_memfile_undo_flush_needed;
- struct GSet *used_id_memset;
- short used_id_memset_tag;
+ struct GHash *used_id_memhash;
+ struct LinkNode *used_id_memhash_history_chains;
+ short used_id_memhash_tag;
BlendThumbnail *blen_thumb;
@@ -155,7 +156,7 @@ typedef struct Main {
/* Main.used_id_memory_pointers_tag */
enum {
- MAIN_IDMEMSET_OWNER = 1 << 0,
+ MAIN_IDMEMHASH_OWNER = 1 << 0,
};
struct Main *BKE_main_new(void);
@@ -164,22 +165,24 @@ void BKE_main_free(struct Main *mainvar);
void BKE_main_lock(struct Main *bmain);
void BKE_main_unlock(struct Main *bmain);
-void BKE_main_idmemset_ensure(struct Main *bmain);
-void BKE_main_idmemset_release(struct Main *bmain);
-void BKE_main_idmemset_transfer_ownership(struct Main *bmain_dst, struct Main *bmain_src);
-void BKE_main_idmemset_usefrom(struct Main *bmain_user, struct Main *bmain_src);
-bool BKE_main_idmemset_register_id(struct Main *bmain, struct ID *id);
-void *BKE_main_idmemset_unique_alloc(struct Main *bmain,
- void *(*alloc_cb)(size_t len, const char *str),
- size_t size,
- const char *message);
-void *BKE_main_idmemset_unique_realloc(struct Main *bmain,
- void *vmemh,
- void *(*realloc_cb)(void *vmemh,
- size_t len,
- const char *str),
- size_t size,
- const char *message);
+void BKE_main_idmemhash_ensure(struct Main *bmain);
+void BKE_main_idmemhash_release(struct Main *bmain);
+void BKE_main_idmemhash_transfer_ownership(struct Main *bmain_dst, struct Main *bmain_src);
+void BKE_main_idmemhash_usefrom(struct Main *bmain_user, struct Main *bmain_src);
+bool BKE_main_idmemhash_register_id(struct Main *bmain, void *old_vmemh, struct ID *id);
+void *BKE_main_idmemhash_unique_alloc(struct Main *bmain,
+ void *old_vmemh,
+ void *(*alloc_cb)(size_t len, const char *str),
+ size_t size,
+ const char *message);
+void *BKE_main_idmemhash_unique_realloc(struct Main *bmain,
+ void *old_vmemh,
+ void *vmemh,
+ void *(*realloc_cb)(void *vmemh,
+ size_t len,
+ const char *str),
+ size_t size,
+ const char *message);
void BKE_main_relations_create(struct Main *bmain, const short flag);
void BKE_main_relations_free(struct Main *bmain);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 7a145f41c32..a828ede92bb 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -127,7 +127,7 @@ void BKE_blender_globals_init(void)
U.savetime = 1;
G_MAIN = BKE_main_new();
- BKE_main_idmemset_ensure(G_MAIN);
+ BKE_main_idmemhash_ensure(G_MAIN);
strcpy(G.ima, "//");
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 8fbb54e3cda..6ce89994235 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -1198,7 +1198,7 @@ void *BKE_libblock_alloc_notest(Main *bmain, short type)
const char *name;
size_t size = BKE_libblock_get_alloc_info(type, &name);
if (size != 0) {
- return BKE_main_idmemset_unique_alloc(bmain, MEM_callocN, size, name);
+ return BKE_main_idmemhash_unique_alloc(bmain, NULL, MEM_callocN, size, name);
}
BLI_assert(!"Request to allocate unknown data type");
return NULL;
diff --git a/source/blender/blenkernel/intern/main.c b/source/blender/blenkernel/intern/main.c
index bf7d7fc00ab..78b45a58dca 100644
--- a/source/blender/blenkernel/intern/main.c
+++ b/source/blender/blenkernel/intern/main.c
@@ -29,6 +29,7 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
+#include "BLI_linklist.h"
#include "BLI_mempool.h"
#include "BLI_threads.h"
@@ -194,7 +195,7 @@ void BKE_main_free(Main *mainvar)
BKE_main_relations_free(mainvar);
}
- BKE_main_idmemset_release(mainvar);
+ BKE_main_idmemhash_release(mainvar);
BLI_spin_end((SpinLock *)mainvar->lock);
MEM_freeN(mainvar->lock);
@@ -211,64 +212,100 @@ void BKE_main_unlock(struct Main *bmain)
BLI_spin_unlock((SpinLock *)bmain->lock);
}
-void BKE_main_idmemset_ensure(Main *bmain)
+void BKE_main_idmemhash_ensure(Main *bmain)
{
- if (bmain->used_id_memset == NULL || (bmain->used_id_memset_tag & MAIN_IDMEMSET_OWNER) == 0) {
- bmain->used_id_memset = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
- bmain->used_id_memset_tag |= MAIN_IDMEMSET_OWNER;
+ if (bmain->used_id_memhash == NULL || (bmain->used_id_memhash_tag & MAIN_IDMEMHASH_OWNER) == 0) {
+ bmain->used_id_memhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
+ bmain->used_id_memhash_history_chains = NULL;
+ bmain->used_id_memhash_tag |= MAIN_IDMEMHASH_OWNER;
}
}
-void BKE_main_idmemset_release(Main *bmain)
+void main_idmemhash_history_chains_free(void *linkv)
{
- if (bmain->used_id_memset != NULL) {
- if ((bmain->used_id_memset_tag & MAIN_IDMEMSET_OWNER) != 0) {
- BLI_gset_free(bmain->used_id_memset, NULL);
+ LinkNode *link = linkv;
+ BLI_linklist_free(link, NULL);
+}
+
+void BKE_main_idmemhash_release(Main *bmain)
+{
+ if (bmain->used_id_memhash != NULL) {
+ if ((bmain->used_id_memhash_tag & MAIN_IDMEMHASH_OWNER) != 0) {
+ BLI_ghash_free(bmain->used_id_memhash, NULL, NULL);
+ BLI_linklist_free(bmain->used_id_memhash_history_chains, main_idmemhash_history_chains_free);
}
- bmain->used_id_memset = NULL;
- bmain->used_id_memset_tag &= ~MAIN_IDMEMSET_OWNER;
+ bmain->used_id_memhash = NULL;
+ bmain->used_id_memhash_history_chains = NULL;
+ bmain->used_id_memhash_tag &= ~MAIN_IDMEMHASH_OWNER;
}
}
-void BKE_main_idmemset_transfer_ownership(Main *bmain_dst, Main *bmain_src)
+void BKE_main_idmemhash_transfer_ownership(Main *bmain_dst, Main *bmain_src)
{
- BKE_main_idmemset_release(bmain_dst);
+ BKE_main_idmemhash_release(bmain_dst);
- BLI_assert(bmain_src->used_id_memset != NULL);
- BLI_assert(bmain_src->used_id_memset_tag & MAIN_IDMEMSET_OWNER);
+ BLI_assert(bmain_src->used_id_memhash != NULL);
+ BLI_assert(bmain_src->used_id_memhash_tag & MAIN_IDMEMHASH_OWNER);
- bmain_dst->used_id_memset = bmain_src->used_id_memset;
- bmain_dst->used_id_memset_tag |= MAIN_IDMEMSET_OWNER;
- bmain_src->used_id_memset_tag &= ~MAIN_IDMEMSET_OWNER;
+ bmain_dst->used_id_memhash = bmain_src->used_id_memhash;
+ bmain_dst->used_id_memhash_history_chains = bmain_src->used_id_memhash_history_chains;
+ bmain_dst->used_id_memhash_tag |= MAIN_IDMEMHASH_OWNER;
+ bmain_src->used_id_memhash_tag &= ~MAIN_IDMEMHASH_OWNER;
}
-void BKE_main_idmemset_usefrom(Main *bmain_user, Main *bmain_src)
+void BKE_main_idmemhash_usefrom(Main *bmain_user, Main *bmain_src)
{
- BKE_main_idmemset_release(bmain_user);
+ BKE_main_idmemhash_release(bmain_user);
- BLI_assert(bmain_src->used_id_memset != NULL);
- bmain_user->used_id_memset = bmain_src->used_id_memset;
+ BLI_assert(bmain_src->used_id_memhash != NULL);
+ bmain_user->used_id_memhash = bmain_src->used_id_memhash;
+ bmain_user->used_id_memhash_history_chains = bmain_src->used_id_memhash_history_chains;
}
/**
* @return true if the ID was successfully added to the memset, false if it already existed.
*/
-bool BKE_main_idmemset_register_id(Main *bmain, ID *id)
+bool BKE_main_idmemhash_register_id(Main *bmain, void *old_vmemh, ID *id)
{
- BLI_assert(bmain->used_id_memset != NULL);
- return BLI_gset_add(bmain->used_id_memset, id);
+ BLI_assert(bmain->used_id_memhash != NULL);
+ void **val;
+ if (!BLI_ghash_ensure_p(bmain->used_id_memhash, id, &val)) {
+ if (old_vmemh != NULL) {
+ BLI_assert(BLI_ghash_haskey(bmain->used_id_memhash, old_vmemh));
+ LinkNode **chain_hook = (LinkNode **)BLI_ghash_lookup_p(bmain->used_id_memhash, old_vmemh);
+ if (*chain_hook == NULL) {
+ /* That datablock only ever had one address so far, we need to initialize its addresses
+ * history chain. */
+ *chain_hook = MEM_callocN(sizeof(**chain_hook), __func__);
+ LinkNode *old_id_entry = MEM_mallocN(sizeof(*old_id_entry), __func__);
+ old_id_entry->link = old_vmemh;
+ old_id_entry->next = NULL;
+ BLI_linklist_prepend_nlink(
+ &bmain->used_id_memhash_history_chains, old_id_entry, *chain_hook);
+ }
+ LinkNode *curr_id_entry = MEM_mallocN(sizeof(*curr_id_entry), __func__);
+ BLI_linklist_prepend_nlink((LinkNode **)&(*chain_hook)->link, id, curr_id_entry);
+ *val = *chain_hook;
+ }
+ else {
+ *val = NULL;
+ }
+ return true;
+ }
+ return false;
}
-void *BKE_main_idmemset_unique_alloc(Main *bmain,
- void *(*alloc_cb)(size_t len, const char *str),
- size_t size,
- const char *message)
+void *BKE_main_idmemhash_unique_alloc(Main *bmain,
+ void *old_vmemh,
+ void *(*alloc_cb)(size_t len, const char *str),
+ size_t size,
+ const char *message)
{
void *id_mem = alloc_cb(size, message);
- if (bmain != NULL && bmain->used_id_memset != NULL) {
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list