Bug 1361745 - Part 1: Improve the nsClassHashtable::LookupForAdd() API; r=froydnj

The OrInsert() method adds the new entry to the hashtable if needed, and
returns the newly added entry or the pre-existing one.  It allows for a
more concise syntax at the call site.
This commit is contained in:
Ehsan Akhgari 2017-05-05 22:20:24 -04:00
Родитель 3a4ab7966c
Коммит 5de2ecd325
2 изменённых файлов: 16 добавлений и 24 удалений

Просмотреть файл

@ -730,7 +730,9 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObser
return NS_OK;
}
mObservers.Insert(p, pCallback);
p.OrInsert([&pCallback]() {
return pCallback;
});
// We must pass a fully qualified preference name to the callback
// aDomain == nullptr is the only possible failure, and we trapped it with

Просмотреть файл

@ -99,18 +99,14 @@ public:
return !!mEntry.mData;
}
T& operator*()
template <class F>
T* OrInsert(F func)
{
MOZ_ASSERT(mEntry.mData);
MOZ_ASSERT(mTableGeneration == mTable.GetGeneration());
return *mEntry.mData;
}
void TakeOwnership(T* aPtr)
{
MOZ_ASSERT(!mEntry.mData);
MOZ_ASSERT(mTableGeneration == mTable.GetGeneration());
mEntry.mData = aPtr;
if (!mEntry.mData) {
mEntry.mData = func();
}
return mEntry.mData;
}
};
@ -121,23 +117,25 @@ public:
*
* A typical usage of this API looks like this:
*
* auto insertedValue = table.LookupForAdd(key).OrInsert([]() {
* return newValue;
* });
*
* auto p = table.LookupForAdd(key);
* if (p) {
* // The entry already existed in the table.
* Use(*p);
* DoSomething();
* } else {
* // An existing entry wasn't found, store a new entry in the hashtable.
* table.Insert(p, newValue);
* p.OrInsert([]() { return newValue; });
* }
*
* We ensure that the hashtable isn't modified before Insert() is called.
* We ensure that the hashtable isn't modified before OrInsert() is called.
* This is useful for cases where you want to insert a new entry into the
* hashtable if one doesn't exist before but would like to avoid two hashtable
* lookups.
*/
MOZ_MUST_USE EntryPtr LookupForAdd(KeyType aKey);
void Insert(EntryPtr& aEntryPtr, T* aPtr);
};
//
@ -165,14 +163,6 @@ nsClassHashtable<KeyClass, T>::LookupForAdd(KeyType aKey)
return EntryPtr(*this, ent);
}
template<class KeyClass, class T>
void
nsClassHashtable<KeyClass, T>::Insert(typename nsClassHashtable<KeyClass, T>::EntryPtr& aEntryPtr,
T* aPtr)
{
aEntryPtr.TakeOwnership(aPtr);
}
template<class KeyClass, class T>
bool
nsClassHashtable<KeyClass, T>::Get(KeyType aKey, T** aRetVal) const