Skip to content

Commit 8212646

Browse files
authored
[swift-api-digester] caching the equality comparison results among SDKNodes. (#5297)
During the lifetime of analysing source-breaking changes, we may compare the equality of two SDKNodes more than once, which makes the comprison results amenable for caching. This patch implemented it. NFC
1 parent e250960 commit 8212646

File tree

1 file changed

+36
-8
lines changed

1 file changed

+36
-8
lines changed

tools/swift-api-digester/swift-api-digester.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -808,17 +808,45 @@ NodeUniquePtr SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) {
808808
return Result;
809809
}
810810

811+
/// This is for caching the comparison results between two SDKNodes.
812+
class SDKNodeEqualContext {
813+
using NodePtrAndEqual = llvm::DenseMap<const SDKNode*, bool>;
814+
llvm::DenseMap<const SDKNode*, llvm::DenseMap<const SDKNode*, bool>> Data;
815+
816+
public:
817+
Optional<bool> getEquality(const SDKNode* Left, const SDKNode* Right) {
818+
auto &Map = Data.insert({Left, NodePtrAndEqual()}).first->getSecond();
819+
if (Map.count(Right))
820+
return Map[Right];
821+
return None;
822+
}
823+
824+
void addEquality(const SDKNode* Left, const SDKNode* Right, const bool Value) {
825+
Data.insert(std::make_pair(Left, NodePtrAndEqual())).first->getSecond().
826+
insert({Right, Value});
827+
}
828+
};
829+
811830
bool SDKNode::operator==(const SDKNode &Other) const {
831+
static SDKNodeEqualContext EqualCache;
832+
if (auto Cached = EqualCache.getEquality(this, &Other)) {
833+
return Cached.getValue();
834+
}
835+
auto Exit = [&](const bool Result) {
836+
EqualCache.addEquality(this, &Other, Result);
837+
return Result;
838+
};
839+
812840
if (getKind() != Other.getKind())
813-
return false;
841+
return Exit(false);
814842

815843
switch(getKind()) {
816844
case SDKNodeKind::TypeNominal:
817845
case SDKNodeKind::TypeFunc: {
818846
auto Left = this->getAs<SDKNodeType>();
819847
auto Right = (&Other)->getAs<SDKNodeType>();
820-
return Left->getTypeAttributes().equals(Right->getTypeAttributes())
821-
&& Left->getPrintedName() == Right->getPrintedName();
848+
return Exit(Left->getTypeAttributes().equals(Right->getTypeAttributes())
849+
&& Left->getPrintedName() == Right->getPrintedName());
822850
}
823851

824852
case SDKNodeKind::Function:
@@ -828,9 +856,9 @@ bool SDKNode::operator==(const SDKNode &Other) const {
828856
auto Left = this->getAs<SDKNodeAbstractFunc>();
829857
auto Right = (&Other)->getAs<SDKNodeAbstractFunc>();
830858
if (Left->isMutating() ^ Right->isMutating())
831-
return false;
859+
return Exit(false);
832860
if (Left->isThrowing() ^ Right->isThrowing())
833-
return false;
861+
return Exit(false);
834862
SWIFT_FALLTHROUGH;
835863
}
836864
case SDKNodeKind::TypeDecl:
@@ -842,11 +870,11 @@ bool SDKNode::operator==(const SDKNode &Other) const {
842870
Children.size() == Other.Children.size()) {
843871
for (unsigned I = 0; I < Children.size(); ++ I) {
844872
if (*Children[I] != *Other.Children[I])
845-
return false;
873+
return Exit(false);
846874
}
847-
return true;
875+
return Exit(true);
848876
}
849-
return false;
877+
return Exit(false);
850878
}
851879
}
852880
}

0 commit comments

Comments
 (0)