[Bf-blender-cvs] [6732a03531f] functions: introduce StringMultiMap

Jacques Lucke noreply at git.blender.org
Thu Jan 2 16:38:31 CET 2020


Commit: 6732a03531f9a1a14adb5edee17217aaff67d802
Author: Jacques Lucke
Date:   Thu Jan 2 16:28:55 2020 +0100
Branches: functions
https://developer.blender.org/rB6732a03531f9a1a14adb5edee17217aaff67d802

introduce StringMultiMap

===================================================================

M	source/blender/blenlib/BLI_parallel.h
M	source/blender/blenlib/BLI_string_map.h
A	source/blender/blenlib/BLI_string_multi_map.h
M	source/blender/blenlib/CMakeLists.txt
M	source/blender/simulations/bparticles/actions.cpp
M	source/blender/simulations/bparticles/c_wrapper.cpp
M	source/blender/simulations/bparticles/particle_allocator.hpp
M	source/blender/simulations/bparticles/simulate.cpp
M	tests/gtests/blenlib/BLI_string_map_test.cc

===================================================================

diff --git a/source/blender/blenlib/BLI_parallel.h b/source/blender/blenlib/BLI_parallel.h
index da82c2fdc7b..769beaf39fa 100644
--- a/source/blender/blenlib/BLI_parallel.h
+++ b/source/blender/blenlib/BLI_parallel.h
@@ -10,6 +10,7 @@
 #include "BLI_index_range.h"
 #include "BLI_multi_map.h"
 #include "BLI_string_map.h"
+#include "BLI_string_multi_map.h"
 
 namespace BLI {
 
@@ -76,7 +77,7 @@ void parallel_invoke(const FuncT1 &func1, const FuncT2 &func2, const FuncT3 &fun
 }
 
 template<typename KeyT, typename ValueT, uint N, typename FuncT>
-void parallel_multi_map_items(const MultiMap<KeyT, ValueT, N> &multi_map, const FuncT &func)
+void parallel_map_items(const MultiMap<KeyT, ValueT, N> &multi_map, const FuncT &func)
 {
   ScopedVector<const KeyT *> key_vector;
   ScopedVector<ArrayRef<ValueT>> values_vector;
@@ -95,12 +96,31 @@ void parallel_multi_map_items(const MultiMap<KeyT, ValueT, N> &multi_map, const
 }
 
 template<typename ValueT, typename FuncT>
-void parallel_string_map_items(const StringMap<ValueT> &string_map, const FuncT &func)
+void parallel_map_items(const StringMultiMap<ValueT> &string_multi_map, const FuncT &func)
+{
+  ScopedVector<StringRefNull> key_vector;
+  ScopedVector<ArrayRef<ValueT>> values_vector;
+
+  string_multi_map.foreach_item([&](StringRefNull key, ArrayRef<ValueT> values) {
+    key_vector.append(key);
+    values_vector.append(values);
+  });
+
+  parallel_for(key_vector.index_range(), [&](uint index) {
+    StringRefNull &key = key_vector[index];
+    ArrayRef<ValueT> values = values_vector[index];
+
+    func(key, values);
+  });
+}
+
+template<typename ValueT, typename FuncT>
+void parallel_map_items(const StringMap<ValueT> &string_map, const FuncT &func)
 {
   ScopedVector<StringRefNull> key_vector;
   ScopedVector<const ValueT *> value_vector;
 
-  string_map.foreach_key_value_pair([&](StringRefNull key, const ValueT &value) {
+  string_map.foreach_item([&](StringRefNull key, const ValueT &value) {
     key_vector.append(key);
     value_vector.append(&value);
   });
diff --git a/source/blender/blenlib/BLI_string_map.h b/source/blender/blenlib/BLI_string_map.h
index 1378c3ae79e..2f09e489a7a 100644
--- a/source/blender/blenlib/BLI_string_map.h
+++ b/source/blender/blenlib/BLI_string_map.h
@@ -348,7 +348,7 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap {
   /**
    * Run a function for every key-value-pair in the map.
    */
-  template<typename FuncT> void foreach_key_value_pair(const FuncT &func)
+  template<typename FuncT> void foreach_item(const FuncT &func)
   {
     for (Item &item : m_array) {
       for (uint offset = 0; offset < 4; offset++) {
@@ -361,7 +361,7 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap {
     }
   }
 
-  template<typename FuncT> void foreach_key_value_pair(const FuncT &func) const
+  template<typename FuncT> void foreach_item(const FuncT &func) const
   {
     for (const Item &item : m_array) {
       for (uint offset = 0; offset < 4; offset++) {
diff --git a/source/blender/blenlib/BLI_string_multi_map.h b/source/blender/blenlib/BLI_string_multi_map.h
new file mode 100644
index 00000000000..94f414d14ab
--- /dev/null
+++ b/source/blender/blenlib/BLI_string_multi_map.h
@@ -0,0 +1,81 @@
+#ifndef __BLI_STRING_MULTI_MAP_H__
+#define __BLI_STRING_MULTI_MAP_H__
+
+#include "BLI_string_ref.h"
+#include "BLI_string_map.h"
+#include "BLI_vector.h"
+
+namespace BLI {
+
+template<typename ValueT> class StringMultiMap {
+ private:
+  StringMap<Vector<ValueT>> m_map;
+
+ public:
+  StringMultiMap() = default;
+  ~StringMultiMap() = default;
+
+  uint key_amount() const
+  {
+    return m_map.size();
+  }
+
+  uint value_amount(StringRef key) const
+  {
+    return m_map.lookup(key).size();
+  }
+
+  bool add(StringRef key, const ValueT &value)
+  {
+    if (m_map.contains(key)) {
+      m_map.lookup(key).append(value);
+      return false;
+    }
+    else {
+      m_map.add_new(key, Vector<ValueT>({value}));
+      return true;
+    }
+  }
+
+  void add_multiple(StringRef key, ArrayRef<ValueT> values)
+  {
+    if (m_map.contains(key)) {
+      m_map.lookup(key).extend(values);
+    }
+    else {
+      m_map.add_new(key, values);
+    }
+  }
+
+  void add_multiple(const StringMultiMap<ValueT> &other)
+  {
+    other.foreach_item(
+        [&](StringRefNull key, ArrayRef<ValueT> values) { this->add_multiple(key, values); });
+  }
+
+  ArrayRef<ValueT> lookup(StringRef key) const
+  {
+    return m_map.lookup(key);
+  }
+
+  ArrayRef<ValueT> lookup_default(StringRef key,
+                                  ArrayRef<ValueT> default_array = ArrayRef<ValueT>())
+  {
+    const Vector<ValueT> *values = m_map.lookup_ptr(key);
+    if (values == nullptr) {
+      return default_array;
+    }
+    else {
+      return *values;
+    }
+  }
+
+  template<typename FuncT> void foreach_item(const FuncT &func) const
+  {
+    m_map.foreach_item([&](StringRefNull key, ArrayRef<ValueT> vector) { func(key, vector); });
+  }
+};
+
+}  // namespace BLI
+
+#endif /* __BLI_STRING_MULTI_MAP_H__ */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 30dc6e31f3f..81d0f6f3a60 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -275,6 +275,7 @@ set(SRC
   BLI_static_class_ids.h
   BLI_index_mask.h
   BLI_parallel.h
+  BLI_string_multi_map.h
 )
 
 set(LIB
diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp
index c60a7967b98..8f6970ef3a7 100644
--- a/source/blender/simulations/bparticles/actions.cpp
+++ b/source/blender/simulations/bparticles/actions.cpp
@@ -199,23 +199,21 @@ void SpawnParticlesAction::execute(ParticleActionContext &context)
   for (StringRef system_name : m_systems_to_emit) {
     auto new_particles = context.particle_allocator().request(system_name, total_spawn_amount);
 
-    attribute_arrays.foreach_key_value_pair(
-        [&](StringRef attribute_name, GenericMutableArrayRef array) {
-          if (new_particles.info().has_attribute(attribute_name, array.type())) {
-            new_particles.set(attribute_name, array);
-          }
-        });
+    attribute_arrays.foreach_item([&](StringRef attribute_name, GenericMutableArrayRef array) {
+      if (new_particles.info().has_attribute(attribute_name, array.type())) {
+        new_particles.set(attribute_name, array);
+      }
+    });
 
     m_action.execute_for_new_particles(new_particles, context);
   }
 
-  attribute_arrays.foreach_key_value_pair(
-      [&](StringRef attribute_name, GenericMutableArrayRef array) {
-        if (attribute_name != "Birth Time") {
-          array.destruct_indices(context.mask());
-          MEM_freeN(array.buffer());
-        }
-      });
+  attribute_arrays.foreach_item([&](StringRef attribute_name, GenericMutableArrayRef array) {
+    if (attribute_name != "Birth Time") {
+      array.destruct_indices(context.mask());
+      MEM_freeN(array.buffer());
+    }
+  });
 }
 
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/c_wrapper.cpp b/source/blender/simulations/bparticles/c_wrapper.cpp
index 8b84e055a0f..1fafeff947c 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -74,7 +74,7 @@ void BParticles_simulate_modifier(BParticlesModifierData *bpmd,
   simulation_state.time().end_update();
 
   auto &containers = simulation_state.particles().particle_containers();
-  containers.foreach_key_value_pair([](StringRefNull system_name, ParticleSet *particles) {
+  containers.foreach_item([](StringRefNull system_name, ParticleSet *particles) {
     std::cout << "Particle System: " << system_name << ": " << particles->size() << "\n";
   });
 }
@@ -297,7 +297,7 @@ void BParticles_modifier_cache_state(BParticlesModifierData *bpmd,
   Vector<std::string> system_names;
   Vector<ParticleSet *> particle_sets;
 
-  state.particles().particle_containers().foreach_key_value_pair(
+  state.particles().particle_containers().foreach_item(
       [&system_names, &particle_sets](StringRefNull name, ParticleSet *particles) {
         system_names.append(name);
         particle_sets.append(particles);
diff --git a/source/blender/simulations/bparticles/particle_allocator.hpp b/source/blender/simulations/bparticles/particle_allocator.hpp
index 21c4dd82b5b..304d5e0d5a0 100644
--- a/source/blender/simulations/bparticles/particle_allocator.hpp
+++ b/source/blender/simulations/bparticles/particle_allocator.hpp
@@ -2,19 +2,19 @@
 
 #include <mutex>
 
-#include "BLI_multi_map.h"
+#include "BLI_string_multi_map.h"
 
 #include "particles_state.hpp"
 
 namespace BParticles {
 
-using BLI::MultiMap;
+using BLI::StringMultiMap;
 using FN::AttributesRefGroup;
 
 class ParticleAllocator : BLI::NonCopyable, BLI::NonMovable {
  private:
   ParticlesState &m_state;
-  MultiMap<std::string, ParticleSet *> m_allocated_particles;
+  StringMultiMap<ParticleSet *> m_allocated_particles;
   std::mutex m_request_mutex;
 
  public:
@@ -23,7 +23,7 @@ class ParticleAllocator : BLI::NonCopyable, BLI::NonMovable {
   /**
    * Access all particles that have been allocated by this allocator.
    */
-  MultiMap<std::string, ParticleSet *> allocated_particles();
+  StringMultiMap<ParticleSet *> allocated_particles();
 
   /**
    * Get memory buffers for new particles.
@@ -37,7 +37,7 @@ class ParticleAllocator : BLI::NonCopyable, BLI::NonMovable {
 /* ParticleAllocator inline functions
  ********************************************/
 
-inline MultiMap<std::string, ParticleSet *> ParticleAllocator::allocated_particles()
+inline StringMultiMap<ParticleSet *> ParticleAllocator::allocated_particles()
 {
   return m_allocated_particles;
 }
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index 2d0d1f8758b..84b3a14b979 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -392,20 +392,20 @@ BLI_NOINLINE static void simulate_existing_particles(
 {
   FloatInterval simulation_time_span = simulation_state.time().current_updat

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list