#ifndef wasm_support_suffix_tree_h
#define wasm_support_suffix_tree_h
#include "llvm/Support/Allocator.h"
#include <cassert>
#include <cstddef>
#include <vector>
#include "support/suffix_tree_node.h"
using namespace llvm;
namespace wasm {
class SuffixTree {
public:
std::vector<unsigned> Str;
struct RepeatedSubstring {
unsigned Length;
std::vector<unsigned> StartIndices;
bool operator==(const RepeatedSubstring& other) const {
return Length == other.Length && StartIndices == other.StartIndices;
}
};
private:
SpecificBumpPtrAllocator<SuffixTreeInternalNode> InternalNodeAllocator;
SpecificBumpPtrAllocator<SuffixTreeLeafNode> LeafNodeAllocator;
SuffixTreeInternalNode* Root = nullptr;
unsigned LeafEndIdx = SuffixTreeNode::EmptyIdx;
struct ActiveState {
SuffixTreeInternalNode* Node = nullptr;
unsigned Idx = SuffixTreeNode::EmptyIdx;
unsigned Len = 0;
};
ActiveState Active;
SuffixTreeNode*
insertLeaf(SuffixTreeInternalNode& Parent, unsigned StartIdx, unsigned Edge);
SuffixTreeInternalNode* insertInternalNode(SuffixTreeInternalNode* Parent,
unsigned StartIdx,
unsigned EndIdx,
unsigned Edge);
SuffixTreeInternalNode* insertRoot();
void setSuffixIndices();
unsigned extend(unsigned EndIdx, unsigned SuffixesToAdd);
public:
SuffixTree(const std::vector<unsigned>& Str);
struct RepeatedSubstringIterator {
private:
SuffixTreeNode* N = nullptr;
RepeatedSubstring RS;
std::vector<SuffixTreeInternalNode*> InternalNodesToVisit;
const unsigned MinLength = 2;
void advance();
public:
using iterator_category = std::input_iterator_tag;
using value_type = RepeatedSubstring;
using difference_type = std::ptrdiff_t;
using pointer = const RepeatedSubstring*;
using reference = const RepeatedSubstring&;
RepeatedSubstring& operator*() { return RS; }
RepeatedSubstring* operator->() { return &RS; }
RepeatedSubstringIterator& operator++() {
advance();
return *this;
}
RepeatedSubstringIterator operator++(int I) {
RepeatedSubstringIterator It(*this);
advance();
return It;
}
bool operator==(const RepeatedSubstringIterator& Other) const {
return N == Other.N;
}
bool operator!=(const RepeatedSubstringIterator& Other) const {
return !(*this == Other);
}
RepeatedSubstringIterator(SuffixTreeInternalNode* N) : N(N) {
if (!N) {
return;
}
InternalNodesToVisit.push_back(N);
advance();
}
};
typedef RepeatedSubstringIterator iterator;
iterator begin() { return iterator(Root); }
iterator end() { return iterator(nullptr); }
};
}
#endif