Bug 1372317 part 1 - Introduce a nsBaseHashtable::Lookup() method that allows modifying the value and optionally remove the entry. r=froydnj
authorMats Palmgren <mats@mozilla.com>
Sun, 18 Jun 2017 17:07:54 +0200
changeset 364619 55f418ab5447fe6dc29a7521c50ab4473bf1e34c
parent 364562 8c7dd6a9e9354565c209f77ec9720b76eae334b2
child 364620 ab565909b1d0e52c55a272251cb91d98ae8a36a8
push id32050
push usercbook@mozilla.com
push dateMon, 19 Jun 2017 11:37:33 +0000
treeherdermozilla-central@d39cd452b52b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1372317
milestone56.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 1372317 part 1 - Introduce a nsBaseHashtable::Lookup() method that allows modifying the value and optionally remove the entry. r=froydnj MozReview-Commit-ID: AcNBQvTMnX8
xpcom/ds/nsBaseHashtable.h
--- a/xpcom/ds/nsBaseHashtable.h
+++ b/xpcom/ds/nsBaseHashtable.h
@@ -189,16 +189,79 @@ public:
     bool shouldRemove = aFunction(ent->mData);
     MOZ_ASSERT(tableGeneration == GetGeneration(),
                "hashtable was modified by the LookupRemoveIf callback!");
     if (shouldRemove) {
       this->RemoveEntry(ent);
     }
   }
 
+  struct LookupResult {
+  private:
+    EntryType* mEntry;
+    nsBaseHashtable& mTable;
+#ifdef DEBUG
+    uint32_t mTableGeneration;
+#endif
+
+  public:
+    LookupResult(EntryType* aEntry, nsBaseHashtable& aTable)
+      : mEntry(aEntry)
+      , mTable(aTable)
+#ifdef DEBUG
+      , mTableGeneration(aTable.GetGeneration())
+#endif
+    {}
+
+    // Is there something stored in the table?
+    explicit operator bool() const
+    {
+      MOZ_ASSERT(mTableGeneration == mTable.GetGeneration());
+      return mEntry;
+    }
+
+    void Remove()
+    {
+      if (!*this) {
+        return;
+      }
+      mTable.RemoveEntry(mEntry);
+      mEntry = nullptr;
+    }
+
+    MOZ_MUST_USE DataType& Data()
+    {
+      MOZ_ASSERT(!!*this, "must have an entry to access its value");
+      return mEntry->mData;
+    }
+  };
+
+  /**
+   * Looks up aKey in the hashtable and returns an object that allows you to
+   * read/modify the value of the entry, or remove the entry (if found).
+   *
+   * A typical usage of this API looks like this:
+   *
+   *   if (auto entry = hashtable.Lookup(key)) {
+   *     DoSomething(entry.Data());
+   *     if (entry.Data() > 42) {
+   *       entry.Remove();
+   *     }
+   *   } // else - an entry with the given key doesn't exist
+   *
+   * This is useful for cases where you want to read/write the value of an entry
+   * and (optionally) remove the entry without having to do multiple hashtable
+   * lookups.  If you want to insert a new entry if one does not exist, then use
+   * LookupForAdd instead, see below.
+   */
+  MOZ_MUST_USE LookupResult Lookup(KeyType aKey)
+  {
+    return LookupResult(this->GetEntry(aKey), *this);
+  }
+
   struct EntryPtr {
   private:
     EntryType& mEntry;
     bool mExistingEntry;
     // For debugging purposes
 #ifdef DEBUG
     nsBaseHashtable& mTable;
     uint32_t mTableGeneration;