Bug 1170416 (part 2) - Merge PLDHashTable2 back into PLDHashTable. r=froydnj.

This commit is contained in:
Nicholas Nethercote 2015-06-02 01:58:58 -07:00
parent e34a80415d
commit c61daa7222
2 changed files with 44 additions and 100 deletions

View File

@ -202,13 +202,6 @@ MOZ_ALWAYS_INLINE void
PLDHashTable::Init(const PLDHashTableOps* aOps,
uint32_t aEntrySize, uint32_t aLength)
{
MOZ_ASSERT(!IsInitialized());
// Check that the important fields have been set by the constructor.
MOZ_ASSERT(mOps == nullptr);
MOZ_ASSERT(mRecursionLevel == 0);
MOZ_ASSERT(mEntryStore == nullptr);
if (aLength > PL_DHASH_MAX_INITIAL_LENGTH) {
MOZ_CRASH("Initial length is too large");
}
@ -243,14 +236,14 @@ PLDHashTable::Init(const PLDHashTableOps* aOps,
#endif
}
PLDHashTable2::PLDHashTable2(const PLDHashTableOps* aOps, uint32_t aEntrySize,
uint32_t aLength)
: PLDHashTable()
PLDHashTable::PLDHashTable(const PLDHashTableOps* aOps, uint32_t aEntrySize,
uint32_t aLength)
{
PLDHashTable::Init(aOps, aEntrySize, aLength);
Init(aOps, aEntrySize, aLength);
}
PLDHashTable& PLDHashTable::operator=(PLDHashTable&& aOther)
PLDHashTable&
PLDHashTable::operator=(PLDHashTable&& aOther)
{
if (this == &aOther) {
return *this;
@ -276,7 +269,6 @@ PLDHashTable& PLDHashTable::operator=(PLDHashTable&& aOther)
#endif
// Clear up |aOther| so its destruction will be a no-op.
aOther.mOps = nullptr;
aOther.mEntryStore = nullptr;
#ifdef DEBUG
aOther.mRecursionLevel = 0;
@ -324,8 +316,7 @@ PLDHashTable::EntryIsFree(PLDHashEntryHdr* aEntry)
MOZ_ALWAYS_INLINE void
PLDHashTable::Finish()
{
if (!IsInitialized()) {
MOZ_ASSERT(!mEntryStore);
if (!mEntryStore) {
return;
}
@ -343,8 +334,6 @@ PLDHashTable::Finish()
entryAddr += mEntrySize;
}
mOps = nullptr;
DECREMENT_RECURSION_LEVEL(this);
MOZ_ASSERT(RECURSION_LEVEL_SAFE_TO_FINISH(this));
@ -353,13 +342,13 @@ PLDHashTable::Finish()
mEntryStore = nullptr;
}
PLDHashTable2::~PLDHashTable2()
PLDHashTable::~PLDHashTable()
{
PLDHashTable::Finish();
Finish();
}
void
PLDHashTable2::ClearAndPrepareForLength(uint32_t aLength)
PLDHashTable::ClearAndPrepareForLength(uint32_t aLength)
{
MOZ_ASSERT(IsInitialized());
@ -367,12 +356,12 @@ PLDHashTable2::ClearAndPrepareForLength(uint32_t aLength)
const PLDHashTableOps* ops = mOps;
uint32_t entrySize = mEntrySize;
PLDHashTable::Finish();
PLDHashTable::Init(ops, entrySize, aLength);
Finish();
Init(ops, entrySize, aLength);
}
void
PLDHashTable2::Clear()
PLDHashTable::Clear()
{
ClearAndPrepareForLength(PL_DHASH_DEFAULT_INITIAL_LENGTH);
}
@ -993,7 +982,8 @@ PLDHashTable::Iterator::~Iterator()
DECREMENT_RECURSION_LEVEL(mTable);
}
bool PLDHashTable::Iterator::HasMoreEntries() const
bool
PLDHashTable::Iterator::HasMoreEntries() const
{
MOZ_ASSERT(mTable->IsInitialized());
@ -1004,7 +994,8 @@ bool PLDHashTable::Iterator::HasMoreEntries() const
return mEntryOffset < mTable->EntryCount();
}
PLDHashEntryHdr* PLDHashTable::Iterator::NextEntry()
PLDHashEntryHdr*
PLDHashTable::Iterator::NextEntry()
{
MOZ_ASSERT(HasMoreEntries());

View File

@ -161,8 +161,6 @@ typedef size_t (*PLDHashSizeOfEntryExcludingThisFun)(
*/
class PLDHashTable
{
friend class PLDHashTable2;
private:
const PLDHashTableOps* mOps; /* Virtual operations; see below. */
int16_t mHashShift; /* multiplicative hash shift */
@ -204,24 +202,16 @@ private:
#endif
public:
// The most important thing here is that we zero |mOps| because it's used to
// determine if Init() has been called. (The use of MOZ_CONSTEXPR means all
// the other members must be initialized too.)
MOZ_CONSTEXPR PLDHashTable()
: mOps(nullptr)
, mHashShift(0)
, mEntrySize(0)
, mEntryCount(0)
, mRemovedCount(0)
, mGeneration(0)
, mEntryStore(nullptr)
#ifdef PL_DHASHMETER
, mStats()
#endif
#ifdef DEBUG
, mRecursionLevel()
#endif
{}
// Initialize the table with |aOps| and |aEntrySize|. The table's initial
// capacity is chosen such that |aLength| elements can be inserted without
// rehashing; if |aLength| is a power-of-two, this capacity will be
// |2*length|. However, because entry storage is allocated lazily, this
// initial capacity won't be relevant until the first element is added; prior
// to that the capacity will be zero.
//
// This will crash if |aEntrySize| and/or |aLength| are too large.
PLDHashTable(const PLDHashTableOps* aOps, uint32_t aEntrySize,
uint32_t aLength = PL_DHASH_DEFAULT_INITIAL_LENGTH);
PLDHashTable(PLDHashTable&& aOther)
: mOps(nullptr)
@ -235,6 +225,8 @@ public:
PLDHashTable& operator=(PLDHashTable&& aOther);
~PLDHashTable();
bool IsInitialized() const { return !!mOps; }
// This should be used rarely.
@ -263,6 +255,20 @@ public:
uint32_t Enumerate(PLDHashEnumerator aEtor, void* aArg);
// This function is equivalent to
// ClearAndPrepareForLength(PL_DHASH_DEFAULT_INITIAL_LENGTH).
void Clear();
// This function clears the table's contents and frees its entry storage,
// leaving it in a empty state ready to be used again. Afterwards, when the
// first element is added the entry storage that gets allocated will have a
// capacity large enough to fit |aLength| elements without rehashing.
//
// It's conceptually the same as calling the destructor and then re-calling
// the constructor with the original |aOps| and |aEntrySize| arguments, and
// a new |aLength| argument.
void ClearAndPrepareForLength(uint32_t aLength);
size_t SizeOfIncludingThis(
PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr) const;
@ -335,61 +341,8 @@ private:
PLDHashTable& operator=(const PLDHashTable& aOther) = delete;
};
// PLDHashTable uses C style, manual initialization and finalization, via the
// Init() and Finish() methods. PLDHashTable2 is a slight extension of
// PLDHashTable that provides C++-style, automatic initialization and
// finalization via an initializing constructor and a destructor. It also
// overrides the Init() and Finish() methods with versions that will crash
// immediately if called.
//
// XXX: We're using a subclass here so that instances of PLDHashTable can be
// converted incrementally to PLDHashTable2. Once all instances have been
// converted, we can merge the two and call the merged class PLDHashTable
// again.
class PLDHashTable2 : public PLDHashTable
{
public:
// Initialize the table with |aOps| and |aEntrySize|. The table's initial
// capacity is chosen such that |aLength| elements can be inserted without
// rehashing; if |aLength| is a power-of-two, this capacity will be
// |2*length|. However, because entry storage is allocated lazily, this
// initial capacity won't be relevant until the first element is added; prior
// to that the capacity will be zero.
//
// This will crash if |aEntrySize| and/or |aLength| are too large.
PLDHashTable2(const PLDHashTableOps* aOps, uint32_t aEntrySize,
uint32_t aLength = PL_DHASH_DEFAULT_INITIAL_LENGTH);
PLDHashTable2(PLDHashTable2&& aOther)
: PLDHashTable(mozilla::Move(aOther))
{}
PLDHashTable2& operator=(PLDHashTable2&& aOther)
{
return static_cast<PLDHashTable2&>(
PLDHashTable::operator=(mozilla::Move(aOther)));
}
~PLDHashTable2();
// This function is equivalent to
// ClearAndPrepareForLength(PL_DHASH_DEFAULT_INITIAL_LENGTH).
void Clear();
// This function clears the table's contents and frees its entry storage,
// leaving it in a empty state ready to be used again. Afterwards, when the
// first element is added the entry storage that gets allocated will have a
// capacity large enough to fit |aLength| elements without rehashing.
//
// It's conceptually the same as calling the destructor and then re-calling
// the constructor with the original |aOps| and |aEntrySize| arguments, and
// a new |aLength| argument.
void ClearAndPrepareForLength(uint32_t aLength);
private:
PLDHashTable2(const PLDHashTable2& aOther) = delete;
PLDHashTable2& operator=(const PLDHashTable2& aOther) = delete;
};
// XXX: this is a temporary typedef that will be removed shortly.
typedef PLDHashTable PLDHashTable2;
/*
* Compute the hash code for a given key to be looked up, added, or removed