Fabric: Optimized ShadowNode::replaceChild() with `suggestedIndex` argument

Summary:
@public
In most cases callsite knows probable index of replacing child node, hence it makes sense to provide this info to `replaceChild` to illuminate O(n) search in most cases.

Reviewed By: mdvacca

Differential Revision: D8814809

fbshipit-source-id: 0edf82878a72260365e2757beb3886ad07c7464d
This commit is contained in:
Valentin Shergin 2018-07-17 22:41:32 -07:00 committed by Facebook Github Bot
parent e906d4cdc9
commit ec5b1fd259
5 changed files with 15 additions and 7 deletions

View File

@ -108,11 +108,11 @@ public:
}
}
LayoutableShadowNode *cloneAndReplaceChild(LayoutableShadowNode *child) override {
LayoutableShadowNode *cloneAndReplaceChild(LayoutableShadowNode *child, int suggestedIndex = -1) override {
ensureUnsealed();
auto childShadowNode = static_cast<const ConcreteViewShadowNode *>(child);
auto clonedChildShadowNode = std::static_pointer_cast<ConcreteViewShadowNode>(childShadowNode->clone());
ShadowNode::replaceChild(childShadowNode->shared_from_this(), clonedChildShadowNode);
ShadowNode::replaceChild(childShadowNode->shared_from_this(), clonedChildShadowNode, suggestedIndex);
return clonedChildShadowNode.get();
}

View File

@ -79,7 +79,7 @@ void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) {
auto childYogaNodeRawPtr = &child->yogaNode_;
if (childYogaNodeRawPtr->getOwner() != nullptr) {
child = static_cast<YogaLayoutableShadowNode *>(cloneAndReplaceChild(child));
child = static_cast<YogaLayoutableShadowNode *>(cloneAndReplaceChild(child, yogaNode_.getChildren().size()));
childYogaNodeRawPtr = &child->yogaNode_;
assert(childYogaNodeRawPtr->getOwner() == nullptr);
}
@ -154,7 +154,7 @@ YGNode *YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(YGNode *oldYoga
auto oldNode =
static_cast<YogaLayoutableShadowNode *>(oldYogaNode->getContext());
auto clonedNode =
static_cast<YogaLayoutableShadowNode *>(parentNode->cloneAndReplaceChild(oldNode));
static_cast<YogaLayoutableShadowNode *>(parentNode->cloneAndReplaceChild(oldNode, childIndex));
return &clonedNode->yogaNode_;
}

View File

@ -91,7 +91,7 @@ protected:
* In case layout algorithm needs to mutate this (probably sealed) node,
* it has to clone and replace it in the hierarchy before to do so.
*/
virtual LayoutableShadowNode *cloneAndReplaceChild(LayoutableShadowNode *child) = 0;
virtual LayoutableShadowNode *cloneAndReplaceChild(LayoutableShadowNode *child, int suggestedIndex = -1) = 0;
/*
* Sets layout metrics for the shadow node.

View File

@ -110,10 +110,18 @@ void ShadowNode::appendChild(const SharedShadowNode &child) {
nonConstChildren->push_back(child);
}
void ShadowNode::replaceChild(const SharedShadowNode &oldChild, const SharedShadowNode &newChild) {
void ShadowNode::replaceChild(const SharedShadowNode &oldChild, const SharedShadowNode &newChild, int suggestedIndex) {
ensureUnsealed();
auto nonConstChildren = std::const_pointer_cast<SharedShadowNodeList>(children_);
if (suggestedIndex != -1 && suggestedIndex < nonConstChildren->size()) {
if (nonConstChildren->at(suggestedIndex) == oldChild) {
(*nonConstChildren)[suggestedIndex] = newChild;
return;
}
}
std::replace(nonConstChildren->begin(), nonConstChildren->end(), oldChild, newChild);
}

View File

@ -93,7 +93,7 @@ public:
#pragma mark - Mutating Methods
void appendChild(const SharedShadowNode &child);
void replaceChild(const SharedShadowNode &oldChild, const SharedShadowNode &newChild);
void replaceChild(const SharedShadowNode &oldChild, const SharedShadowNode &newChild, int suggestedIndex = -1);
void clearSourceNode();
/*