mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
Use vector for child storage instead of map. This will also make
our life during future GraphTraits'ing slightly easier. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44952 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7915cbee4d
commit
41ff20bff4
@ -22,7 +22,6 @@ namespace llvm {
|
|||||||
|
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// - Labels are usually small, maybe it's better to use SmallString
|
// - Labels are usually small, maybe it's better to use SmallString
|
||||||
// - Something efficient for child storage
|
|
||||||
// - Should we use char* during construction?
|
// - Should we use char* during construction?
|
||||||
// - Should we templatize Empty with traits-like interface?
|
// - Should we templatize Empty with traits-like interface?
|
||||||
// - GraphTraits interface
|
// - GraphTraits interface
|
||||||
@ -39,10 +38,21 @@ class Trie {
|
|||||||
DontMatch = 0,
|
DontMatch = 0,
|
||||||
HaveCommonPart
|
HaveCommonPart
|
||||||
} QueryResult;
|
} QueryResult;
|
||||||
|
typedef std::vector<Node*> NodeVector;
|
||||||
|
typedef typename std::vector<Node*>::iterator NodeVectorIter;
|
||||||
|
|
||||||
|
struct NodeCmp {
|
||||||
|
bool operator() (Node* N1, Node* N2) {
|
||||||
|
return (N1->Label[0] < N2->Label[0]);
|
||||||
|
}
|
||||||
|
bool operator() (Node* N, char Id) {
|
||||||
|
return (N->Label[0] < Id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
std::string Label;
|
std::string Label;
|
||||||
Payload Data;
|
Payload Data;
|
||||||
std::map<char, Node*> Children;
|
NodeVector Children;
|
||||||
public:
|
public:
|
||||||
inline explicit Node(const Payload& data, const std::string& label = ""):
|
inline explicit Node(const Payload& data, const std::string& label = ""):
|
||||||
Label(label), Data(data) { }
|
Label(label), Data(data) { }
|
||||||
@ -70,9 +80,44 @@ class Trie {
|
|||||||
inline void setLabel(const std::string& label) { Label = label; }
|
inline void setLabel(const std::string& label) { Label = label; }
|
||||||
inline const std::string& getLabel() const { return Label; }
|
inline const std::string& getLabel() const { return Label; }
|
||||||
|
|
||||||
inline bool addEdge(Node* N) {
|
#if 0
|
||||||
const std::string& Label = N->getLabel();
|
inline void dump() {
|
||||||
return Children.insert(std::make_pair(Label[0], N)).second;
|
std::cerr << "Node: " << this << "\n"
|
||||||
|
<< "Label: " << Label << "\n"
|
||||||
|
<< "Children:\n";
|
||||||
|
|
||||||
|
for (NodeVectorIter I = Children.begin(), E = Children.end(); I != E; ++I)
|
||||||
|
std::cerr << (*I)->Label << "\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline void addEdge(Node* N) {
|
||||||
|
if (Children.empty())
|
||||||
|
Children.push_back(N);
|
||||||
|
else {
|
||||||
|
NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
|
||||||
|
N, NodeCmp());
|
||||||
|
// FIXME: no dups are allowed
|
||||||
|
Children.insert(I, N);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Node* getEdge(char Id) {
|
||||||
|
Node* fNode = NULL;
|
||||||
|
NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
|
||||||
|
Id, NodeCmp());
|
||||||
|
if (I != Children.end() && (*I)->Label[0] == Id)
|
||||||
|
fNode = *I;
|
||||||
|
|
||||||
|
return fNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setEdge(Node* N) {
|
||||||
|
char Id = N->Label[0];
|
||||||
|
NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
|
||||||
|
Id, NodeCmp());
|
||||||
|
assert(I != Children.end() && "Node does not exists!");
|
||||||
|
*I = N;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryResult query(const std::string& s) const {
|
QueryResult query(const std::string& s) const {
|
||||||
@ -101,6 +146,8 @@ class Trie {
|
|||||||
std::vector<Node*> Nodes;
|
std::vector<Node*> Nodes;
|
||||||
Payload Empty;
|
Payload Empty;
|
||||||
|
|
||||||
|
inline Node* getRoot() const { return Nodes[0]; }
|
||||||
|
|
||||||
inline Node* addNode(const Payload& data, const std::string label = "") {
|
inline Node* addNode(const Payload& data, const std::string label = "") {
|
||||||
Node* N = new Node(data, label);
|
Node* N = new Node(data, label);
|
||||||
Nodes.push_back(N);
|
Nodes.push_back(N);
|
||||||
@ -108,21 +155,19 @@ class Trie {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline Node* splitEdge(Node* N, char Id, size_t index) {
|
inline Node* splitEdge(Node* N, char Id, size_t index) {
|
||||||
assert(N->Children.count(Id) && "Node doesn't exist");
|
Node* eNode = N->getEdge(Id);
|
||||||
|
assert(eNode && "Node doesn't exist");
|
||||||
Node* eNode = N->Children[Id];
|
|
||||||
|
|
||||||
const std::string &l = eNode->Label;
|
const std::string &l = eNode->Label;
|
||||||
assert(index > 0 && index < l.length() && "Trying to split too far!");
|
assert(index > 0 && index < l.length() && "Trying to split too far!");
|
||||||
std::string l1 = l.substr(0, index);
|
std::string l1 = l.substr(0, index);
|
||||||
std::string l2 = l.substr(index);
|
std::string l2 = l.substr(index);
|
||||||
|
|
||||||
eNode->Label = l2;
|
|
||||||
|
|
||||||
Node* nNode = addNode(Empty, l1);
|
Node* nNode = addNode(Empty, l1);
|
||||||
nNode->addEdge(eNode);
|
N->setEdge(nNode);
|
||||||
|
|
||||||
N->Children[Id] = nNode;
|
eNode->Label = l2;
|
||||||
|
nNode->addEdge(eNode);
|
||||||
|
|
||||||
return nNode;
|
return nNode;
|
||||||
}
|
}
|
||||||
@ -136,8 +181,6 @@ public:
|
|||||||
delete Nodes[i];
|
delete Nodes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Node* getRoot() const { return Nodes[0]; }
|
|
||||||
|
|
||||||
bool addString(const std::string& s, const Payload& data) {
|
bool addString(const std::string& s, const Payload& data) {
|
||||||
Node* cNode = getRoot();
|
Node* cNode = getRoot();
|
||||||
Node* tNode = NULL;
|
Node* tNode = NULL;
|
||||||
@ -145,8 +188,7 @@ public:
|
|||||||
|
|
||||||
while (tNode == NULL) {
|
while (tNode == NULL) {
|
||||||
char Id = s1[0];
|
char Id = s1[0];
|
||||||
if (cNode->Children.count(Id)) {
|
if (Node* nNode = cNode->getEdge(Id)) {
|
||||||
Node* nNode = cNode->Children[Id];
|
|
||||||
typename Node::QueryResult r = nNode->query(s1);
|
typename Node::QueryResult r = nNode->query(s1);
|
||||||
|
|
||||||
switch (r) {
|
switch (r) {
|
||||||
@ -167,7 +209,7 @@ public:
|
|||||||
nNode = splitEdge(cNode, Id, r);
|
nNode = splitEdge(cNode, Id, r);
|
||||||
tNode = addNode(data, s1.substr(r));
|
tNode = addNode(data, s1.substr(r));
|
||||||
nNode->addEdge(tNode);
|
nNode->addEdge(tNode);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tNode = addNode(data, s1);
|
tNode = addNode(data, s1);
|
||||||
cNode->addEdge(tNode);
|
cNode->addEdge(tNode);
|
||||||
@ -183,8 +225,8 @@ public:
|
|||||||
std::string s1(s);
|
std::string s1(s);
|
||||||
|
|
||||||
while (tNode == NULL) {
|
while (tNode == NULL) {
|
||||||
if (cNode->Children.count(s1[0])) {
|
char Id = s1[0];
|
||||||
Node* nNode = cNode->Children[s1[0]];
|
if (Node* nNode = cNode->getEdge(Id)) {
|
||||||
typename Node::QueryResult r = nNode->query(s1);
|
typename Node::QueryResult r = nNode->query(s1);
|
||||||
|
|
||||||
switch (r) {
|
switch (r) {
|
||||||
|
Loading…
Reference in New Issue
Block a user