|
|
|
@ -308,8 +308,7 @@ void DatasetNode::AddChild(std::shared_ptr<DatasetNode> child) {
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
Status DatasetNode::AppendChild(std::shared_ptr<DatasetNode> child) {
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(child != nullptr, "Node to append must not be a null pointer.");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(child->parent_ == nullptr, "Node to append must have no parent.");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(IsOrphanNode(child), "Node to append must be an orphan node.");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED((IsUnaryOperator() && Children().empty()) || IsNaryOperator(),
|
|
|
|
|
"This node must be a unary operator with no child or an n-ary operator");
|
|
|
|
|
children_.push_back(child);
|
|
|
|
@ -324,8 +323,7 @@ Status DatasetNode::AppendChild(std::shared_ptr<DatasetNode> child) {
|
|
|
|
|
*/
|
|
|
|
|
Status DatasetNode::InsertChildAt(int32_t pos, std::shared_ptr<DatasetNode> child) {
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(pos > -1 && pos <= children_.size(), "Position must in the range of [0, size]");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(child != nullptr, "Node to insert must not be a null pointer.");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(child->parent_ == nullptr, "Node to insert must have no parent.");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(IsOrphanNode(child), "Node to append must be an orphan node.");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED((IsUnaryOperator() && Children().empty()) || IsNaryOperator(),
|
|
|
|
|
"This node must be a unary operator with no child or an n-ary operator");
|
|
|
|
|
children_.insert(children_.begin() + pos, child);
|
|
|
|
@ -374,8 +372,7 @@ Status DatasetNode::InsertChildAt(int32_t pos, std::shared_ptr<DatasetNode> chil
|
|
|
|
|
* InsertAbove() cannot use on the root node of a tree.
|
|
|
|
|
*/
|
|
|
|
|
Status DatasetNode::InsertAbove(std::shared_ptr<DatasetNode> node) {
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(node != nullptr, "Node to insert must not be a null pointer.");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(node->parent_ == nullptr, "Node to insert must have no parent.");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(IsOrphanNode(node), "Node to insert must be an orphan node.");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(parent_ != nullptr, "This node must not be the root or a node without parent.");
|
|
|
|
|
auto parent = parent_;
|
|
|
|
|
|
|
|
|
@ -384,10 +381,10 @@ Status DatasetNode::InsertAbove(std::shared_ptr<DatasetNode> node) {
|
|
|
|
|
// 2. node->parent_ and node->children_
|
|
|
|
|
// 3. this->parent_
|
|
|
|
|
auto current_node_itr = std::find(parent_->children_.begin(), parent_->children_.end(), shared_from_this());
|
|
|
|
|
*current_node_itr = node;
|
|
|
|
|
node->parent_ = parent;
|
|
|
|
|
node->children_.push_back(shared_from_this());
|
|
|
|
|
parent_ = node.get();
|
|
|
|
|
*current_node_itr = node; // replace me in my parent's children list with the newly inserted node
|
|
|
|
|
node->parent_ = parent; // set the newly inserted node's parent ptr to my parent
|
|
|
|
|
node->children_.push_back(shared_from_this()); // add myself to the newly inserted node's children list
|
|
|
|
|
parent_ = node.get(); // set my parent ptr to the newly inserted node
|
|
|
|
|
|
|
|
|
|
return Status::OK();
|
|
|
|
|
}
|
|
|
|
@ -477,7 +474,29 @@ Status DatasetNode::InsertAbove(std::shared_ptr<DatasetNode> node) {
|
|
|
|
|
* | / \
|
|
|
|
|
* ds7 ds3 ds2
|
|
|
|
|
*
|
|
|
|
|
* Case 5: When the node has more than one child and more than one sibling, Drop() will raise an error.
|
|
|
|
|
* Case 5: When the node has only one child but has siblings, Drop() detaches the node from its tree and the node's
|
|
|
|
|
* children become its parent's children.
|
|
|
|
|
*
|
|
|
|
|
* Input tree:
|
|
|
|
|
* ds10
|
|
|
|
|
* / \
|
|
|
|
|
* ds9 ds6
|
|
|
|
|
* | / | \
|
|
|
|
|
* ds8 ds5 ds4 ds1
|
|
|
|
|
* | |
|
|
|
|
|
* ds7 ds3
|
|
|
|
|
*
|
|
|
|
|
* ds4->Drop() yields the tree below:
|
|
|
|
|
*
|
|
|
|
|
* ds10
|
|
|
|
|
* / \
|
|
|
|
|
* ds9 ds6
|
|
|
|
|
* | / | \
|
|
|
|
|
* ds8 ds5 ds3 ds1
|
|
|
|
|
* |
|
|
|
|
|
* ds7
|
|
|
|
|
*
|
|
|
|
|
* Case 6: When the node has more than one child and more than one sibling, Drop() will raise an error.
|
|
|
|
|
* If we want to drop ds4 from the input tree, ds4->Drop() will not work. We will have to do it
|
|
|
|
|
* with a combination of Drop(), InsertChildAt()
|
|
|
|
|
*
|
|
|
|
@ -507,8 +526,6 @@ Status DatasetNode::Drop() {
|
|
|
|
|
"Trying to drop an n-ary operator that is a child of a unary operator");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(!(children_.size() > 1 && parent_->children_.size() > 1),
|
|
|
|
|
"This node to drop must not have more than one child and more than one sibling.");
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(children_.size() == 0 || parent_->children_.size() == 1,
|
|
|
|
|
"If this node to drop has children, it must be its parent's only child.");
|
|
|
|
|
if (parent_->children_.size() == 1) {
|
|
|
|
|
auto parent = parent_;
|
|
|
|
|
// Case 2: When the node has one child and no sibling, Drop() detaches the node from its tree and the node's child
|
|
|
|
@ -547,6 +564,16 @@ Status DatasetNode::Drop() {
|
|
|
|
|
// And mark itself as an orphan
|
|
|
|
|
parent_ = nullptr;
|
|
|
|
|
children_.clear();
|
|
|
|
|
} else if (children_.size() == 1 && parent_->children_.size() > 1) {
|
|
|
|
|
// Case 5: When the node has only one child but has siblings, Drop() detaches the node from its tree and the node's
|
|
|
|
|
// children become its parent's children.
|
|
|
|
|
auto itr = std::find(parent_->children_.begin(), parent_->children_.end(), shared_from_this());
|
|
|
|
|
CHECK_FAIL_RETURN_UNEXPECTED(itr != parent_->children_.end(), "I am not in my parent's children list.");
|
|
|
|
|
*itr = children_[0]; // replace this node in its parent's children list with its single child
|
|
|
|
|
children_[0]->parent_ = parent_; // set its single child's parent ptr to its parent
|
|
|
|
|
// And mark itself as an orphan
|
|
|
|
|
parent_ = nullptr;
|
|
|
|
|
children_.clear();
|
|
|
|
|
} else {
|
|
|
|
|
RETURN_STATUS_UNEXPECTED("Internal error: we should not reach here.");
|
|
|
|
|
}
|
|
|
|
|