LCOV - code coverage report
Current view: top level - core/core/memory - SPMemRbtree.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 180 194 92.8 %
Date: 2024-05-12 00:16:13 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2017-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #include "SPMemRbtree.h"
      25             : #include "SPMemStringStream.h"
      26             : 
      27             : namespace STAPPLER_VERSIONIZED stappler::memory::rbtree {
      28             : 
      29    19421264 : NodeBase * NodeBase::increment(NodeBase *c) {
      30    19421264 :         if (c->right) {
      31     8811330 :                 c = c->right;
      32    12148950 :                 while (c->left) {
      33     3337620 :                         c = c->left;
      34             :                 }
      35             :         } else {
      36    10609934 :                 if (c->parent) {
      37    10679968 :                         if (c->parent->left == c) {
      38     6461793 :                                 c = c->parent;
      39             :                         } else {
      40    10951566 :                                 while (c->parent && c->parent->right == c) {
      41     6733391 :                                         c = c->parent;
      42             :                                 }
      43     4218175 :                                 if (!c->parent) {
      44           0 :                                         return nullptr;
      45             :                                 } else {
      46     4218175 :                                         c = c->parent;
      47             :                                 }
      48             :                         }
      49             :                 } else {
      50           0 :                         return nullptr;
      51             :                 }
      52             :         }
      53    19491298 :         return c;
      54             : }
      55             : 
      56   209763891 : const NodeBase * NodeBase::increment(const NodeBase *c) {
      57   209763891 :         if (c->right) {
      58             :                  // move right one step, then left until end
      59    90637166 :                 c = c->right;
      60   137912455 :                 while (c->left) {
      61    47275289 :                         c = c->left;
      62             :                 }
      63             :         } else {
      64   119126725 :                 if (c->parent) {
      65   121214658 :                         if (c->parent->left == c) {
      66    63813863 :                                 c = c->parent;
      67             :                         } else {
      68   147753068 :                                 while (c->parent && c->parent->right == c) {
      69    90352273 :                                         c = c->parent;
      70             :                                 }
      71    57400795 :                                 if (!c->parent) {
      72           0 :                                         return nullptr; // end of iteration
      73             :                                 } else {
      74    57400795 :                                         c = c->parent;
      75             :                                 }
      76             :                         }
      77             :                 } else {
      78           0 :                         return nullptr;
      79             :                 }
      80             :         }
      81   211851824 :         return c;
      82             : }
      83             : 
      84     1387527 : NodeBase * NodeBase::decrement(NodeBase *c) {
      85     1387527 :         if (c->left) {
      86             :                  // move left one step, then right until end
      87      702527 :                 c = c->left;
      88      702527 :                 while (c->right) {
      89           0 :                         c = c->right;
      90             :                 }
      91             :         } else {
      92      685000 :                 if (c->parent) {
      93      689404 :                         if (c->parent->right == c) {
      94      689389 :                                 c = c->parent;
      95             :                         } else {
      96          15 :                                 while (c->parent && c->parent->left == c) {
      97           0 :                                         c = c->parent;
      98             :                                 }
      99          15 :                                 if (!c->parent) {
     100           0 :                                         return nullptr; // end of iteration
     101             :                                 } else {
     102          15 :                                         c = c->parent;
     103             :                                 }
     104             :                         }
     105             :                 } else {
     106           0 :                         return nullptr;
     107             :                 }
     108             :         }
     109     1391931 :         return c;
     110             : }
     111             : 
     112     5211530 : const NodeBase * NodeBase::decrement(const NodeBase *c) {
     113     5211530 :         if (c->left) {
     114             :                  // move left one step, then right until end
     115     3396864 :                 c = c->left;
     116     4243671 :                 while (c->right) {
     117      846807 :                         c = c->right;
     118             :                 }
     119             :         } else {
     120     1814666 :                 if (c->parent) {
     121     1824830 :                         if (c->parent->right == c) {
     122     1373226 :                                 c = c->parent;
     123             :                         } else {
     124     1013297 :                                 while (c->parent && c->parent->left == c) {
     125      561693 :                                         c = c->parent;
     126             :                                 }
     127      451604 :                                 if (!c->parent) {
     128           0 :                                         return nullptr; // end of iteration
     129             :                                 } else {
     130      451604 :                                         c = c->parent;
     131             :                                 }
     132             :                         }
     133             :                 } else {
     134           0 :                         return nullptr;
     135             :                 }
     136             :         }
     137     5221694 :         return c;
     138             : }
     139             : 
     140     3373180 : NodeBase *NodeBase::replace(NodeBase *old, NodeBase *n) {
     141     3373180 :         n->left = old->left;
     142     3373180 :         n->right = old->right;
     143     3373180 :         n->setColor(old->getColor());
     144     3374332 :         n->parent = old->parent;
     145             : 
     146             :         // link new with parent
     147     3374332 :         if (old->parent) {
     148     3375913 :         if (old->parent->left == old) {
     149     2620369 :                 old->parent->left = n;
     150             :         } else {
     151      755544 :                 old->parent->right = n;
     152             :         }
     153             :         }
     154             : 
     155             :         // link new with childs
     156     3374332 :         if (old->left && old->left != n) {
     157     1917804 :                 old->left->parent = n;
     158     1456528 :         } else if (old->left == n) {
     159           0 :                 n->left = nullptr;
     160             :         }
     161     3374332 :         if (old->right && old->right != n) {
     162     2888076 :                 old->right->parent = n;
     163      486256 :         } else if (old->right == n) {
     164           0 :                 n->right = nullptr;
     165             :         }
     166             : 
     167     3374332 :         return old;
     168             : }
     169             : 
     170     5603878 : void RotateLeft(NodeBase * head, NodeBase * n, NodeBase * p) {
     171     5603878 :         NodeBase * tmp = n->left;
     172     5603878 :         if (p == head->left) {
     173     1925125 :                 head->left = n;
     174             :         } else {
     175     3678753 :                 if (p->parent->right == p) {
     176     2214339 :                         p->parent->right = n;
     177             :                 } else {
     178     1464414 :                         p->parent->left = n;
     179             :                 }
     180             :         }
     181     5603878 :         n->parent = p->parent;
     182     5603878 :         p->parent = n;
     183     5603878 :         n->left = p;
     184             : 
     185     5603878 :         if (tmp) tmp->parent = p;
     186     5603878 :         p->right = tmp;
     187     5603878 : }
     188             : 
     189     3028737 : void RotateRight(NodeBase * head, NodeBase * n, NodeBase * p) {
     190     3028737 :         NodeBase * tmp = n->right;
     191     3028737 :         if (p == head->left) {
     192      347157 :                 head->left = n;
     193             :         } else {
     194     2681580 :                 if (p->parent->right == p) {
     195     2059741 :                         p->parent->right = n;
     196             :                 } else {
     197      621839 :                         p->parent->left = n;
     198             :                 }
     199             :         }
     200     3028737 :         n->parent = p->parent;
     201     3028737 :         p->parent = n;
     202     3028737 :         n->right = p;
     203             : 
     204     3028737 :         if (tmp) tmp->parent = p;
     205     3028737 :         p->left = tmp;
     206     3028737 : }
     207             : 
     208    15058117 : void NodeBase::insert(NodeBase *head, NodeBase * n) {
     209             :     /* check Red-Black properties */
     210    22818948 :     while (n != head->left && n->parent->getColor() == NodeColor::Red) {
     211     7762906 :         auto p = n->parent;
     212     7762906 :         auto g = n->parent->parent;
     213     7762906 :         if (p == g->left) {
     214     1630328 :                 NodeBase * u = g->right;
     215     1630328 :             if (u && u->getColor() == NodeColor::Red) {
     216      831552 :                 p->setColor(NodeColor::Black);
     217      831543 :                 u->setColor(NodeColor::Black);
     218      831594 :                 g->setColor(NodeColor::Red);
     219      831614 :                 n = g;
     220             :             } else {
     221      798761 :                 if (n == p->right) {
     222      300271 :                         RotateLeft(head, n, p);
     223      300276 :                     n = n->left;
     224      300276 :                     p = n->parent;
     225             :                 }
     226      798766 :                 p->setColor(NodeColor::Black);
     227      799160 :                 g->setColor(NodeColor::Red);
     228      799170 :                 RotateRight(head, p, g);
     229             :             }
     230             :         } else {
     231     6132578 :                 NodeBase * u = g->left;
     232     6132578 :             if (u && u->getColor() == NodeColor::Red) {
     233     2242146 :                 p->setColor(NodeColor::Black);
     234     2242139 :                 u->setColor(NodeColor::Black);
     235     2242178 :                 g->setColor(NodeColor::Red);
     236     2242179 :                 n = g;
     237             :             } else {
     238     3890438 :                 if (n == n->parent->left) {
     239     1063497 :                         RotateRight(head, n, p);
     240     1063541 :                         n = n->right;
     241     1063541 :                     p = n->parent;
     242             :                 }
     243     3890482 :                 p->setColor(NodeColor::Black);
     244     3890648 :                 g->setColor(NodeColor::Red);
     245     3890650 :                 RotateLeft(head, p, g);
     246             :             }
     247             :         }
     248             :     }
     249    15056353 :     head->left->setColor(NodeColor::Black); // root
     250    15062370 : }
     251             : 
     252     3110182 : void NodeBase::remove(NodeBase *head, NodeBase * n) {
     253     3568545 :         while (n != head->left && n->getColor() == NodeColor::Black) {
     254     2831723 :                 if (n == n->parent->left) {
     255     1750817 :                         NodeBase *s = n->parent->right;
     256     1750817 :                         if (s && s->getColor() == NodeColor::Red) {
     257      163577 :                                 n->parent->setColor(NodeColor::Red);
     258      163572 :                                 s->setColor(NodeColor::Black);
     259      163572 :                                 RotateLeft(head, s, n->parent);
     260      163655 :                                 s = n->parent->right;
     261             :                         }
     262     1750903 :                         if (s) {
     263     1750903 :                                 if (s->getColor() == NodeColor::Black
     264     1750873 :                                                 && (!s->left || s->left->getColor() == NodeColor::Black)
     265     3501812 :                                                 && (!s->right || s->right->getColor() == NodeColor::Black)) {
     266      714893 :                                         s->setColor(NodeColor::Red);
     267      714878 :                                         if (s->parent->getColor() == NodeColor::Red) {
     268      405516 :                                                 s->parent->setColor(NodeColor::Black);
     269      405521 :                                                 break;
     270             :                                         } else {
     271      309500 :                                                 n = n->parent;
     272             :                                         }
     273             :                                 } else {
     274     1036056 :                                         if ((!s->right || s->right->getColor() == NodeColor::Black) && (s->left && s->left->getColor() == NodeColor::Red)) {
     275      488195 :                                                 s->setColor(NodeColor::Red);
     276      488158 :                                                 s->left->setColor(NodeColor::Black);
     277      488181 :                                                 RotateRight(head, s->left, s);
     278      488192 :                                                 s = n->parent->right;
     279             :                                         }
     280     1036042 :                                         s->setColor(n->parent->getColor());
     281     1036943 :                                         n->parent->setColor(NodeColor::Black);
     282     1037121 :                                         if (s->right) s->right->setColor(NodeColor::Black);
     283     1037501 :                                         RotateLeft(head, s, n->parent);
     284     1037487 :                                         break;
     285             :                                 }
     286             :                         } else {
     287           0 :                                 break;
     288             :                         }
     289             :                 } else {
     290     1080906 :                         NodeBase *s = n->parent->left;
     291     1080906 :                         if (s && s->getColor() == NodeColor::Red) {
     292       67777 :                                 n->parent->setColor(NodeColor::Red);
     293       67774 :                                 s->setColor(NodeColor::Black);
     294       67774 :                                 RotateRight(head, s, n->parent);
     295       67749 :                                 s = n->parent->left;
     296             :                         }
     297     1080904 :                         if (s) {
     298     1080904 :                                 if (s->getColor() == NodeColor::Black
     299     1080895 :                                                 && (!s->left || s->left->getColor() == NodeColor::Black)
     300     2161792 :                                                 && (!s->right || s->right->getColor() == NodeColor::Black)) {
     301      468718 :                                         s->setColor(NodeColor::Red);
     302      468716 :                                         if (s->parent->getColor() == NodeColor::Red) {
     303      319885 :                                                 s->parent->setColor(NodeColor::Black);
     304      319890 :                                                 break;
     305             :                                         } else {
     306      148863 :                                                 n = n->parent;
     307             :                                         }
     308             :                                 } else {
     309      612186 :                                         if ((!s->left || s->left->getColor() == NodeColor::Black) && (s->right && s->right->getColor() == NodeColor::Red)) {
     310      214254 :                                                 s->setColor(NodeColor::Red);
     311      214238 :                                                 s->right->setColor(NodeColor::Black);
     312      214248 :                                                 RotateLeft(head, s->right, s);
     313      214249 :                                                 s = n->parent->left;
     314             :                                         }
     315      612183 :                                         s->setColor(n->parent->getColor());
     316      612367 :                                         n->parent->setColor(NodeColor::Black);
     317      612436 :                                         if (s->left) s->left->setColor(NodeColor::Black);
     318      612507 :                                         RotateRight(head, s, n->parent);
     319      612432 :                                         break;
     320             :                                 }
     321             :                         } else {
     322           0 :                                 break;
     323             :                         }
     324             :                 }
     325             :         }
     326     3112610 :         n->setColor(NodeColor::Black);
     327     3113102 : }
     328             : 
     329             : #if SP_MEM_RBTREE_DEBUG
     330             : 
     331             : bool TreeDebug::make_test(std::ostream &ostream, int size) {
     332             :         apr::rbtree::Tree<int, int> tree_test;
     333             :         bool valid = true;
     334             : 
     335             :         apr::ostringstream stream;
     336             :         stream << "{ ";
     337             :         for (int i = 0; i < size; i ++) {
     338             :                 auto val = rand() % 100000;
     339             :                 tree_test.emplace(val);
     340             :                 stream << val << ", ";
     341             : 
     342             :                 auto v = validate(tree_test);
     343             :                 switch (v) {
     344             :                 case Validation::Valid:
     345             :                         break;
     346             :                 case Validation::RootIsNotBlack:
     347             :                         stream << "\nInsert: Invalid Tree: RootIsNotBlack\n";
     348             :                         visit(tree_test, stream);
     349             :                         valid = false;
     350             :                         break;
     351             :                 case Validation::RedChildIntoRedNode:
     352             :                         stream << "\nInsert: Invalid Tree: RedChildIntoRedNode\n";
     353             :                         visit(tree_test, stream);
     354             :                         valid = false;
     355             :                         break;
     356             :                 case Validation::DifferentBlackNodeCount:
     357             :                         stream << "\nInsert: Invalid Tree: DifferentBlackNodeCount\n";
     358             :                         visit(tree_test, stream);
     359             :                         valid = false;
     360             :                         break;
     361             :                 }
     362             :         }
     363             :         stream << "}\nSize: " << tree_test.size() << "\n";
     364             : 
     365             :         apr::array<int> arr;
     366             :         stream << "Sorted: ";
     367             :         for (auto it = tree_test.begin(); it != tree_test.end(); it ++) {
     368             :                 stream << *it << " ";
     369             :                 arr.emplace_back(*it);
     370             :         }
     371             :         stream << "\n";
     372             : 
     373             :         if (valid) {
     374             :                 ostream << stream.str();
     375             :                 stream.clear();
     376             :         }
     377             : 
     378             :         auto val = validate(tree_test);
     379             :         switch (val) {
     380             :         case Validation::Valid:
     381             :                 stream << "Valid Tree\n";
     382             :                 break;
     383             :         case Validation::RootIsNotBlack:
     384             :                 stream << "Invalid Tree: RootIsNotBlack\n";
     385             :                 valid = false;
     386             :                 break;
     387             :         case Validation::RedChildIntoRedNode:
     388             :                 stream << "Invalid Tree: RedChildIntoRedNode\n";
     389             :                 valid = false;
     390             :                 break;
     391             :         case Validation::DifferentBlackNodeCount:
     392             :                 stream << "Invalid Tree: DifferentBlackNodeCount\n";
     393             :                 valid = false;
     394             :                 break;
     395             :         }
     396             :         visit(tree_test, stream);
     397             : 
     398             :         auto max = arr.size();
     399             :         for (size_t i = 0; i < max; i++) {
     400             :                 auto c = rand() % (max - i);
     401             : 
     402             :                 stream << "erase " << arr[c] << " at " << c << "\n";
     403             :                 tree_test.erase_unique(arr[c]);
     404             :                 arr.erase(arr.begin() + c);
     405             : 
     406             :                 for (auto it = tree_test.begin(); it != tree_test.end(); it ++) {
     407             :                         stream << *it << " ";
     408             :                 }
     409             :                 stream << "\n";
     410             :                 auto val = validate(tree_test);
     411             :                 switch (val) {
     412             :                 case Validation::Valid:
     413             :                         break;
     414             :                 case Validation::RootIsNotBlack:
     415             :                         stream << "Erase: Invalid Tree: RootIsNotBlack\n";
     416             :                         visit(tree_test, stream);
     417             :                         valid = false;
     418             :                         break;
     419             :                 case Validation::RedChildIntoRedNode:
     420             :                         stream << "Erase: Invalid Tree: RedChildIntoRedNode\n";
     421             :                         visit(tree_test, stream);
     422             :                         valid = false;
     423             :                         break;
     424             :                 case Validation::DifferentBlackNodeCount:
     425             :                         stream << "Erase: Invalid Tree: DifferentBlackNodeCount\n";
     426             :                         visit(tree_test, stream);
     427             :                         valid = false;
     428             :                         break;
     429             :                 }
     430             :         }
     431             : 
     432             :         if (!valid) {
     433             :                 ostream << stream.str();
     434             :         }
     435             : 
     436             :         return valid;
     437             : }
     438             : 
     439             : bool TreeDebug::make_test(std::ostream &ostream, const apr::array<int> &data, const apr::array<int> &erase) {
     440             :         apr::rbtree::Tree<int, int> tree_test;
     441             :         apr::ostringstream stream;
     442             :         bool valid = true;
     443             : 
     444             :         for (auto &it : data) {
     445             :                 tree_test.emplace(it);
     446             :         }
     447             : 
     448             :         stream << "Sorted: ";
     449             :         apr::array<int> arr;
     450             :         for (auto it = tree_test.begin(); it != tree_test.end(); it ++) {
     451             :                 stream << *it << " ";
     452             :                 arr.emplace_back(*it);
     453             :         }
     454             :         stream << "\n";
     455             : 
     456             :         auto val = validate(tree_test);
     457             :         switch (val) {
     458             :         case Validation::Valid:
     459             :                 stream << "Valid Tree\n";
     460             :                 break;
     461             :         case Validation::RootIsNotBlack:
     462             :                 stream << "Invalid Tree: RootIsNotBlack\n";
     463             :                 valid = false;
     464             :                 break;
     465             :         case Validation::RedChildIntoRedNode:
     466             :                 stream << "Invalid Tree: RedChildIntoRedNode\n";
     467             :                 valid = false;
     468             :                 break;
     469             :         case Validation::DifferentBlackNodeCount:
     470             :                 stream << "Invalid Tree: DifferentBlackNodeCount\n";
     471             :                 valid = false;
     472             :                 break;
     473             :         }
     474             :         visit(tree_test, stream);
     475             : 
     476             : 
     477             :         for (auto &it : erase) {
     478             :                 tree_test.erase_unique(it);
     479             : 
     480             :                 val = validate(tree_test);
     481             :                 switch (val) {
     482             :                 case Validation::Valid:
     483             :                         break;
     484             :                 case Validation::RootIsNotBlack:
     485             :                         stream << "Invalid Tree: RootIsNotBlack\n";
     486             :                         visit(tree_test, stream);
     487             :                         valid = false;
     488             :                         break;
     489             :                 case Validation::RedChildIntoRedNode:
     490             :                         stream << "Invalid Tree: RedChildIntoRedNode\n";
     491             :                         visit(tree_test, stream);
     492             :                         valid = false;
     493             :                         break;
     494             :                 case Validation::DifferentBlackNodeCount:
     495             :                         stream << "Invalid Tree: DifferentBlackNodeCount\n";
     496             :                         visit(tree_test, stream);
     497             :                         valid = false;
     498             :                         break;
     499             :                 }
     500             :         }
     501             : 
     502             :         if (!valid) {
     503             :                 ostream << stream.str();
     504             :         }
     505             : 
     506             :         return valid;
     507             : }
     508             : 
     509             : bool TreeDebug::make_hint_test(std::ostream &stream, int size) {
     510             :         Tree<int, int> tree_test1;
     511             :         auto time_test1_s = std::chrono::system_clock::now();
     512             :         for(int i = 0; i < size; ++i) {
     513             :                 tree_test1.emplace(i);
     514             :         }
     515             :         auto time_test1 = std::chrono::system_clock::now() - time_test1_s;
     516             : 
     517             : 
     518             :         auto time_test2_s = std::chrono::system_clock::now();
     519             :         Tree<int, int> tree_test2;
     520             :         auto it2 = tree_test2.begin();
     521             :         for(int i = 0; i < size; ++i) {
     522             :                 tree_test2.emplace_hint(it2, i);
     523             :                 it2 = tree_test2.end();
     524             :         }
     525             :         auto time_test2 = std::chrono::system_clock::now() - time_test2_s;
     526             : 
     527             : 
     528             :         auto time_test3_s = std::chrono::system_clock::now();
     529             :         Tree<int, int> tree_test3;
     530             :         auto it3 = tree_test3.begin();
     531             :         for(int i = size; i > 0; --i) {
     532             :                 tree_test3.emplace_hint(it3, i);
     533             :                 it3 = tree_test3.end();
     534             :         }
     535             :         auto time_test3 = std::chrono::system_clock::now() - time_test3_s;
     536             : 
     537             : 
     538             :         auto time_test4_s = std::chrono::system_clock::now();
     539             :         Tree<int, int> tree_test4;
     540             :         auto it4 = tree_test4.begin();
     541             :         for(int i = size; i > 0; --i) {
     542             :                 tree_test4.emplace_hint(it4, i);
     543             :                 it4 = tree_test4.begin();
     544             :         }
     545             :         auto time_test4 = std::chrono::system_clock::now() - time_test4_s;
     546             : 
     547             : 
     548             :         auto time_test5_s = std::chrono::system_clock::now();
     549             :         Tree<int, int> tree_test5;
     550             :         auto it5 = tree_test5.begin();
     551             :         for(int i = 0; i < size; ++i) {
     552             :                 it5 = tree_test5.emplace_hint(it5, i);
     553             :         }
     554             :         auto time_test5 = std::chrono::system_clock::now() - time_test5_s;
     555             : 
     556             : 
     557             :         stream << std::fixed << std::setprecision(2)
     558             :         << " time: " << time_test1.count() << " Emplace test: " << validate(tree_test1) << "\n"
     559             :         << " time: " << time_test2.count() << " Emplace Hint test: " << validate(tree_test2) << "\n"
     560             :         << " time: " << time_test3.count() << " Emplace Wrong Hint test: " << validate(tree_test3) << "\n"
     561             :         << " time: " << time_test4.count() << " Emplace Corrected Hint test: " << validate(tree_test4) << "\n"
     562             :         << " time: " << time_test5.count() << " Emplace Closest Hint test: " << validate(tree_test5) << "\n";
     563             : 
     564             :         return true;
     565             : }
     566             : 
     567             : #endif
     568             : 
     569             : }

Generated by: LCOV version 1.14