Bug 906918 - Use MoveRef's in nsTHashtable. r=bsmedberg

This patch adds a move constructor for nsTHashtable and also lets
nsTHashtable use its EntryType's move constructor, if one is available.

This patch also adds move constructors for nsCharPtrHashKey and
nsUnicharPtrHashKey.  Using these new constructors, nsTHashtable will be
able to avoid strdup()'ing all of its keys whenever it resizes the
table.
This commit is contained in:
Justin Lebar 2013-08-20 09:08:00 -07:00
parent c6732ba0b0
commit 05a66409ca
2 changed files with 34 additions and 4 deletions

View File

@ -22,6 +22,7 @@
#include <string.h>
#include "mozilla/HashFunctions.h"
#include "mozilla/Move.h"
namespace mozilla {
@ -471,6 +472,13 @@ public:
nsCharPtrHashKey(const char* aKey) : mKey(strdup(aKey)) { }
nsCharPtrHashKey(const nsCharPtrHashKey& toCopy) : mKey(strdup(toCopy.mKey)) { }
nsCharPtrHashKey(mozilla::MoveRef<nsCharPtrHashKey> other)
: mKey(other->mKey)
{
other->mKey = nullptr;
}
~nsCharPtrHashKey() { if (mKey) free(const_cast<char *>(mKey)); }
const char* GetKey() const { return mKey; }
@ -501,6 +509,13 @@ public:
nsUnicharPtrHashKey(const PRUnichar* aKey) : mKey(NS_strdup(aKey)) { }
nsUnicharPtrHashKey(const nsUnicharPtrHashKey& toCopy) : mKey(NS_strdup(toCopy.mKey)) { }
nsUnicharPtrHashKey(mozilla::MoveRef<nsUnicharPtrHashKey> other)
: mKey(other->mKey)
{
other->mKey = nullptr;
}
~nsUnicharPtrHashKey() { if (mKey) NS_Free(const_cast<PRUnichar *>(mKey)); }
const PRUnichar* GetKey() const { return mKey; }

View File

@ -11,6 +11,7 @@
#include "nsDebug.h"
#include <new>
#include "mozilla/MemoryReporting.h"
#include "mozilla/Move.h"
#include "mozilla/fallible.h"
// helper function for nsTHashtable::Clear()
@ -45,9 +46,10 @@ PL_DHashStubEnumRemove(PLDHashTable *table,
*
* EntryType(KeyTypePointer aKey);
*
* // the copy constructor must be defined, even if AllowMemMove() == true
* // or you will cause link errors!
* EntryType(const EntryType& aEnt);
* // A copy or move constructor must be defined, even if AllowMemMove() ==
* // true, otherwise you will cause link errors.
* EntryType(const EntryType& aEnt); // Either this...
* EntryType(MoveRef<EntryType> aEnt); // ...or this
*
* // the destructor must be defined... or you will cause link errors!
* ~EntryType();
@ -88,6 +90,8 @@ public:
*/
~nsTHashtable();
nsTHashtable(mozilla::MoveRef<nsTHashtable<EntryType> > aOther);
/**
* Initialize the table. This function must be called before any other
* class operations. This can fail due to OOM conditions.
@ -378,6 +382,15 @@ nsTHashtable<EntryType>::nsTHashtable()
mTable.entrySize = 0;
}
template<class EntryType>
nsTHashtable<EntryType>::nsTHashtable(
mozilla::MoveRef<nsTHashtable<EntryType> > aOther)
: mTable(aOther->mTable)
{
aOther->mTable = PLDHashTable();
aOther->mTable.entrySize = 0;
}
template<class EntryType>
nsTHashtable<EntryType>::~nsTHashtable()
{
@ -448,10 +461,12 @@ nsTHashtable<EntryType>::s_CopyEntry(PLDHashTable *table,
const PLDHashEntryHdr *from,
PLDHashEntryHdr *to)
{
using mozilla::Move;
EntryType* fromEntry =
const_cast<EntryType*>(reinterpret_cast<const EntryType*>(from));
new(to) EntryType(*fromEntry);
new(to) EntryType(Move(*fromEntry));
fromEntry->~EntryType();
}