зеркало из https://github.com/mozilla/pjs.git
Fix for AIX build bustage. Unfortunately the compiler requires that if
a class includes other classes, then the other classes must be defined by the time the enclosing class is. In this case nsDST includes NodeArena, LeafNode & TwoNode and so therefore those classes must be defined in nsDST.h. r troy: Note, Troy didn't APPROVE of the fix (since it isn't pretty) but he has graciously allowed it in order to help AIX development. He did believe that it wouldn't hurt to put the change in.
This commit is contained in:
Родитель
98616e3d41
Коммит
165a7fafa6
|
@ -22,79 +22,11 @@
|
|||
#define PL_ARENA_CONST_ALIGN_MASK 3
|
||||
#include "nslayout.h"
|
||||
#include "nsDST.h"
|
||||
#include "plarena.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
#ifdef NS_DEBUG
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Classes that represents nodes in the DST
|
||||
|
||||
// To reduce the amount of memory we use there are two types of nodes:
|
||||
// - leaf nodes
|
||||
// - two nodes (left and right child)
|
||||
//
|
||||
// We distinguish the two types of nodes by looking at the low-order
|
||||
// bit of the key. If it is 0, then the node is a leaf node. If it is
|
||||
// 1, then the node is a two node. Use function Key() when retrieving
|
||||
// the key, and function IsLeaf() to tell what type of node it is
|
||||
//
|
||||
// It's an invariant of the tree that a two node can not have both child links
|
||||
// NULL. In that case it must be converted back to a leaf node
|
||||
|
||||
// Definition of NodeArena class
|
||||
class nsDST::NodeArena {
|
||||
public:
|
||||
NodeArena(PRUint32 aArenaSize);
|
||||
~NodeArena();
|
||||
|
||||
// Memory management functions
|
||||
void* AllocLeafNode();
|
||||
void* AllocTwoNode();
|
||||
void FreeNode(LeafNode*);
|
||||
void FreeNode(TwoNode*);
|
||||
void FreeArenaPool();
|
||||
|
||||
// Lifetime management functions
|
||||
void AddRef() {mRefCnt++;}
|
||||
void Release();
|
||||
PRBool IsShared() const {return mRefCnt > 1;}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
int NumArenas() const;
|
||||
PRUint32 ArenaSize() const {return mPool.arenasize;}
|
||||
#endif
|
||||
|
||||
private:
|
||||
PLArenaPool mPool;
|
||||
LeafNode* mLeafNodeFreeList;
|
||||
TwoNode* mTwoNodeFreeList;
|
||||
PRUint32 mRefCnt;
|
||||
};
|
||||
|
||||
// Definition of LeafNode class
|
||||
class nsDST::LeafNode {
|
||||
public:
|
||||
void* mKey;
|
||||
void* mValue;
|
||||
|
||||
// Constructors
|
||||
LeafNode(void* aKey, void* aValue);
|
||||
LeafNode(const LeafNode& aLeafNode);
|
||||
|
||||
// Accessor for getting the key. Clears the bit used to tell if the
|
||||
// node is a leaf. This function can be safely used on any node without
|
||||
// knowing whether it's a leaf or a two node
|
||||
void* Key() const {return (void*)(PtrBits(mKey) & ~0x1);}
|
||||
|
||||
// Helper function that returns TRUE if the node is a leaf
|
||||
int IsLeaf() const {return 0 == (PtrBits(mKey) & 0x1);}
|
||||
|
||||
// Overloaded placement operator for allocating from an arena
|
||||
void* operator new(size_t aSize, NodeArena* aArena) {return aArena->AllocLeafNode();}
|
||||
};
|
||||
|
||||
// Constructors
|
||||
inline nsDST::LeafNode::LeafNode(void* aKey, void* aValue)
|
||||
: mKey(aKey), mValue(aValue)
|
||||
|
@ -107,30 +39,9 @@ inline nsDST::LeafNode::LeafNode(const LeafNode& aNode)
|
|||
{
|
||||
}
|
||||
|
||||
// Definition of TwoNode class
|
||||
class nsDST::TwoNode : public nsDST::LeafNode {
|
||||
public:
|
||||
LeafNode* mLeft; // left subtree
|
||||
LeafNode* mRight; // right subtree
|
||||
|
||||
TwoNode(const LeafNode& aLeafNode);
|
||||
|
||||
void SetKeyAndValue(void* aKey, void* aValue) {
|
||||
mKey = (void*)(PtrBits(aKey) | 0x01);
|
||||
mValue = aValue;
|
||||
}
|
||||
|
||||
// Overloaded placement operator for allocating from an arena
|
||||
void* operator new(size_t aSize, NodeArena* aArena) {return aArena->AllocTwoNode();}
|
||||
|
||||
private:
|
||||
TwoNode(const TwoNode&); // no implementation
|
||||
void operator=(const TwoNode&); // no implementation
|
||||
};
|
||||
|
||||
// Constructor
|
||||
inline nsDST::TwoNode::TwoNode(const LeafNode& aLeafNode)
|
||||
: LeafNode((void*)(PtrBits(aLeafNode.mKey) | 0x1), aLeafNode.mValue),
|
||||
: nsDST::LeafNode((void*)(PtrBits(aLeafNode.mKey) | 0x1), aLeafNode.mValue),
|
||||
mLeft(0), mRight(0)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "plarena.h"
|
||||
|
||||
/**
|
||||
* Function-like object used when enumerating the nodes of the DST
|
||||
*/
|
||||
|
@ -52,6 +54,16 @@ public:
|
|||
* Digital search tree for doing a radix-search of pointer-based keys
|
||||
*/
|
||||
class nsDST {
|
||||
public:
|
||||
class NodeArena;
|
||||
friend class NodeArena;
|
||||
|
||||
private:
|
||||
class LeafNode;
|
||||
class TwoNode;
|
||||
friend class LeafNode;
|
||||
friend class TwoNode;
|
||||
|
||||
public:
|
||||
typedef unsigned long PtrBits;
|
||||
|
||||
|
@ -60,7 +72,34 @@ public:
|
|||
// Node arenas can be shared across DST objects (they don't lock when allocating
|
||||
// and freeing memory, so don't share them across threads). The DST object(s)
|
||||
// own the node arena, and you just hold a weak reference.
|
||||
class NodeArena;
|
||||
class NodeArena {
|
||||
public:
|
||||
NodeArena(PRUint32 aArenaSize);
|
||||
~NodeArena();
|
||||
|
||||
// Memory management functions
|
||||
void* AllocLeafNode();
|
||||
void* AllocTwoNode();
|
||||
void FreeNode(LeafNode*);
|
||||
void FreeNode(TwoNode*);
|
||||
void FreeArenaPool();
|
||||
|
||||
// Lifetime management functions
|
||||
void AddRef() {mRefCnt++;}
|
||||
void Release();
|
||||
PRBool IsShared() const {return mRefCnt > 1;}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
int NumArenas() const;
|
||||
PRUint32 ArenaSize() const {return mPool.arenasize;}
|
||||
#endif
|
||||
|
||||
private:
|
||||
PLArenaPool mPool;
|
||||
LeafNode* mLeafNodeFreeList;
|
||||
TwoNode* mTwoNodeFreeList;
|
||||
PRUint32 mRefCnt;
|
||||
};
|
||||
|
||||
// Create a DST. You specify the node arena to use; this allows the arena to
|
||||
// be shared.
|
||||
|
@ -85,11 +124,67 @@ public:
|
|||
static NodeArena* NewMemoryArena(PRUint32 aArenaSize = 512);
|
||||
|
||||
private:
|
||||
class LeafNode;
|
||||
class TwoNode;
|
||||
friend class LeafNode;
|
||||
friend class TwoNode;
|
||||
friend class NodeArena; // needs access to structs LeafNode and TwoNode
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Classes that represents nodes in the DST
|
||||
|
||||
// To reduce the amount of memory we use there are two types of nodes:
|
||||
// - leaf nodes
|
||||
// - two nodes (left and right child)
|
||||
//
|
||||
// We distinguish the two types of nodes by looking at the low-order
|
||||
// bit of the key. If it is 0, then the node is a leaf node. If it is
|
||||
// 1, then the node is a two node. Use function Key() when retrieving
|
||||
// the key, and function IsLeaf() to tell what type of node it is
|
||||
//
|
||||
// It's an invariant of the tree that a two node can not have both child links
|
||||
// NULL. In that case it must be converted back to a leaf node
|
||||
//
|
||||
// NOTE: This code was originally put into nsDST.cpp to reduce size
|
||||
// and to hide the implementation - See Troy's 1.10 revision.
|
||||
// However the AIX xlC 3.6.4.0 compiler does not allow this.
|
||||
|
||||
class LeafNode {
|
||||
public:
|
||||
void* mKey;
|
||||
void* mValue;
|
||||
|
||||
// Constructors
|
||||
LeafNode(void* aKey, void* aValue);
|
||||
LeafNode(const LeafNode& aLeafNode);
|
||||
|
||||
// Accessor for getting the key. Clears the bit used to tell if the
|
||||
// node is a leaf. This function can be safely used on any node without
|
||||
// knowing whether it's a leaf or a two node
|
||||
void* Key() const {return (void*)(PtrBits(mKey) & ~0x1);}
|
||||
|
||||
// Helper function that returns TRUE if the node is a leaf
|
||||
int IsLeaf() const {return 0 == (PtrBits(mKey) & 0x1);}
|
||||
|
||||
// Overloaded placement operator for allocating from an arena
|
||||
void* operator new(size_t aSize, NodeArena* aArena) {return aArena->AllocLeafNode();}
|
||||
};
|
||||
|
||||
// Definition of TwoNode class
|
||||
class TwoNode : public LeafNode {
|
||||
public:
|
||||
LeafNode* mLeft; // left subtree
|
||||
LeafNode* mRight; // right subtree
|
||||
|
||||
TwoNode(const LeafNode& aLeafNode);
|
||||
|
||||
void SetKeyAndValue(void* aKey, void* aValue) {
|
||||
mKey = (void*)(PtrBits(aKey) | 0x01);
|
||||
mValue = aValue;
|
||||
}
|
||||
|
||||
// Overloaded placement operator for allocating from an arena
|
||||
void* operator new(size_t aSize, NodeArena* aArena) {return aArena->AllocTwoNode();}
|
||||
|
||||
private:
|
||||
TwoNode(const TwoNode&); // no implementation
|
||||
void operator=(const TwoNode&); // no implementation
|
||||
};
|
||||
|
||||
LeafNode* mRoot; // root node of the tree
|
||||
NodeArena* mArena;
|
||||
|
|
Загрузка…
Ссылка в новой задаче