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(); ensureUnsealed();
auto childShadowNode = static_cast<const ConcreteViewShadowNode *>(child); auto childShadowNode = static_cast<const ConcreteViewShadowNode *>(child);
auto clonedChildShadowNode = std::static_pointer_cast<ConcreteViewShadowNode>(childShadowNode->clone()); 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(); return clonedChildShadowNode.get();
} }

View File

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

View File

@ -91,7 +91,7 @@ protected:
* In case layout algorithm needs to mutate this (probably sealed) node, * 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. * 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. * Sets layout metrics for the shadow node.

View File

@ -110,10 +110,18 @@ void ShadowNode::appendChild(const SharedShadowNode &child) {
nonConstChildren->push_back(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(); ensureUnsealed();
auto nonConstChildren = std::const_pointer_cast<SharedShadowNodeList>(children_); 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); std::replace(nonConstChildren->begin(), nonConstChildren->end(), oldChild, newChild);
} }

View File

@ -93,7 +93,7 @@ public:
#pragma mark - Mutating Methods #pragma mark - Mutating Methods
void appendChild(const SharedShadowNode &child); 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(); void clearSourceNode();
/* /*