Skip to content

[Support] Set SuffixIdx and ConcatLen during node insertion #144467

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions llvm/include/llvm/Support/SuffixTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,6 @@ class SuffixTree {
/// \returns A pointer to the root.
SuffixTreeInternalNode *insertRoot();

/// Set the suffix indices of the leaves to the start indices of their
/// respective suffixes.
void setSuffixIndices();

/// Construct the suffix tree for the prefix of the input ending at
/// \p EndIdx.
///
Expand Down
39 changes: 8 additions & 31 deletions llvm/lib/Support/SuffixTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ SuffixTree::SuffixTree(const ArrayRef<unsigned> &Str,
SuffixesToAdd = extend(PfxEndIdx, SuffixesToAdd);
}

// Set the suffix indices of each leaf.
assert(Root && "Root node can't be nullptr!");
setSuffixIndices();

// Collect all leaf nodes of the suffix tree. And for each internal node,
// record the range of leaf nodes that are descendants of it.
Expand All @@ -60,6 +58,9 @@ SuffixTreeNode *SuffixTree::insertLeaf(SuffixTreeInternalNode &Parent,
assert(StartIdx <= LeafEndIdx && "String can't start after it ends!");
auto *N = new (LeafNodeAllocator.Allocate())
SuffixTreeLeafNode(StartIdx, &LeafEndIdx);
// Since the suffix indices are already determined,
// they can be set directly.
N->setSuffixIdx(StartIdx - Parent.getConcatLen());
Parent.Children[Edge] = N;
return N;
}
Expand All @@ -73,8 +74,12 @@ SuffixTree::insertInternalNode(SuffixTreeInternalNode *Parent,
"Non-root internal nodes must have parents!");
auto *N = new (InternalNodeAllocator.Allocate())
SuffixTreeInternalNode(StartIdx, EndIdx, Root);
if (Parent)
if (Parent) {
// Since the concatLens are already determined,
// they can be set directly.
N->setConcatLen(Parent->getConcatLen() + numElementsInSubstring(N));
Parent->Children[Edge] = N;
}
return N;
}

Expand All @@ -83,34 +88,6 @@ SuffixTreeInternalNode *SuffixTree::insertRoot() {
SuffixTreeNode::EmptyIdx, /*Edge = */ 0);
}

void SuffixTree::setSuffixIndices() {
// List of nodes we need to visit along with the current length of the
// string.
SmallVector<std::pair<SuffixTreeNode *, unsigned>> ToVisit;

// Current node being visited.
SuffixTreeNode *CurrNode = Root;

// Sum of the lengths of the nodes down the path to the current one.
unsigned CurrNodeLen = 0;
ToVisit.push_back({CurrNode, CurrNodeLen});
while (!ToVisit.empty()) {
std::tie(CurrNode, CurrNodeLen) = ToVisit.pop_back_val();
// Length of the current node from the root down to here.
CurrNode->setConcatLen(CurrNodeLen);
if (auto *InternalNode = dyn_cast<SuffixTreeInternalNode>(CurrNode))
for (auto &ChildPair : InternalNode->Children) {
assert(ChildPair.second && "Node had a null child!");
ToVisit.push_back(
{ChildPair.second,
CurrNodeLen + numElementsInSubstring(ChildPair.second)});
}
// No children, so we are at the end of the string.
if (auto *LeafNode = dyn_cast<SuffixTreeLeafNode>(CurrNode))
LeafNode->setSuffixIdx(Str.size() - CurrNodeLen);
}
}

void SuffixTree::setLeafNodes() {
// A stack that keeps track of nodes to visit for post-order DFS traversal.
SmallVector<SuffixTreeNode *> ToVisit;
Expand Down