forked from mirrors/gecko-dev
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:
parent
40e261a3cf
commit
9e14278425
2 changed files with 24 additions and 23 deletions
|
|
@ -9,7 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SpanningCellSorter.h"
|
#include "SpanningCellSorter.h"
|
||||||
#include "nsQuickSort.h"
|
#include "nsTArray.h"
|
||||||
#include "mozilla/HashFunctions.h"
|
#include "mozilla/HashFunctions.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
@ -17,13 +17,11 @@ using namespace mozilla;
|
||||||
// #define DEBUG_SPANNING_CELL_SORTER
|
// #define DEBUG_SPANNING_CELL_SORTER
|
||||||
|
|
||||||
SpanningCellSorter::SpanningCellSorter()
|
SpanningCellSorter::SpanningCellSorter()
|
||||||
: mState(ADDING),
|
: mState(ADDING), mHashTable(&HashTableOps, sizeof(HashTableEntry)) {
|
||||||
mHashTable(&HashTableOps, sizeof(HashTableEntry)),
|
|
||||||
mSortedHashTable(nullptr) {
|
|
||||||
memset(mArray, 0, sizeof(mArray));
|
memset(mArray, 0, sizeof(mArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
SpanningCellSorter::~SpanningCellSorter() { delete[] mSortedHashTable; }
|
SpanningCellSorter::~SpanningCellSorter() = default;
|
||||||
|
|
||||||
/* static */ const PLDHashTableOps SpanningCellSorter::HashTableOps = {
|
/* static */ const PLDHashTableOps SpanningCellSorter::HashTableOps = {
|
||||||
HashTableHashKey, HashTableMatchEntry, PLDHashTable::MoveEntryStub,
|
HashTableHashKey, HashTableMatchEntry, PLDHashTable::MoveEntryStub,
|
||||||
|
|
@ -73,19 +71,20 @@ bool SpanningCellSorter::AddCell(int32_t aColSpan, int32_t aRow, int32_t aCol) {
|
||||||
return true;
|
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) {
|
SpanningCellSorter::Item* SpanningCellSorter::GetNext(int32_t* aColSpan) {
|
||||||
NS_ASSERTION(mState != DONE, "done enumerating, stop calling");
|
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) {
|
switch (mState) {
|
||||||
case ADDING:
|
case ADDING:
|
||||||
/* prepare to enumerate the array */
|
/* prepare to enumerate the array */
|
||||||
|
|
@ -112,14 +111,15 @@ SpanningCellSorter::Item* SpanningCellSorter::GetNext(int32_t* aColSpan) {
|
||||||
mState = ENUMERATING_HASH;
|
mState = ENUMERATING_HASH;
|
||||||
mEnumerationIndex = 0;
|
mEnumerationIndex = 0;
|
||||||
if (mHashTable.EntryCount() > 0) {
|
if (mHashTable.EntryCount() > 0) {
|
||||||
HashTableEntry** sh = new HashTableEntry*[mHashTable.EntryCount()];
|
// This clear is a no-op if the array is empty and it makes us
|
||||||
int32_t j = 0;
|
// resilient against re-entrance.
|
||||||
|
mSortedHashTable.ClearAndRetainStorage();
|
||||||
|
mSortedHashTable.SetCapacity(mHashTable.EntryCount());
|
||||||
for (auto iter = mHashTable.ConstIter(); !iter.Done(); iter.Next()) {
|
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,
|
mSortedHashTable.Sort(HashTableEntryComparator());
|
||||||
nullptr);
|
|
||||||
mSortedHashTable = sh;
|
|
||||||
}
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ENUMERATING_HASH:
|
case ENUMERATING_HASH:
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "PLDHashTable.h"
|
#include "PLDHashTable.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
#include "StackArena.h"
|
#include "StackArena.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,11 +74,11 @@ class MOZ_STACK_CLASS SpanningCellSorter {
|
||||||
static PLDHashNumber HashTableHashKey(const void* key);
|
static PLDHashNumber HashTableHashKey(const void* key);
|
||||||
static bool HashTableMatchEntry(const PLDHashEntryHdr* hdr, 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 */
|
/* state used only during enumeration */
|
||||||
uint32_t mEnumerationIndex; // into mArray or mSortedHashTable
|
uint32_t mEnumerationIndex; // into mArray or mSortedHashTable
|
||||||
HashTableEntry** mSortedHashTable;
|
nsTArray<HashTableEntry*> mSortedHashTable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* operator new is forbidden since we use the pres shell's stack
|
* operator new is forbidden since we use the pres shell's stack
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue