[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