You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-29 08:21:15 +03:00
Replace recursion with iteration in ParseTree (and some related walkers)
This commit is contained in:
@ -195,33 +195,102 @@ void ObjectReader::writeParseTree(const ParseTree* tree, messageqcpp::ByteStream
|
||||
return;
|
||||
}
|
||||
|
||||
b << (id_t)PARSETREE;
|
||||
writeParseTree(tree->left(), b);
|
||||
writeParseTree(tree->right(), b);
|
||||
|
||||
if (tree->data() == NULL)
|
||||
b << (id_t)NULL_CLASS;
|
||||
else
|
||||
tree->data()->serialize(b);
|
||||
DFSStack stack;
|
||||
stack.emplace_back(const_cast<ParseTree*>(tree));
|
||||
while (!stack.empty())
|
||||
{
|
||||
auto [node, dir] = stack.back();
|
||||
if (node == NULL)
|
||||
{
|
||||
b << (id_t)NULL_CLASS;
|
||||
stack.pop_back();
|
||||
continue;
|
||||
}
|
||||
if (dir == ParseTree::GoTo::Left)
|
||||
{
|
||||
b << (id_t)PARSETREE;
|
||||
stack.back().direction = ParseTree::GoTo::Right;
|
||||
stack.emplace_back(node->left());
|
||||
}
|
||||
else if (dir == ParseTree::GoTo::Right)
|
||||
{
|
||||
stack.back().direction = ParseTree::GoTo::Up;
|
||||
stack.emplace_back(node->right());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node->data() == NULL)
|
||||
b << (id_t)NULL_CLASS;
|
||||
else
|
||||
node->data()->serialize(b);
|
||||
stack.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParseTree* ObjectReader::createParseTree(messageqcpp::ByteStream& b)
|
||||
{
|
||||
CLASSID id = ZERO;
|
||||
ParseTree* ret;
|
||||
|
||||
DFSStack stack;
|
||||
b >> (id_t&)id;
|
||||
|
||||
if (id == NULL_CLASS)
|
||||
return NULL;
|
||||
|
||||
if (id != PARSETREE)
|
||||
throw UnserializeException("Not a ParseTree");
|
||||
|
||||
ret = new ParseTree();
|
||||
ret->left(createParseTree(b));
|
||||
ret->right(createParseTree(b));
|
||||
ret->data(createTreeNode(b));
|
||||
stack.emplace_back(ret);
|
||||
while (!stack.empty())
|
||||
{
|
||||
auto [node, dir] = stack.back();
|
||||
if (dir == ParseTree::GoTo::Left)
|
||||
{
|
||||
id = ZERO;
|
||||
ParseTree* cur = NULL;
|
||||
b >> (id_t&)id;
|
||||
|
||||
if (id == NULL_CLASS)
|
||||
{
|
||||
stack.back().node->left(cur);
|
||||
stack.back().direction = ParseTree::GoTo::Right;
|
||||
continue;
|
||||
}
|
||||
if (id != PARSETREE)
|
||||
throw UnserializeException("Not a ParseTree");
|
||||
|
||||
cur = new ParseTree();
|
||||
stack.back().direction = ParseTree::GoTo::Right;
|
||||
stack.back().node->left(cur);
|
||||
stack.emplace_back(node->left());
|
||||
}
|
||||
else if (dir == ParseTree::GoTo::Right)
|
||||
{
|
||||
id = ZERO;
|
||||
ParseTree* cur = NULL;
|
||||
b >> (id_t&)id;
|
||||
|
||||
if (id == NULL_CLASS)
|
||||
{
|
||||
stack.back().node->right(cur);
|
||||
stack.back().direction = ParseTree::GoTo::Up;
|
||||
continue;
|
||||
}
|
||||
if (id != PARSETREE)
|
||||
throw UnserializeException("Not a ParseTree");
|
||||
|
||||
cur = new ParseTree();
|
||||
stack.back().direction = ParseTree::GoTo::Up;
|
||||
stack.back().node->right(cur);
|
||||
stack.emplace_back(node->right());
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.back().node->data(createTreeNode(b));
|
||||
stack.pop_back();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user