From 6fad4f1a7ba33d1ba2d1d828aef221d39f5a65eb Mon Sep 17 00:00:00 2001
From: Quentin Khan <quentin.khan@inria.fr>
Date: Mon, 6 Jun 2016 14:27:06 +0200
Subject: [PATCH] FNode: reduce FNode::split allocation call count

An allocation was made for each child. Now an array of children is
allocated in one go.
---
 Src/Adaptive/new/FNode.hpp | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/Src/Adaptive/new/FNode.hpp b/Src/Adaptive/new/FNode.hpp
index b8b44431e..3da00ecc6 100644
--- a/Src/Adaptive/new/FNode.hpp
+++ b/Src/Adaptive/new/FNode.hpp
@@ -251,9 +251,7 @@ public:
 
     /** Destructor */
     ~FNode() {
-        for(auto&& child : _children) {
-            delete child;
-        }
+        this->delete_children();
     }
 
 
@@ -634,12 +632,14 @@ private:
 
     /** Allocates this node's children */
     void create_children() {
+        using uninit_FNode = typename std::aligned_storage<sizeof(FNode)>::type;
         std::size_t idx = 0;
         // Remove this node from tree leaf list
         getTree().leaves().erase(this);
         // Create the children, add them to tree leaf list
+        FNode* tmp = reinterpret_cast<FNode*>(new uninit_FNode[child_count]);
         for(FNode*& child : getChildren()) {
-            child = new FNode(*this, idx);
+            child = new(tmp+idx) FNode(*this, idx);
             getTree().leaves().insert(child);
             ++idx;
         }
@@ -651,12 +651,16 @@ private:
 
     /* Deletes this node's children */
     void delete_children() {
+        using uninit_FNode = typename std::aligned_storage<sizeof(FNode)>::type;
         // Remove children from tree leaf list, free them
         for(FNode*& child : getChildren()) {
-            getTree().leaves().erase(child);
-            delete child;
-            child = nullptr;
+            if(child) {
+                getTree().leaves().erase(child);
+                child->~FNode();
+            }
         }
+        delete[] reinterpret_cast<uninit_FNode*>(getChild(0));
+        std::fill_n(this->getChildren().data(), child_count, nullptr);
         // Insert this node in tree leaf list
         getTree().leaves().insert(this);
         // Set leaf status for this node
-- 
GitLab