mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 606080 - add SplayTree::LookupOrAdd r=froydnj
This commit is contained in:
parent
79b41494fa
commit
46d0164fdd
@ -13,6 +13,7 @@
|
||||
#define mozilla_SplayTree_h
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -55,7 +56,7 @@ class SplayTree
|
||||
T* mRoot;
|
||||
|
||||
public:
|
||||
SplayTree()
|
||||
MOZ_CONSTEXPR SplayTree()
|
||||
: mRoot(nullptr)
|
||||
{}
|
||||
|
||||
@ -86,15 +87,12 @@ public:
|
||||
T* last = lookup(*aValue);
|
||||
int cmp = Comparator::compare(*aValue, *last);
|
||||
|
||||
T** parentPointer = (cmp < 0) ? &last->mLeft : &last->mRight;
|
||||
MOZ_ASSERT(!*parentPointer);
|
||||
*parentPointer = aValue;
|
||||
aValue->mParent = last;
|
||||
|
||||
splay(aValue);
|
||||
finishInsertion(last, cmp, aValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
T* findOrInsert(const T& aValue);
|
||||
|
||||
T* remove(const T& aValue)
|
||||
{
|
||||
T* last = lookup(aValue);
|
||||
@ -196,6 +194,19 @@ private:
|
||||
return parent;
|
||||
}
|
||||
|
||||
T* finishInsertion(T* aLast, int32_t aCmp, T* aNew)
|
||||
{
|
||||
MOZ_ASSERT(aCmp, "Nodes shouldn't be equal!");
|
||||
|
||||
T** parentPointer = (aCmp < 0) ? &aLast->mLeft : &aLast->mRight;
|
||||
MOZ_ASSERT(!*parentPointer);
|
||||
*parentPointer = aNew;
|
||||
aNew->mParent = aLast;
|
||||
|
||||
splay(aNew);
|
||||
return aNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the tree until |node| is at the root of the tree. Performing
|
||||
* the rotations in this fashion preserves the amortized balancing of
|
||||
@ -295,6 +306,24 @@ private:
|
||||
void operator=(const SplayTree&) = delete;
|
||||
};
|
||||
|
||||
template<typename T, class Comparator>
|
||||
T*
|
||||
SplayTree<T, Comparator>::findOrInsert(const T& aValue)
|
||||
{
|
||||
if (!mRoot) {
|
||||
mRoot = new T(aValue);
|
||||
return mRoot;
|
||||
}
|
||||
|
||||
T* last = lookup(aValue);
|
||||
int cmp = Comparator::compare(aValue, *last);
|
||||
if (!cmp) {
|
||||
return last;
|
||||
}
|
||||
|
||||
return finishInsertion(last, cmp, new T(aValue));
|
||||
}
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif /* mozilla_SplayTree_h */
|
||||
|
@ -105,6 +105,16 @@ struct SplayInt : SplayTreeNode<SplayInt>
|
||||
int mValue;
|
||||
};
|
||||
|
||||
struct SplayNoCopy : SplayTreeNode<SplayNoCopy>
|
||||
{
|
||||
SplayNoCopy(const SplayNoCopy&) = delete;
|
||||
SplayNoCopy(SplayNoCopy&&) = delete;
|
||||
|
||||
static int compare(const SplayNoCopy&, const SplayNoCopy&) {}
|
||||
};
|
||||
|
||||
static SplayTree<SplayNoCopy, SplayNoCopy> testNoCopy;
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
@ -119,13 +129,47 @@ main()
|
||||
// Insert the values, and check each one is findable just after insertion.
|
||||
for (int i = 0; i < N; i++) {
|
||||
tree.insert(new SplayInt(gValues[i]));
|
||||
MOZ_RELEASE_ASSERT(tree.find(SplayInt(gValues[i])));
|
||||
SplayInt* inserted = tree.find(SplayInt(gValues[i]));
|
||||
MOZ_RELEASE_ASSERT(inserted);
|
||||
MOZ_RELEASE_ASSERT(tree.findOrInsert(SplayInt(gValues[i])) == inserted);
|
||||
tree.checkCoherency();
|
||||
}
|
||||
|
||||
// Check they're all findable after all insertions.
|
||||
for (int i = 0; i < N; i++) {
|
||||
MOZ_RELEASE_ASSERT(tree.find(SplayInt(gValues[i])));
|
||||
MOZ_RELEASE_ASSERT(tree.findOrInsert(SplayInt(gValues[i])));
|
||||
tree.checkCoherency();
|
||||
}
|
||||
|
||||
// Check that non-inserted values cannot be found.
|
||||
MOZ_RELEASE_ASSERT(!tree.find(SplayInt(-1)));
|
||||
MOZ_RELEASE_ASSERT(!tree.find(SplayInt(N)));
|
||||
MOZ_RELEASE_ASSERT(!tree.find(SplayInt(0x7fffffff)));
|
||||
|
||||
// Remove the values, and check each one is not findable just after removal.
|
||||
for (int i = 0; i < N; i++) {
|
||||
SplayInt* removed = tree.remove(SplayInt(gValues[i]));
|
||||
MOZ_RELEASE_ASSERT(removed->mValue == gValues[i]);
|
||||
MOZ_RELEASE_ASSERT(!tree.find(*removed));
|
||||
delete removed;
|
||||
tree.checkCoherency();
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(tree.empty());
|
||||
|
||||
// Insert the values, and check each one is findable just after insertion.
|
||||
for (int i = 0; i < N; i++) {
|
||||
SplayInt* inserted = tree.findOrInsert(SplayInt(gValues[i]));
|
||||
MOZ_RELEASE_ASSERT(tree.find(SplayInt(gValues[i])) == inserted);
|
||||
MOZ_RELEASE_ASSERT(tree.findOrInsert(SplayInt(gValues[i])) == inserted);
|
||||
tree.checkCoherency();
|
||||
}
|
||||
|
||||
// Check they're all findable after all insertions.
|
||||
for (int i = 0; i < N; i++) {
|
||||
MOZ_RELEASE_ASSERT(tree.find(SplayInt(gValues[i])));
|
||||
MOZ_RELEASE_ASSERT(tree.findOrInsert(SplayInt(gValues[i])));
|
||||
tree.checkCoherency();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user