PsTreeNodeWriter.cpp
// PsTreeNodeWriter.cpp
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2010
@import "PsTreeNodeWriter.h"
#include "Ceda/cxUtils/Tracer.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
// PsTreeNodeWriter
PsTreeNodeWriter::PsTreeNodeWriter(PsTreeNode* rootNode, bool seedFromClock, bool enableTrace) :
m_isaac(seedFromClock),
m_rootNode(rootNode),
m_enableTrace(enableTrace)
{
}
PsTreeNode* PsTreeNodeWriter::PickNode()
{
ceda::xvector<PsTreeNode*> nodes;
m_rootNode->GetAllNodes(nodes);
ceda::ssize_t i = m_isaac.GetUniformDistInteger_ssize_t(0,nodes.size());
cxAlwaysAssert(0 <= i && i < nodes.size());
return nodes[i];
}
void PsTreeNodeWriter::AddRandomNode(PsTreeNode* c)
{
PsTreeNode* p = PickNode();
cxAlwaysAssert(p);
ceda::ssize_t n = p->GetNumChildren();
ceda::ssize_t i = m_isaac.GetUniformDistInteger_ssize_t(0,n+1);
cxAlwaysAssert(0 <= i && i <= n);
p->AddChild(i,c);
p->ValidateChildren();
}
void PsTreeNodeWriter::DeleteRandomNode()
{
PsTreeNode* p = PickNode();
cxAlwaysAssert(p);
if (p != m_rootNode)
{
p->DeleteThisNode();
p->ValidateChildren();
}
}
void PsTreeNodeWriter::MoveRandomNode()
{
PsTreeNode* c = PickNode();
cxAlwaysAssert(c);
if (c != m_rootNode)
{
c->RemoveThisNode();
AddRandomNode(c);
}
}
void PsTreeNodeWriter::AddRandomAmount()
{
PsTreeNode* p = PickNode();
cxAlwaysAssert(p);
p->OffsetAmount( m_isaac.GetUniformDistInteger(0,100) );
}
void PsTreeNodeWriter::Run(ceda::ssize_t minOps, ceda::ssize_t maxOps)
{
ceda::TraceIndenter indent(2);
m_rootNode->CheckInvariant();
ceda::ssize_t n = m_isaac.GetUniformDistInteger_ssize_t(minOps,maxOps);
for (ceda::ssize_t k=0 ; k < n ; ++k)
{
int i = m_isaac.GetUniformDistInteger(0,4);
if (i == 0)
{
if (m_enableTrace)
{
Tracer() << "Adding node\n";
}
PsTreeNode* n = new PsTreeNode();
RegisterGcObject(n);
AddRandomNode(n);
}
else if (i == 1)
{
if (m_enableTrace)
{
Tracer() << "Deleting node\n";
}
DeleteRandomNode();
}
else if (i == 2)
{
if (m_enableTrace)
{
Tracer() << "Moving node\n";
}
MoveRandomNode();
}
else if (i == 3)
{
if (m_enableTrace)
{
Tracer() << "Adding amount\n";
}
AddRandomAmount();
}
else
{
break;
}
}
//m_rootNode->CheckInvariant();
if (m_enableTrace)
{
Tracer() << "Size of tree = " << m_rootNode->GetNumNodes() << '\n';
}
}