Bug 1403444 - Allow First and Last to take a start node, and use that in Next and Prev. r?njn draft
authorMike Hommey <mh+mozilla@glandium.org>
Tue, 26 Sep 2017 16:55:31 +0900
changeset 670929 2e21726138e12d2bf5f9a54ecd0cacdea3f72433
parent 670928 6207d5bb51ef7858ec94ecc2c1f5567d3c51b695
child 670930 e9a5e4ac7b22b980cafc4dda39a6af319d880f6e
push id81767
push userbmo:mh+mozilla@glandium.org
push dateWed, 27 Sep 2017 06:43:40 +0000
reviewersnjn
bugs1403444
milestone58.0a1
Bug 1403444 - Allow First and Last to take a start node, and use that in Next and Prev. r?njn
memory/build/rb.h
--- a/memory/build/rb.h
+++ b/memory/build/rb.h
@@ -506,36 +506,35 @@ struct RedBlackTree
   void Init()
   {
     rbt_root = &rbt_nil;
     Trait::GetTreeNode(&rbt_nil).SetLeft(&rbt_nil);
     Trait::GetTreeNode(&rbt_nil).SetRight(&rbt_nil);
     Trait::GetTreeNode(&rbt_nil).SetColor(NodeColor::Black);
   }
 
-  T* First()
+  T* First(T* aStart = nullptr)
   {
     T* ret;
-    rbp_first(T, Trait::GetTreeNode, this, rbt_root, (ret));
+    rbp_first(T, Trait::GetTreeNode, this, (aStart ? aStart : rbt_root), (ret));
     return (ret == &rbt_nil) ? nullptr : ret;
   }
 
-  T* Last()
+  T* Last(T* aStart = nullptr)
   {
     T* ret;
-    rbp_last(T, Trait::GetTreeNode, this, rbt_root, ret);
+    rbp_last(T, Trait::GetTreeNode, this, (aStart ? aStart : rbt_root), ret);
     return (ret == &rbt_nil) ? nullptr : ret;
   }
 
   T* Next(T* aNode)
   {
     T* ret;
     if (Trait::GetTreeNode(aNode).Right() != &rbt_nil) {
-      rbp_first(
-        T, Trait::GetTreeNode, this, Trait::GetTreeNode(aNode).Right(), (ret));
+      ret = First(Trait::GetTreeNode(aNode).Right());
     } else {
       T* rbp_n_t = rbt_root;
       MOZ_ASSERT(rbp_n_t != &rbt_nil);
       ret = &rbt_nil;
       while (true) {
         int rbp_n_cmp = Trait::Compare(aNode, rbp_n_t);
         if (rbp_n_cmp < 0) {
           ret = rbp_n_t;
@@ -550,18 +549,17 @@ struct RedBlackTree
     }
     return (ret == &rbt_nil) ? nullptr : ret;
   }
 
   T* Prev(T* aNode)
   {
     T* ret;
     if (Trait::GetTreeNode(aNode).Left() != &rbt_nil) {
-      rbp_last(
-        T, Trait::GetTreeNode, this, Trait::GetTreeNode(aNode).Left(), (ret));
+      ret = Last(Trait::GetTreeNode(aNode).Left());
     } else {
       T* rbp_p_t = rbt_root;
       MOZ_ASSERT(rbp_p_t != &rbt_nil);
       ret = &rbt_nil;
       while (true) {
         int rbp_p_cmp = Trait::Compare(aNode, rbp_p_t);
         if (rbp_p_cmp < 0) {
           rbp_p_t = Trait::GetTreeNode(rbp_p_t).Left();