readfile: avoid library lookups for every id on undo
authorCampbell Barton <ideasman42@gmail.com>
Mon, 6 Jun 2016 15:54:59 +0000 (01:54 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 7 Jun 2016 04:13:22 +0000 (14:13 +1000)
Instead index libraries, makes minor speedup when using many libraries.

source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_ID.h

index 96a9c4442d932dba8a51907ef01612383ef5ca0e..fd105f6aafaae350a793875cf2c05f240f199b0d 100644 (file)
@@ -485,53 +485,57 @@ void blo_join_main(ListBase *mainlist)
        }
 }
 
        }
 }
 
-static void split_libdata(ListBase *lb, Main *first)
+static void split_libdata(ListBase *lb_src, Main **lib_main_array, const unsigned int lib_main_array_len)
 {
 {
-       ListBase *lbn;
-       ID *id, *idnext;
-       Main *mainvar;
-       
-       id = lb->first;
-       while (id) {
+       for (ID *id = lb_src->first, *idnext; id; id = idnext) {
                idnext = id->next;
                idnext = id->next;
+
                if (id->lib) {
                if (id->lib) {
-                       mainvar = first;
-                       while (mainvar) {
-                               if (mainvar->curlib == id->lib) {
-                                       lbn= which_libbase(mainvar, GS(id->name));
-                                       BLI_remlink(lb, id);
-                                       BLI_addtail(lbn, id);
-                                       break;
-                               }
-                               mainvar = mainvar->next;
+                       if (((unsigned int)id->lib->temp_index < lib_main_array_len) &&
+                           /* this check should never fail, just incase 'id->lib' is a dangling pointer. */
+                           (lib_main_array[id->lib->temp_index]->curlib == id->lib))
+                       {
+                               Main *mainvar = lib_main_array[id->lib->temp_index];
+                               ListBase *lb_dst = which_libbase(mainvar, GS(id->name));
+                               BLI_remlink(lb_src, id);
+                               BLI_addtail(lb_dst, id);
+                       }
+                       else {
+                               printf("%s: invalid library for '%s'\n", __func__, id->name);
+                               BLI_assert(0);
                        }
                        }
-                       if (mainvar == NULL) printf("error split_libdata\n");
                }
                }
-               id = idnext;
        }
 }
 
 void blo_split_main(ListBase *mainlist, Main *main)
 {
        }
 }
 
 void blo_split_main(ListBase *mainlist, Main *main)
 {
-       ListBase *lbarray[MAX_LIBARRAY];
-       Library *lib;
-       int i;
-       
        mainlist->first = mainlist->last = main;
        main->next = NULL;
        
        if (BLI_listbase_is_empty(&main->library))
                return;
        
        mainlist->first = mainlist->last = main;
        main->next = NULL;
        
        if (BLI_listbase_is_empty(&main->library))
                return;
        
-       for (lib = main->library.first; lib; lib = lib->id.next) {
+       /* (Library.temp_index -> Main), lookup table */
+       const unsigned int lib_main_array_len = BLI_listbase_count(&main->library);
+       Main             **lib_main_array     = MEM_mallocN(lib_main_array_len * sizeof(*lib_main_array), __func__);
+
+       int i = 0;
+       for (Library *lib = main->library.first; lib; lib = lib->id.next, i++) {
                Main *libmain = BKE_main_new();
                libmain->curlib = lib;
                BLI_addtail(mainlist, libmain);
                Main *libmain = BKE_main_new();
                libmain->curlib = lib;
                BLI_addtail(mainlist, libmain);
+               lib->temp_index = i;
+               lib_main_array[i] = libmain;
        }
        
        }
        
+       ListBase *lbarray[MAX_LIBARRAY];
        i = set_listbasepointers(main, lbarray);
        i = set_listbasepointers(main, lbarray);
-       while (i--)
-               split_libdata(lbarray[i], main->next);
+       while (i--) {
+               split_libdata(lbarray[i], lib_main_array, lib_main_array_len);
+       }
+
+       MEM_freeN(lib_main_array);
 }
 
 static void read_file_version(FileData *fd, Main *main)
 }
 
 static void read_file_version(FileData *fd, Main *main)
index d3d7d075229bc89855e0265376377dd8d9484e05..b0812a81ee14a08acf1d7e63ebcf87c2f8e1df61 100644 (file)
@@ -154,6 +154,9 @@ typedef struct Library {
        struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */
        
        struct PackedFile *packedfile;
        struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */
        
        struct PackedFile *packedfile;
+
+       int temp_index;
+       int _pad;
 } Library;
 
 enum eIconSizes {
 } Library;
 
 enum eIconSizes {