llvm.org GIT mirror llvm / 41ff20b
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 Anton Korobeynikov 12 years ago
1 changed file(s) with 61 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
2121
2222 // FIXME:
2323 // - Labels are usually small, maybe it's better to use SmallString
24 // - Something efficient for child storage
2524 // - Should we use char* during construction?
2625 // - Should we templatize Empty with traits-like interface?
2726 // - GraphTraits interface
3837 DontMatch = 0,
3938 HaveCommonPart
4039 } QueryResult;
40 typedef std::vector NodeVector;
41 typedef typename std::vector::iterator NodeVectorIter;
42
43 struct NodeCmp {
44 bool operator() (Node* N1, Node* N2) {
45 return (N1->Label[0] < N2->Label[0]);
46 }
47 bool operator() (Node* N, char Id) {
48 return (N->Label[0] < Id);
49 }
50 };
4151
4252 std::string Label;
4353 Payload Data;
44 std::map Children;
54 NodeVector Children;
4555 public:
4656 inline explicit Node(const Payload& data, const std::string& label = ""):
4757 Label(label), Data(data) { }
6979 inline void setLabel(const std::string& label) { Label = label; }
7080 inline const std::string& getLabel() const { return Label; }
7181
72 inline bool addEdge(Node* N) {
73 const std::string& Label = N->getLabel();
74 return Children.insert(std::make_pair(Label[0], N)).second;
82 #if 0
83 inline void dump() {
84 std::cerr << "Node: " << this << "\n"
85 << "Label: " << Label << "\n"
86 << "Children:\n";
87
88 for (NodeVectorIter I = Children.begin(), E = Children.end(); I != E; ++I)
89 std::cerr << (*I)->Label << "\n";
90 }
91 #endif
92
93 inline void addEdge(Node* N) {
94 if (Children.empty())
95 Children.push_back(N);
96 else {
97 NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
98 N, NodeCmp());
99 // FIXME: no dups are allowed
100 Children.insert(I, N);
101 }
102 }
103
104 inline Node* getEdge(char Id) {
105 Node* fNode = NULL;
106 NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
107 Id, NodeCmp());
108 if (I != Children.end() && (*I)->Label[0] == Id)
109 fNode = *I;
110
111 return fNode;
112 }
113
114 inline void setEdge(Node* N) {
115 char Id = N->Label[0];
116 NodeVectorIter I = std::lower_bound(Children.begin(), Children.end(),
117 Id, NodeCmp());
118 assert(I != Children.end() && "Node does not exists!");
119 *I = N;
75120 }
76121
77122 QueryResult query(const std::string& s) const {
100145 std::vector Nodes;
101146 Payload Empty;
102147
148 inline Node* getRoot() const { return Nodes[0]; }
149
103150 inline Node* addNode(const Payload& data, const std::string label = "") {
104151 Node* N = new Node(data, label);
105152 Nodes.push_back(N);
107154 }
108155
109156 inline Node* splitEdge(Node* N, char Id, size_t index) {
110 assert(N->Children.count(Id) && "Node doesn't exist");
111
112 Node* eNode = N->Children[Id];
157 Node* eNode = N->getEdge(Id);
158 assert(eNode && "Node doesn't exist");
113159
114160 const std::string &l = eNode->Label;
115161 assert(index > 0 && index < l.length() && "Trying to split too far!");
116162 std::string l1 = l.substr(0, index);
117163 std::string l2 = l.substr(index);
118164
165 Node* nNode = addNode(Empty, l1);
166 N->setEdge(nNode);
167
119168 eNode->Label = l2;
120
121 Node* nNode = addNode(Empty, l1);
122169 nNode->addEdge(eNode);
123
124 N->Children[Id] = nNode;
125170
126171 return nNode;
127172 }
134179 for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
135180 delete Nodes[i];
136181 }
137
138 inline Node* getRoot() const { return Nodes[0]; }
139182
140183 bool addString(const std::string& s, const Payload& data) {
141184 Node* cNode = getRoot();
144187
145188 while (tNode == NULL) {
146189 char Id = s1[0];
147 if (cNode->Children.count(Id)) {
148 Node* nNode = cNode->Children[Id];
190 if (Node* nNode = cNode->getEdge(Id)) {
149191 typename Node::QueryResult r = nNode->query(s1);
150192
151193 switch (r) {
166208 nNode = splitEdge(cNode, Id, r);
167209 tNode = addNode(data, s1.substr(r));
168210 nNode->addEdge(tNode);
169 }
211 }
170212 } else {
171213 tNode = addNode(data, s1);
172214 cNode->addEdge(tNode);
182224 std::string s1(s);
183225
184226 while (tNode == NULL) {
185 if (cNode->Children.count(s1[0])) {
186 Node* nNode = cNode->Children[s1[0]];
227 char Id = s1[0];
228 if (Node* nNode = cNode->getEdge(Id)) {
187229 typename Node::QueryResult r = nNode->query(s1);
188230
189231 switch (r) {