MAINT-646: Factor std::set out of lloctree https://bitbucket.org/davep/viewer-development/changeset/52b6c9168974
This commit is contained in:
@@ -89,9 +89,9 @@ public:
|
||||
|
||||
typedef LLOctreeTraveler<T> oct_traveler;
|
||||
typedef LLTreeTraveler<T> tree_traveler;
|
||||
typedef typename std::set<LLPointer<T> > element_list;
|
||||
typedef typename element_list::iterator element_iter;
|
||||
typedef typename element_list::const_iterator const_element_iter;
|
||||
typedef LLPointer<T>* element_list;
|
||||
typedef LLPointer<T>* element_iter;
|
||||
typedef const LLPointer<T>* const_element_iter;
|
||||
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
|
||||
typedef typename std::vector<LLOctreeNode<T>* > child_list;
|
||||
typedef LLTreeNode<T> BaseType;
|
||||
@@ -115,6 +115,9 @@ public:
|
||||
: mParent((oct_node*)parent),
|
||||
mOctant(octant)
|
||||
{
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
|
||||
mCenter = center;
|
||||
mSize = size;
|
||||
|
||||
@@ -133,6 +136,16 @@ public:
|
||||
{
|
||||
BaseType::destroyListeners();
|
||||
|
||||
for (U32 i = 0; i < mElementCount; ++i)
|
||||
{
|
||||
mData[i]->setBinIndex(-1);
|
||||
mData[i] = NULL;
|
||||
}
|
||||
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
|
||||
for (U32 i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
delete getChild(i);
|
||||
@@ -232,9 +245,14 @@ public:
|
||||
virtual bool isLeaf() const { return mChild.empty(); }
|
||||
|
||||
U32 getElementCount() const { return mElementCount; }
|
||||
bool isEmpty() const { return mElementCount == 0; }
|
||||
element_list& getData() { return mData; }
|
||||
const element_list& getData() const { return mData; }
|
||||
|
||||
element_iter getDataBegin() { return mData; }
|
||||
element_iter getDataEnd() { return mDataEnd; }
|
||||
const_element_iter getDataBegin() const { return mData; }
|
||||
const_element_iter getDataEnd() const { return mDataEnd; }
|
||||
|
||||
U32 getChildCount() const { return mChildCount; }
|
||||
oct_node* getChild(U32 index) { return mChild[index]; }
|
||||
const oct_node* getChild(U32 index) const { return mChild[index]; }
|
||||
@@ -299,7 +317,7 @@ public:
|
||||
|
||||
virtual bool insert(T* data)
|
||||
{
|
||||
if (data == NULL)
|
||||
if (data == NULL || data->getBinIndex() != -1)
|
||||
{
|
||||
OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl;
|
||||
return false;
|
||||
@@ -309,22 +327,19 @@ public:
|
||||
//is it here?
|
||||
if (isInside(data->getPositionGroup()))
|
||||
{
|
||||
if (((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius())) ||
|
||||
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
|
||||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
|
||||
{ //it belongs here
|
||||
#if LL_OCTREE_PARANOIA_CHECK
|
||||
//if this is a redundant insertion, error out (should never happen)
|
||||
if (mData.find(data) != mData.end())
|
||||
{
|
||||
llwarns << "Redundant octree insertion detected. " << data << llendl;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
mElementCount++;
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
|
||||
mData.insert(data);
|
||||
//avoid unref on uninitialized memory
|
||||
memset(mData+mElementCount-1, 0, sizeof(LLPointer<T>));
|
||||
|
||||
mData[mElementCount-1] = data;
|
||||
mDataEnd = mData + mElementCount;
|
||||
data->setBinIndex(mElementCount-1);
|
||||
BaseType::insert(data);
|
||||
|
||||
mElementCount = mData.size();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -358,10 +373,16 @@ public:
|
||||
|
||||
if( lt == 0x7 )
|
||||
{
|
||||
mData.insert(data);
|
||||
BaseType::insert(data);
|
||||
mElementCount++;
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
|
||||
mElementCount = mData.size();
|
||||
//avoid unref on uninitialized memory
|
||||
memset(mData+mElementCount-1, 0, sizeof(LLPointer<T>));
|
||||
|
||||
mData[mElementCount-1] = data;
|
||||
mDataEnd = mData + mElementCount;
|
||||
data->setBinIndex(mElementCount-1);
|
||||
BaseType::insert(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -410,23 +431,59 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void _remove(T* data, S32 i)
|
||||
{ //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
|
||||
|
||||
mElementCount--;
|
||||
data->setBinIndex(-1);
|
||||
|
||||
if (mElementCount > 0)
|
||||
{
|
||||
if (mElementCount != i)
|
||||
{
|
||||
mData[i] = mData[mElementCount]; //might unref data, do not access data after this point
|
||||
mData[i]->setBinIndex(i);
|
||||
}
|
||||
|
||||
mData[mElementCount] = NULL; //needed for unref
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
mDataEnd = mData+mElementCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
mData[0] = NULL; //needed for unref
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
}
|
||||
|
||||
notifyRemoval(data);
|
||||
checkAlive();
|
||||
}
|
||||
|
||||
bool remove(T* data)
|
||||
{
|
||||
if (mData.find(data) != mData.end())
|
||||
{ //we have data
|
||||
mData.erase(data);
|
||||
mElementCount = mData.size();
|
||||
this->notifyRemoval(data);
|
||||
checkAlive();
|
||||
return true;
|
||||
S32 i = data->getBinIndex();
|
||||
|
||||
if (i >= 0 && i < (S32)mElementCount)
|
||||
{
|
||||
if (mData[i] == data)
|
||||
{ //found it
|
||||
_remove(data, i);
|
||||
llassert(data->getBinIndex() == -1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (isInside(data))
|
||||
|
||||
if (isInside(data))
|
||||
{
|
||||
oct_node* dest = getNodeAt(data);
|
||||
|
||||
if (dest != this)
|
||||
{
|
||||
return dest->remove(data);
|
||||
bool ret = dest->remove(data);
|
||||
llassert(data->getBinIndex() == -1);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,19 +502,20 @@ public:
|
||||
//node is now root
|
||||
llwarns << "!!! OCTREE REMOVING FACE BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << llendl;
|
||||
node->removeByAddress(data);
|
||||
llassert(data->getBinIndex() == -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void removeByAddress(T* data)
|
||||
{
|
||||
if (mData.find(data) != mData.end())
|
||||
for (U32 i = 0; i < mElementCount; ++i)
|
||||
{
|
||||
mData.erase(data);
|
||||
mElementCount = mData.size();
|
||||
this->notifyRemoval(data);
|
||||
llwarns << "FOUND!" << llendl;
|
||||
checkAlive();
|
||||
return;
|
||||
if (mData[i] == data)
|
||||
{ //we have data
|
||||
_remove(data, i);
|
||||
llwarns << "FOUND!" << llendl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < getChildCount(); i++)
|
||||
@@ -624,6 +682,7 @@ protected:
|
||||
U32 mChildCount;
|
||||
|
||||
element_list mData;
|
||||
element_iter mDataEnd;
|
||||
U32 mElementCount;
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user