diff options
-rw-r--r-- | source/blender/blenkernel/intern/derived_node_tree.cc | 6 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_map.hh | 70 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_rna.cc | 2 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_physics.cc | 4 | ||||
-rw-r--r-- | tests/gtests/blenlib/BLI_map_test.cc | 26 |
5 files changed, 85 insertions, 23 deletions
diff --git a/source/blender/blenkernel/intern/derived_node_tree.cc b/source/blender/blenkernel/intern/derived_node_tree.cc index 80ae521642e..961fef958b7 100644 --- a/source/blender/blenkernel/intern/derived_node_tree.cc +++ b/source/blender/blenkernel/intern/derived_node_tree.cc @@ -24,8 +24,8 @@ namespace BKE { static const NodeTreeRef &get_tree_ref(NodeTreeRefMap &node_tree_refs, bNodeTree *btree) { - return *node_tree_refs.lookup_or_add(btree, - [&]() { return blender::make_unique<NodeTreeRef>(btree); }); + return *node_tree_refs.lookup_or_add_cb( + btree, [&]() { return blender::make_unique<NodeTreeRef>(btree); }); } DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs) : m_btree(btree) @@ -365,7 +365,7 @@ static Dot::Cluster *get_cluster_for_parent(Dot::DirectedGraph &graph, if (parent == nullptr) { return nullptr; } - return clusters.lookup_or_add(parent, [&]() { + return clusters.lookup_or_add_cb(parent, [&]() { Dot::Cluster *parent_cluster = get_cluster_for_parent(graph, clusters, parent->parent()); bNodeTree *btree = (bNodeTree *)parent->node_ref().bnode()->id; Dot::Cluster *new_cluster = &graph.new_cluster(parent->node_ref().name() + " / " + diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh index 56ec5b7010c..5819430fe97 100644 --- a/source/blender/blenlib/BLI_map.hh +++ b/source/blender/blenlib/BLI_map.hh @@ -514,6 +514,38 @@ class Map { } /** + * Returns a reference to the value corresponding to the given key. If the key is not in the map, + * a new key-value-pair is added and a reference to the value in the map is returned. + */ + Value &lookup_or_add(const Key &key, const Value &value) + { + return this->lookup_or_add_as(key, value); + } + Value &lookup_or_add(const Key &key, Value &&value) + { + return this->lookup_or_add_as(key, std::move(value)); + } + Value &lookup_or_add(Key &&key, const Value &value) + { + return this->lookup_or_add_as(std::move(key), value); + } + Value &lookup_or_add(Key &&key, Value &&value) + { + return this->lookup_or_add_as(std::move(key), std::move(value)); + } + + /** + * Same as `lookup_or_add`, but accepts other key types that are supported by the hash + * function. + */ + template<typename ForwardKey, typename ForwardValue> + Value &lookup_or_add_as(ForwardKey &&key, ForwardValue &&value) + { + return this->lookup_or_add__impl( + std::forward<ForwardKey>(key), std::forward<ForwardValue>(value), m_hash(key)); + } + + /** * Returns a reference to the value that corresponds to the given key. If the key is not yet in * the map, it will be newly added. * @@ -521,22 +553,24 @@ class Map { * take no parameters and return the value to be inserted. */ template<typename CreateValueF> - Value &lookup_or_add(const Key &key, const CreateValueF &create_value) + Value &lookup_or_add_cb(const Key &key, const CreateValueF &create_value) { - return this->lookup_or_add_as(key, create_value); + return this->lookup_or_add_cb_as(key, create_value); } - template<typename CreateValueF> Value &lookup_or_add(Key &&key, const CreateValueF &create_value) + template<typename CreateValueF> + Value &lookup_or_add_cb(Key &&key, const CreateValueF &create_value) { - return this->lookup_or_add_as(std::move(key), create_value); + return this->lookup_or_add_cb_as(std::move(key), create_value); } /** - * Same as `lookup_or_add`, but accepts other key types that are supported by the hash function. + * Same as `lookup_or_add_cb`, but accepts other key types that are supported by the hash + * function. */ template<typename ForwardKey, typename CreateValueF> - Value &lookup_or_add_as(ForwardKey &&key, const CreateValueF &create_value) + Value &lookup_or_add_cb_as(ForwardKey &&key, const CreateValueF &create_value) { - return this->lookup_or_add__impl(std::forward<ForwardKey>(key), create_value, m_hash(key)); + return this->lookup_or_add_cb__impl(std::forward<ForwardKey>(key), create_value, m_hash(key)); } /** @@ -558,7 +592,7 @@ class Map { */ template<typename ForwardKey> Value &lookup_or_add_default_as(ForwardKey &&key) { - return this->lookup_or_add(std::forward<ForwardKey>(key), []() { return Value(); }); + return this->lookup_or_add_cb(std::forward<ForwardKey>(key), []() { return Value(); }); } /** @@ -1024,7 +1058,7 @@ class Map { } template<typename ForwardKey, typename CreateValueF> - Value &lookup_or_add__impl(ForwardKey &&key, const CreateValueF &create_value, uint32_t hash) + Value &lookup_or_add_cb__impl(ForwardKey &&key, const CreateValueF &create_value, uint32_t hash) { this->ensure_can_add(); @@ -1042,6 +1076,24 @@ class Map { } template<typename ForwardKey, typename ForwardValue> + Value &lookup_or_add__impl(ForwardKey &&key, ForwardValue &&value, uint32_t hash) + { + this->ensure_can_add(); + + MAP_SLOT_PROBING_BEGIN (hash, slot) { + if (slot.is_empty()) { + slot.occupy(std::forward<ForwardKey>(key), std::forward<ForwardValue>(value), hash); + m_occupied_and_removed_slots++; + return *slot.value(); + } + if (slot.contains(key, m_is_equal, hash)) { + return *slot.value(); + } + } + MAP_SLOT_PROBING_END(); + } + + template<typename ForwardKey, typename ForwardValue> bool add_overwrite__impl(ForwardKey &&key, ForwardValue &&value, uint32_t hash) { auto create_func = [&](Value *ptr) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 94f58427251..fbd53bf46f8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -364,7 +364,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, RNANodeQueryIDData *RNANodeQuery::ensure_id_data(const ID *id) { - unique_ptr<RNANodeQueryIDData> &id_data = id_data_map_.lookup_or_add( + unique_ptr<RNANodeQueryIDData> &id_data = id_data_map_.lookup_or_add_cb( id, [&]() { return blender::make_unique<RNANodeQueryIDData>(id); }); return id_data.get(); } diff --git a/source/blender/depsgraph/intern/depsgraph_physics.cc b/source/blender/depsgraph/intern/depsgraph_physics.cc index 44c3d23ace4..ad67117fda3 100644 --- a/source/blender/depsgraph/intern/depsgraph_physics.cc +++ b/source/blender/depsgraph/intern/depsgraph_physics.cc @@ -167,7 +167,7 @@ ListBase *build_effector_relations(Depsgraph *graph, Collection *collection) graph->physics_relations[DEG_PHYSICS_EFFECTOR] = new Map<const ID *, ListBase *>(); hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR]; } - return hash->lookup_or_add(&collection->id, [&]() { + return hash->lookup_or_add_cb(&collection->id, [&]() { ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(graph); return BKE_effector_relations_create(depsgraph, graph->view_layer, collection); }); @@ -183,7 +183,7 @@ ListBase *build_collision_relations(Depsgraph *graph, graph->physics_relations[type] = new Map<const ID *, ListBase *>(); hash = graph->physics_relations[type]; } - return hash->lookup_or_add(&collection->id, [&]() { + return hash->lookup_or_add_cb(&collection->id, [&]() { ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(graph); return BKE_collision_relations_create(depsgraph, collection, modifier_type); }); diff --git a/tests/gtests/blenlib/BLI_map_test.cc b/tests/gtests/blenlib/BLI_map_test.cc index ec4cbb9e53e..aa8903ed8ff 100644 --- a/tests/gtests/blenlib/BLI_map_test.cc +++ b/tests/gtests/blenlib/BLI_map_test.cc @@ -197,25 +197,25 @@ static float return_42() return 42.0f; } -TEST(map, LookupOrAdd_SeparateFunction) +TEST(map, LookupOrAddCB_SeparateFunction) { Map<int, float> map; - EXPECT_EQ(map.lookup_or_add(0, return_42), 42.0f); + EXPECT_EQ(map.lookup_or_add_cb(0, return_42), 42.0f); EXPECT_EQ(map.lookup(0), 42); map.keys(); } -TEST(map, LookupOrAdd_Lambdas) +TEST(map, LookupOrAddCB_Lambdas) { Map<int, float> map; auto lambda1 = []() { return 11.0f; }; - EXPECT_EQ(map.lookup_or_add(0, lambda1), 11.0f); + EXPECT_EQ(map.lookup_or_add_cb(0, lambda1), 11.0f); auto lambda2 = []() { return 20.0f; }; - EXPECT_EQ(map.lookup_or_add(1, lambda2), 20.0f); + EXPECT_EQ(map.lookup_or_add_cb(1, lambda2), 20.0f); - EXPECT_EQ(map.lookup_or_add(0, lambda2), 11.0f); - EXPECT_EQ(map.lookup_or_add(1, lambda1), 20.0f); + EXPECT_EQ(map.lookup_or_add_cb(0, lambda2), 11.0f); + EXPECT_EQ(map.lookup_or_add_cb(1, lambda1), 20.0f); } TEST(map, AddOrModify) @@ -258,6 +258,15 @@ TEST(map, LookupOrAddDefault) EXPECT_EQ(map.lookup(3), 10); } +TEST(map, LookupOrAdd) +{ + Map<int, int> map; + EXPECT_EQ(map.lookup_or_add(6, 4), 4); + EXPECT_EQ(map.lookup_or_add(6, 5), 4); + map.lookup_or_add(6, 4) += 10; + EXPECT_EQ(map.lookup(6), 14); +} + TEST(map, MoveConstructorSmall) { Map<int, float> map1; @@ -342,10 +351,11 @@ TEST(map, UniquePtrValue) map.add_new(1, std::move(value1)); map.add(2, std::move(value2)); map.add_overwrite(3, std::move(value3)); - map.lookup_or_add(4, []() { return std::unique_ptr<int>(new int()); }); + map.lookup_or_add_cb(4, []() { return std::unique_ptr<int>(new int()); }); map.add_new(5, std::unique_ptr<int>(new int())); map.add(6, std::unique_ptr<int>(new int())); map.add_overwrite(7, std::unique_ptr<int>(new int())); + map.lookup_or_add(8, std::unique_ptr<int>(new int())); EXPECT_EQ(map.lookup(1).get(), value1_ptr); EXPECT_EQ(map.lookup_ptr(100), nullptr); |