[Bf-blender-cvs] [0144b11673a] functions: Support inline storage in BLI::Array

Jacques Lucke noreply at git.blender.org
Tue Dec 17 13:53:53 CET 2019


Commit: 0144b11673a1b6e5074dab5cca745d9cd45b527c
Author: Jacques Lucke
Date:   Tue Dec 17 11:35:13 2019 +0100
Branches: functions
https://developer.blender.org/rB0144b11673a1b6e5074dab5cca745d9cd45b527c

Support inline storage in BLI::Array

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

M	source/blender/blenlib/BLI_array_cxx.h
M	source/blender/blenlib/intern/BLI_index_range.cc

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

diff --git a/source/blender/blenlib/BLI_array_cxx.h b/source/blender/blenlib/BLI_array_cxx.h
index 5a3b217abf2..7f5f2b2beb9 100644
--- a/source/blender/blenlib/BLI_array_cxx.h
+++ b/source/blender/blenlib/BLI_array_cxx.h
@@ -30,23 +30,24 @@
 
 namespace BLI {
 
-template<typename T, typename Allocator = GuardedAllocator> class Array {
+template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Array {
  private:
   T *m_data;
   uint m_size;
   Allocator m_allocator;
+  AlignedBuffer<sizeof(T) * N, alignof(T)> m_inline_storage;
 
  public:
   Array()
   {
-    m_data = nullptr;
+    m_data = this->inline_storage();
     m_size = 0;
   }
 
   Array(ArrayRef<T> values)
   {
     m_size = values.size();
-    m_data = this->allocate(m_size);
+    m_data = this->get_buffer_for_size(values.size());
     uninitialized_copy_n(values.begin(), m_size, m_data);
   }
 
@@ -56,8 +57,8 @@ template<typename T, typename Allocator = GuardedAllocator> class Array {
 
   explicit Array(uint size)
   {
-    m_data = this->allocate(size);
     m_size = size;
+    m_data = this->get_buffer_for_size(size);
 
     for (uint i = 0; i < m_size; i++) {
       new (m_data + i) T();
@@ -66,8 +67,8 @@ template<typename T, typename Allocator = GuardedAllocator> class Array {
 
   Array(uint size, const T &value)
   {
-    m_data = this->allocate(size);
     m_size = size;
+    m_data = this->get_buffer_for_size(size);
     uninitialized_fill_n(m_data, m_size, value);
   }
 
@@ -76,30 +77,31 @@ template<typename T, typename Allocator = GuardedAllocator> class Array {
     m_size = other.size();
     m_allocator = other.m_allocator;
 
-    if (m_size == 0) {
-      m_data = nullptr;
-      return;
-    }
-    else {
-      m_data = this->allocate(m_size);
-      copy_n(other.begin(), m_size, m_data);
-    }
+    m_data = this->get_buffer_for_size(other.size());
+    copy_n(other.begin(), m_size, m_data);
   }
 
   Array(Array &&other) noexcept
   {
-    m_data = other.m_data;
     m_size = other.m_size;
     m_allocator = other.m_allocator;
 
-    other.m_data = nullptr;
+    if (!other.uses_inline_storage()) {
+      m_data = other.m_data;
+    }
+    else {
+      m_data = this->get_buffer_for_size(m_size);
+      uninitialized_relocate_n(other.m_data, m_size, m_data);
+    }
+
+    other.m_data = other.inline_storage();
     other.m_size = 0;
   }
 
   ~Array()
   {
     destruct_n(m_data, m_size);
-    if (m_data != nullptr) {
+    if (!this->uses_inline_storage()) {
       m_allocator.deallocate((void *)m_data);
     }
   }
@@ -194,14 +196,34 @@ template<typename T, typename Allocator = GuardedAllocator> class Array {
   }
 
  private:
+  T *get_buffer_for_size(uint size)
+  {
+    if (size <= N) {
+      return this->inline_storage();
+    }
+    else {
+      return this->allocate(size);
+    }
+  }
+
+  T *inline_storage() const
+  {
+    return (T *)m_inline_storage.ptr();
+  }
+
   T *allocate(uint size)
   {
     return (T *)m_allocator.allocate_aligned(
         size * sizeof(T), std::alignment_of<T>::value, __func__);
   }
+
+  bool uses_inline_storage() const
+  {
+    return m_data == this->inline_storage();
+  }
 };
 
-template<typename T> using TemporaryArray = Array<T, TemporaryAllocator>;
+template<typename T> using TemporaryArray = Array<T, 4, TemporaryAllocator>;
 
 }  // namespace BLI
 
diff --git a/source/blender/blenlib/intern/BLI_index_range.cc b/source/blender/blenlib/intern/BLI_index_range.cc
index fde4dcf6d41..6421eb0794b 100644
--- a/source/blender/blenlib/intern/BLI_index_range.cc
+++ b/source/blender/blenlib/intern/BLI_index_range.cc
@@ -24,7 +24,7 @@
 
 namespace BLI {
 
-static Vector<Array<uint, RawAllocator>, 1, RawAllocator> arrays;
+static Vector<Array<uint, 0, RawAllocator>, 1, RawAllocator> arrays;
 static uint current_array_size = 0;
 static uint *current_array = nullptr;
 static std::mutex current_array_mutex;
@@ -44,7 +44,7 @@ ArrayRef<uint> IndexRange::as_array_ref() const
   }
 
   uint new_size = std::max<uint>(1000, power_of_2_max_u(min_required_size));
-  Array<uint, RawAllocator> new_array(new_size);
+  Array<uint, 0, RawAllocator> new_array(new_size);
   for (uint i = 0; i < new_size; i++) {
     new_array[i] = i;
   }



More information about the Bf-blender-cvs mailing list