Bug 1839051 - Use nsTArray::Sort in the SpanningCellSorter. r=xpcom-reviewers,emilio

We use stable sorting here as we want the order to not change unless really needed.

Depends on D181890

Differential Revision: https://phabricator.services.mozilla.com/D181891
This commit is contained in:
Jens Stutte 2023-12-04 18:33:41 +00:00
parent 2d1f3f0c2d
commit 3837ef18e3
2 changed files with 24 additions and 23 deletions

View File

@ -9,7 +9,7 @@
*/
#include "SpanningCellSorter.h"
#include "nsQuickSort.h"
#include "nsTArray.h"
#include "mozilla/HashFunctions.h"
using namespace mozilla;
@ -17,13 +17,11 @@ using namespace mozilla;
// #define DEBUG_SPANNING_CELL_SORTER
SpanningCellSorter::SpanningCellSorter()
: mState(ADDING),
mHashTable(&HashTableOps, sizeof(HashTableEntry)),
mSortedHashTable(nullptr) {
: mState(ADDING), mHashTable(&HashTableOps, sizeof(HashTableEntry)) {
memset(mArray, 0, sizeof(mArray));
}
SpanningCellSorter::~SpanningCellSorter() { delete[] mSortedHashTable; }
SpanningCellSorter::~SpanningCellSorter() = default;
/* static */ const PLDHashTableOps SpanningCellSorter::HashTableOps = {
HashTableHashKey, HashTableMatchEntry, PLDHashTable::MoveEntryStub,
@ -73,19 +71,20 @@ bool SpanningCellSorter::AddCell(int32_t aColSpan, int32_t aRow, int32_t aCol) {
return true;
}
/* static */
int SpanningCellSorter::SortArray(const void* a, const void* b, void* closure) {
int32_t spanA = (*static_cast<HashTableEntry* const*>(a))->mColSpan;
int32_t spanB = (*static_cast<HashTableEntry* const*>(b))->mColSpan;
if (spanA < spanB) return -1;
if (spanA == spanB) return 0;
return 1;
}
SpanningCellSorter::Item* SpanningCellSorter::GetNext(int32_t* aColSpan) {
NS_ASSERTION(mState != DONE, "done enumerating, stop calling");
// Our comparator needs the SpanningCellSorter private HashTableEntry
class HashTableEntryComparator {
public:
bool Equals(HashTableEntry* left, HashTableEntry* right) const {
return left->mColSpan == right->mColSpan;
}
bool LessThan(HashTableEntry* left, HashTableEntry* right) const {
return left->mColSpan < right->mColSpan;
}
};
switch (mState) {
case ADDING:
/* prepare to enumerate the array */
@ -112,14 +111,15 @@ SpanningCellSorter::Item* SpanningCellSorter::GetNext(int32_t* aColSpan) {
mState = ENUMERATING_HASH;
mEnumerationIndex = 0;
if (mHashTable.EntryCount() > 0) {
HashTableEntry** sh = new HashTableEntry*[mHashTable.EntryCount()];
int32_t j = 0;
// This clear is a no-op if the array is empty and it makes us
// resilient against re-entrance.
mSortedHashTable.ClearAndRetainStorage();
mSortedHashTable.SetCapacity(mHashTable.EntryCount());
for (auto iter = mHashTable.ConstIter(); !iter.Done(); iter.Next()) {
sh[j++] = static_cast<HashTableEntry*>(iter.Get());
mSortedHashTable.AppendElement(
static_cast<HashTableEntry*>(iter.Get()));
}
NS_QuickSort(sh, mHashTable.EntryCount(), sizeof(sh[0]), SortArray,
nullptr);
mSortedHashTable = sh;
mSortedHashTable.Sort(HashTableEntryComparator());
}
[[fallthrough]];
case ENUMERATING_HASH:

View File

@ -13,6 +13,7 @@
#include "PLDHashTable.h"
#include "nsDebug.h"
#include "nsTArray.h"
#include "StackArena.h"
/**
@ -73,11 +74,11 @@ class MOZ_STACK_CLASS SpanningCellSorter {
static PLDHashNumber HashTableHashKey(const void* key);
static bool HashTableMatchEntry(const PLDHashEntryHdr* hdr, const void* key);
static int SortArray(const void* a, const void* b, void* closure);
static int CompareHashTableEntry(HashTableEntry* a, HashTableEntry* b);
/* state used only during enumeration */
uint32_t mEnumerationIndex; // into mArray or mSortedHashTable
HashTableEntry** mSortedHashTable;
nsTArray<HashTableEntry*> mSortedHashTable;
/*
* operator new is forbidden since we use the pres shell's stack