Bug 1397056 - Add Contains and a return parameter to Remove for SmallPointerArray. r=froydnj
authorMatt Woodrow <mwoodrow@mozilla.com>
Tue, 12 Sep 2017 14:11:47 -0400
changeset 380645 04077d71603ea4dc9dd47e2ccc8d49d92deaa8dc
parent 380644 7bf13864b0abd28bbceb612541e4fe340bd0a67f
child 380646 14d1ec48399778608f58e7e3bd29dfdb810f12f4
push id94962
push usermwoodrow@mozilla.com
push dateWed, 13 Sep 2017 19:29:13 +0000
treeherdermozilla-inbound@14d1ec483997 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1397056
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1397056 - Add Contains and a return parameter to Remove for SmallPointerArray. r=froydnj * * * [mq]: fix MozReview-Commit-ID: 5laM7PQLP7X
mfbt/SmallPointerArray.h
mfbt/tests/TestSmallPointerArray.cpp
testing/cppunittest.ini
--- a/mfbt/SmallPointerArray.h
+++ b/mfbt/SmallPointerArray.h
@@ -4,16 +4,17 @@
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* A vector of pointers space-optimized for a small number of elements. */
 #ifndef mozilla_SmallPointerArray_h
 #define mozilla_SmallPointerArray_h
 
 #include "mozilla/Assertions.h"
+#include <algorithm>
 #include <iterator>
 #include <vector>
 
 namespace mozilla {
 
 // Array class for situations where a small number of elements (<= 2) is
 // expected, a large number of elements must be accomodated if necessary,
 // and the size of the class must be minimal. Typical vector implementations
@@ -91,44 +92,70 @@ public:
       mInlineElements[1] = aElement;
       return;
     }
 
     mArray = new std::vector<T*>({ mInlineElements[0], mInlineElements[1], aElement });
     mInlineElements[0] = nullptr;
   }
 
-  void RemoveElement(T* aElement) {
+  bool RemoveElement(T* aElement) {
     MOZ_ASSERT(aElement != nullptr);
     if (aElement == nullptr) {
-      return;
+      return false;
     }
 
     if (mInlineElements[0] == aElement) {
       // Expectected case.
       mInlineElements[0] = mInlineElements[1];
       mInlineElements[1] = nullptr;
-      return;
+      return true;
     }
 
     if (mInlineElements[0]) {
       if (mInlineElements[1] == aElement) {
         mInlineElements[1] = nullptr;
+        return true;
       }
-      return;
+      return false;
     }
 
     if (mArray) {
       for (auto iter = mArray->begin(); iter != mArray->end(); iter++) {
         if (*iter == aElement) {
           mArray->erase(iter);
-          return;
+          return true;
         }
       }
     }
+    return false;
+  }
+
+  bool Contains(T* aElement) const {
+    MOZ_ASSERT(aElement != nullptr);
+    if (aElement == nullptr) {
+      return false;
+    }
+
+    if (mInlineElements[0] == aElement) {
+      return true;
+    }
+
+    if (mInlineElements[0]) {
+      if (mInlineElements[1] == aElement) {
+        return true;
+      }
+      return false;
+    }
+
+    if (mArray) {
+      return std::find(mArray->begin(), mArray->end(), aElement) != mArray->end();
+    }
+    return false;
+
   }
 
   size_t Length() const
   {
     if (mInlineElements[0]) {
       if (!mInlineElements[1]) {
         return 1;
       }
--- a/mfbt/tests/TestSmallPointerArray.cpp
+++ b/mfbt/tests/TestSmallPointerArray.cpp
@@ -14,70 +14,77 @@
 // switches to the storage method used for larger arrays.
 void TestArrayManipulation()
 {
   using namespace mozilla;
   SmallPointerArray<void> testArray;
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 0);
   MOZ_RELEASE_ASSERT(sizeof(testArray) == 2 * sizeof(void*));
+  MOZ_RELEASE_ASSERT(!testArray.Contains(PTR1));
 
   testArray.AppendElement(PTR1);
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 1);
   MOZ_RELEASE_ASSERT(testArray[0] == PTR1);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(0) == PTR1);
+  MOZ_RELEASE_ASSERT(testArray.Contains(PTR1));
 
   testArray.AppendElement(PTR2);
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 2);
   MOZ_RELEASE_ASSERT(testArray[0] == PTR1);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(0) == PTR1);
   MOZ_RELEASE_ASSERT(testArray[1] == PTR2);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(1) == PTR2);
+  MOZ_RELEASE_ASSERT(testArray.Contains(PTR2));
 
-  testArray.RemoveElement(PTR1);
+  MOZ_RELEASE_ASSERT(testArray.RemoveElement(PTR1));
+  MOZ_RELEASE_ASSERT(!testArray.RemoveElement(PTR1));
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 1);
   MOZ_RELEASE_ASSERT(testArray[0] == PTR2);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(0) == PTR2);
+  MOZ_RELEASE_ASSERT(!testArray.Contains(PTR1));
 
   testArray.AppendElement(PTR1);
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 2);
   MOZ_RELEASE_ASSERT(testArray[0] == PTR2);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(0) == PTR2);
   MOZ_RELEASE_ASSERT(testArray[1] == PTR1);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(1) == PTR1);
+  MOZ_RELEASE_ASSERT(testArray.Contains(PTR1));
 
   testArray.AppendElement(PTR3);
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 3);
   MOZ_RELEASE_ASSERT(testArray[0] == PTR2);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(0) == PTR2);
   MOZ_RELEASE_ASSERT(testArray[1] == PTR1);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(1) == PTR1);
   MOZ_RELEASE_ASSERT(testArray[2] == PTR3);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(2) == PTR3);
+  MOZ_RELEASE_ASSERT(testArray.Contains(PTR3));
 
-  testArray.RemoveElement(PTR1);
+  MOZ_RELEASE_ASSERT(testArray.RemoveElement(PTR1));
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 2);
   MOZ_RELEASE_ASSERT(testArray[0] == PTR2);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(0) == PTR2);
   MOZ_RELEASE_ASSERT(testArray[1] == PTR3);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(1) == PTR3);
 
-  testArray.RemoveElement(PTR2);
+  MOZ_RELEASE_ASSERT(testArray.RemoveElement(PTR2));
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 1);
   MOZ_RELEASE_ASSERT(testArray[0] == PTR3);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(0) == PTR3);
 
-  testArray.RemoveElement(PTR3);
+  MOZ_RELEASE_ASSERT(testArray.RemoveElement(PTR3));
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 0);
 
   testArray.Clear();
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 0);
 
   testArray.AppendElement(PTR1);
@@ -89,23 +96,23 @@ void TestArrayManipulation()
   testArray.AppendElement(PTR2);
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 2);
   MOZ_RELEASE_ASSERT(testArray[0] == PTR1);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(0) == PTR1);
   MOZ_RELEASE_ASSERT(testArray[1] == PTR2);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(1) == PTR2);
 
-  testArray.RemoveElement(PTR2);
+  MOZ_RELEASE_ASSERT(testArray.RemoveElement(PTR2));
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 1);
   MOZ_RELEASE_ASSERT(testArray[0] == PTR1);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(0) == PTR1);
 
-  testArray.RemoveElement(PTR3);
+  MOZ_RELEASE_ASSERT(!testArray.RemoveElement(PTR3));
 
   MOZ_RELEASE_ASSERT(testArray.Length() == 1);
   MOZ_RELEASE_ASSERT(testArray[0] == PTR1);
   MOZ_RELEASE_ASSERT(testArray.ElementAt(0) == PTR1);
 }
 
 void TestRangeBasedLoops()
 {
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -33,16 +33,17 @@ skip-if = os == 'b2g'  #Bug 1038197
 [TestPair]
 [TestPoisonArea]
 skip-if = os == 'android' # Bug 1147630
 [TestRefPtr]
 [TestRollingMean]
 [TestScopeExit]
 [TestSegmentedVector]
 [TestSHA1]
+[TestSmallPointerArray]
 [TestSaturate]
 [TestSplayTree]
 [TestSyncRunnable]
 [TestTemplateLib]
 [TestTuple]
 [TestTypeTraits]
 [TestTypedEnum]
 [TestUniquePtr]