From 57613630c7faa41aa20ae96cbaa577bd2ce178ae Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 29 Nov 2022 16:24:45 +0100 Subject: [PATCH] BLO: use blender::Map in OldNewMap `OldNewMap` used to have its own map implementation. Given that the file uses C++ now, it is easy to use a C++ map implementation instead. This simplifies the code a lot. Going forward it might make sense to remove the `OldNewMap` abstraction or to split it up in two (currently, `NewAddress.nr` has two different meanings in different contexts which is confusing). No functional changes are expected. Differential Revision: https://developer.blender.org/D16546 --- source/blender/blenloader/intern/readfile.cc | 164 +++---------------- 1 file changed, 19 insertions(+), 145 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 8bcfe27a388..d5ba6730369 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -51,6 +51,7 @@ #include "BLI_endian_switch.h" #include "BLI_ghash.h" #include "BLI_linklist.h" +#include "BLI_map.hh" #include "BLI_math.h" #include "BLI_memarena.h" #include "BLI_mempool.h" @@ -229,119 +230,19 @@ static const char *library_parent_filepath(Library *lib) /** \name OldNewMap API * \{ */ -struct OldNew { - const void *oldp; +struct NewAddress { void *newp; /* `nr` is "user count" for data, and ID code for libdata. */ int nr; }; struct OldNewMap { - /* Array that stores the actual entries. */ - OldNew *entries; - int nentries; - /* Hash-map that stores indices into the `entries` array. */ - int32_t *map; - - int capacity_exp; + blender::Map map; }; -#define ENTRIES_CAPACITY(onm) (1ll << (onm)->capacity_exp) -#define MAP_CAPACITY(onm) (1ll << ((onm)->capacity_exp + 1)) -#define SLOT_MASK(onm) (MAP_CAPACITY(onm) - 1) -#define DEFAULT_SIZE_EXP 6 -#define PERTURB_SHIFT 5 - -/* based on the probing algorithm used in Python dicts. */ -#define ITER_SLOTS(onm, KEY, SLOT_NAME, INDEX_NAME) \ - uint32_t hash = BLI_ghashutil_ptrhash(KEY); \ - uint32_t mask = SLOT_MASK(onm); \ - uint perturb = hash; \ - int SLOT_NAME = mask & hash; \ - int INDEX_NAME = onm->map[SLOT_NAME]; \ - for (;; SLOT_NAME = mask & ((5 * SLOT_NAME) + 1 + perturb), \ - perturb >>= PERTURB_SHIFT, \ - INDEX_NAME = onm->map[SLOT_NAME]) - -static void oldnewmap_insert_index_in_map(OldNewMap *onm, const void *ptr, int index) -{ - ITER_SLOTS (onm, ptr, slot, stored_index) { - if (stored_index == -1) { - onm->map[slot] = index; - break; - } - } -} - -static void oldnewmap_insert_or_replace(OldNewMap *onm, OldNew entry) -{ - ITER_SLOTS (onm, entry.oldp, slot, index) { - if (index == -1) { - onm->entries[onm->nentries] = entry; - onm->map[slot] = onm->nentries; - onm->nentries++; - break; - } - if (onm->entries[index].oldp == entry.oldp) { - onm->entries[index] = entry; - break; - } - } -} - -static OldNew *oldnewmap_lookup_entry(const OldNewMap *onm, const void *addr) -{ - ITER_SLOTS (onm, addr, slot, index) { - if (index >= 0) { - OldNew *entry = &onm->entries[index]; - if (entry->oldp == addr) { - return entry; - } - } - else { - return nullptr; - } - } -} - -static void oldnewmap_clear_map(OldNewMap *onm) -{ - memset(onm->map, 0xFF, MAP_CAPACITY(onm) * sizeof(*onm->map)); -} - -static void oldnewmap_increase_size(OldNewMap *onm) -{ - onm->capacity_exp++; - onm->entries = static_cast( - MEM_reallocN(onm->entries, sizeof(*onm->entries) * ENTRIES_CAPACITY(onm))); - onm->map = static_cast(MEM_reallocN(onm->map, sizeof(*onm->map) * MAP_CAPACITY(onm))); - oldnewmap_clear_map(onm); - for (int i = 0; i < onm->nentries; i++) { - oldnewmap_insert_index_in_map(onm, onm->entries[i].oldp, i); - } -} - -/* Public OldNewMap API */ - -static void oldnewmap_init_data(OldNewMap *onm, const int capacity_exp) -{ - memset(onm, 0x0, sizeof(*onm)); - - onm->capacity_exp = capacity_exp; - onm->entries = static_cast( - MEM_malloc_arrayN(ENTRIES_CAPACITY(onm), sizeof(*onm->entries), "OldNewMap.entries")); - onm->map = static_cast( - MEM_malloc_arrayN(MAP_CAPACITY(onm), sizeof(*onm->map), "OldNewMap.map")); - oldnewmap_clear_map(onm); -} - static OldNewMap *oldnewmap_new() { - OldNewMap *onm = static_cast(MEM_mallocN(sizeof(*onm), "OldNewMap")); - - oldnewmap_init_data(onm, DEFAULT_SIZE_EXP); - - return onm; + return MEM_new(__func__); } static void oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, int nr) @@ -350,15 +251,7 @@ static void oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, return; } - if (UNLIKELY(onm->nentries == ENTRIES_CAPACITY(onm))) { - oldnewmap_increase_size(onm); - } - - OldNew entry; - entry.oldp = oldaddr; - entry.newp = newaddr; - entry.nr = nr; - oldnewmap_insert_or_replace(onm, entry); + onm->map.add_overwrite(oldaddr, NewAddress{newaddr, nr}); } static void oldnewmap_lib_insert(FileData *fd, const void *oldaddr, ID *newaddr, int nr) @@ -373,7 +266,7 @@ void blo_do_versions_oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void static void *oldnewmap_lookup_and_inc(OldNewMap *onm, const void *addr, bool increase_users) { - OldNew *entry = oldnewmap_lookup_entry(onm, addr); + NewAddress *entry = onm->map.lookup_ptr(addr); if (entry == nullptr) { return nullptr; } @@ -383,7 +276,7 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, const void *addr, bool inc return entry->newp; } -/* for libdata, OldNew.nr has ID code, no increment */ +/* for libdata, NewAddress.nr has ID code, no increment */ static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *lib) { if (addr == nullptr) { @@ -403,34 +296,19 @@ static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *l static void oldnewmap_clear(OldNewMap *onm) { /* Free unused data. */ - for (int i = 0; i < onm->nentries; i++) { - OldNew *entry = &onm->entries[i]; - if (entry->nr == 0) { - MEM_freeN(entry->newp); - entry->newp = nullptr; + for (NewAddress &new_addr : onm->map.values()) { + if (new_addr.nr == 0) { + MEM_freeN(new_addr.newp); } } - - MEM_freeN(onm->entries); - MEM_freeN(onm->map); - - oldnewmap_init_data(onm, DEFAULT_SIZE_EXP); + onm->map.clear(); } static void oldnewmap_free(OldNewMap *onm) { - MEM_freeN(onm->entries); - MEM_freeN(onm->map); - MEM_freeN(onm); + MEM_delete(onm); } -#undef ENTRIES_CAPACITY -#undef MAP_CAPACITY -#undef SLOT_MASK -#undef DEFAULT_SIZE_EXP -#undef PERTURB_SHIFT -#undef ITER_SLOTS - /** \} */ /* -------------------------------------------------------------------- */ @@ -1555,13 +1433,11 @@ static void change_link_placeholder_to_real_ID_pointer_fd(FileData *fd, const void *old, void *newp) { - for (int i = 0; i < fd->libmap->nentries; i++) { - OldNew *entry = &fd->libmap->entries[i]; - - if (old == entry->newp && entry->nr == ID_LINK_PLACEHOLDER) { - entry->newp = newp; + for (NewAddress &entry : fd->libmap->map.values()) { + if (old == entry.newp && entry.nr == ID_LINK_PLACEHOLDER) { + entry.newp = newp; if (newp) { - entry->nr = GS(((ID *)newp)->name); + entry.nr = GS(((ID *)newp)->name); } } } @@ -1640,12 +1516,10 @@ void blo_make_packed_pointer_map(FileData *fd, Main *oldmain) void blo_end_packed_pointer_map(FileData *fd, Main *oldmain) { - OldNew *entry = fd->packedmap->entries; - /* used entries were restored, so we put them to zero */ - for (int i = 0; i < fd->packedmap->nentries; i++, entry++) { - if (entry->nr > 0) { - entry->newp = nullptr; + for (NewAddress &entry : fd->packedmap->map.values()) { + if (entry.nr > 0) { + entry.newp = nullptr; } }