add guards to prevent runaway reaverageVoxels(), added stats to see if 4 children could be packed internally

This commit is contained in:
ZappoMan 2013-10-17 13:47:18 -07:00
parent d566026026
commit 8d7874b01b
5 changed files with 70 additions and 7 deletions

View file

@ -29,13 +29,20 @@ bool VoxelPersistThread::process() {
_initialLoad = true;
qDebug("loading voxels from file: %s...\n", _filename);
bool persistantFileRead = _tree->readFromSVOFile(_filename);
bool persistantFileRead;
{
PerformanceWarning warn(true, "Loading Voxel File", true);
persistantFileRead = _tree->readFromSVOFile(_filename);
}
if (persistantFileRead) {
PerformanceWarning warn(true, "reaverageVoxelColors()", true);
PerformanceWarning warn(true, "Voxels Re-Averaging", true);
// after done inserting all these voxels, then reaverage colors
qDebug("BEGIN Voxels Re-Averaging\n");
_tree->reaverageVoxelColors(_tree->rootNode);
qDebug("Voxels reAveraged\n");
qDebug("DONE WITH Voxels Re-Averaging\n");
}
_tree->clearDirtyBit(); // the tree is clean since we just loaded it

View file

@ -186,7 +186,7 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) {
mg_printf(connection, "%s", " ----------------\r\n");
mg_printf(connection, " Total: %10.llu nodes\r\n", checkSum);
mg_printf(connection, " Expected: %10.lu nodes\r\n", nodeCount);
mg_printf(connection, "%s", "\r\n");
mg_printf(connection, "%s", "VoxelNode Children Population Statistics...\r\n");
checkSum = 0;
@ -198,6 +198,13 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) {
mg_printf(connection, "%s", " ----------------\r\n");
mg_printf(connection, " Total: %10.llu nodes\r\n", checkSum);
mg_printf(connection, "%s", "\r\n");
mg_printf(connection, "%s", "In other news....\r\n");
mg_printf(connection, "could store 4 children internally: %10.llu nodes\r\n",
VoxelNode::getCouldStoreFourChildrenInternally());
mg_printf(connection, "could NOT store 4 children internally: %10.llu nodes\r\n",
VoxelNode::getCouldNotStoreFourChildrenInternally());
return 1;
} else {
// have mongoose process this request from the document_root

View file

@ -271,6 +271,8 @@ uint64_t VoxelNode::_threeChildrenOffsetCount = 0;
uint64_t VoxelNode::_threeChildrenExternalCount = 0;
uint64_t VoxelNode::_externalChildrenCount = 0;
uint64_t VoxelNode::_childrenCount[NUMBER_OF_CHILDREN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint64_t VoxelNode::_couldStoreFourChildrenInternally = 0;
uint64_t VoxelNode::_couldNotStoreFourChildrenInternally = 0;
VoxelNode* VoxelNode::getChildAtIndex(int childIndex) const {
PerformanceWarning warn(false,"getChildAtIndex",false,&_getChildAtIndexTime,&_getChildAtIndexCalls);
@ -531,6 +533,27 @@ void VoxelNode::retrieveThreeChildren(VoxelNode*& childOne, VoxelNode*& childTwo
_threeChildrenOffsetCount--;
}
}
void VoxelNode::checkStoreFourChildren(VoxelNode* childOne, VoxelNode* childTwo, VoxelNode* childThree, VoxelNode* childFour) {
int64_t offsetOne = (uint8_t*)childOne - (uint8_t*)this;
int64_t offsetTwo = (uint8_t*)childTwo - (uint8_t*)this;
int64_t offsetThree = (uint8_t*)childThree - (uint8_t*)this;
int64_t offsetFour = (uint8_t*)childFour - (uint8_t*)this;
const int64_t minOffset = std::numeric_limits<int16_t>::min();
const int64_t maxOffset = std::numeric_limits<int16_t>::max();
if (isBetween(offsetOne, maxOffset, minOffset) &&
isBetween(offsetTwo, maxOffset, minOffset) &&
isBetween(offsetThree, maxOffset, minOffset) &&
isBetween(offsetFour, maxOffset, minOffset)
) {
_couldStoreFourChildrenInternally++;
} else {
_couldNotStoreFourChildrenInternally++;
}
}
void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) {
PerformanceWarning warn(false,"setChildAtIndex",false,&_setChildAtIndexTime,&_setChildAtIndexCalls);
@ -750,7 +773,7 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) {
const int newChildCount = 4;
_children.external = new VoxelNode*[newChildCount];
_externalChildrenMemoryUsage += newChildCount * sizeof(VoxelNode*);
_children.external[0] = childOne;
_children.external[1] = childTwo;
_children.external[2] = childThree;
@ -866,6 +889,12 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) {
qDebug("THIS SHOULD NOT HAPPEN previousChildCount == %d && newChildCount == %d\n",previousChildCount, newChildCount);
}
// check to see if we could store these 4 children locally
if (getChildCount() == 4 && _childrenExternal && _children.external) {
checkStoreFourChildren(_children.external[0], _children.external[1], _children.external[2], _children.external[3]);
}
#ifdef HAS_AUDIT_CHILDREN
_childrenArray[childIndex] = child;
auditChildren("setChildAtIndex()");

View file

@ -131,7 +131,9 @@ public:
static uint64_t getThreeChildrenExternalCount() { return _threeChildrenExternalCount; }
static uint64_t getExternalChildrenCount() { return _externalChildrenCount; }
static uint64_t getChildrenCount(int childCount) { return _childrenCount[childCount]; }
static uint64_t getCouldStoreFourChildrenInternally() { return _couldStoreFourChildrenInternally; }
static uint64_t getCouldNotStoreFourChildrenInternally() { return _couldNotStoreFourChildrenInternally; }
#ifdef HAS_AUDIT_CHILDREN
void auditChildren(const char* label) const;
@ -145,6 +147,7 @@ private:
void retrieveThreeChildren(VoxelNode*& childOne, VoxelNode*& childTwo, VoxelNode*& childThree);
void decodeThreeOffsets(int64_t& offsetOne, int64_t& offsetTwo, int64_t& offsetThree) const;
void encodeThreeOffsets(int64_t offsetOne, int64_t offsetTwo, int64_t offsetThree);
void checkStoreFourChildren(VoxelNode* childOne, VoxelNode* childTwo, VoxelNode* childThree, VoxelNode* childFour);
void calculateAABox();
void init(unsigned char * octalCode);
@ -221,6 +224,9 @@ private:
static uint64_t _threeChildrenExternalCount;
static uint64_t _externalChildrenCount;
static uint64_t _childrenCount[NUMBER_OF_CHILDREN + 1];
static uint64_t _couldStoreFourChildrenInternally;
static uint64_t _couldNotStoreFourChildrenInternally;
};
#endif /* defined(__hifi__VoxelNode__) */

View file

@ -630,9 +630,22 @@ void VoxelTree::printTreeForDebugging(VoxelNode *startNode) {
}
// Note: this is an expensive call. Don't call it unless you really need to reaverage the entire tree (from startNode)
void VoxelTree::reaverageVoxelColors(VoxelNode *startNode) {
void VoxelTree::reaverageVoxelColors(VoxelNode* startNode) {
// if our tree is a reaveraging tree, then we do this, otherwise we don't do anything
if (_shouldReaverage) {
static int recursionCount;
if (startNode == rootNode) {
recursionCount = 0;
} else {
recursionCount++;
}
const int UNREASONABLY_DEEP_RECURSION = 20;
if (recursionCount > UNREASONABLY_DEEP_RECURSION) {
qDebug("VoxelTree::reaverageVoxelColors()... bailing out of UNREASONABLY_DEEP_RECURSION\n");
recursionCount--;
return;
}
bool hasChildren = false;
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
@ -647,6 +660,7 @@ void VoxelTree::reaverageVoxelColors(VoxelNode *startNode) {
if (hasChildren && !startNode->collapseIdenticalLeaves()) {
startNode->setColorFromAverageOfChildren();
}
recursionCount--;
}
}