[llvm-commits] [llvm] r44952 - /llvm/trunk/include/llvm/ADT/Trie.h

Anton Korobeynikov asl at math.spbu.ru
Wed Dec 12 11:08:44 PST 2007


Author: asl
Date: Wed Dec 12 13:08:44 2007
New Revision: 44952

URL: http://llvm.org/viewvc/llvm-project?rev=44952&view=rev
Log:
Use vector for child storage instead of map. This will also make
our life during future GraphTraits'ing slightly easier.

Modified:
    llvm/trunk/include/llvm/ADT/Trie.h

Modified: llvm/trunk/include/llvm/ADT/Trie.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Trie.h?rev=44952&r1=44951&r2=44952&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ADT/Trie.h (original)
+++ llvm/trunk/include/llvm/ADT/Trie.h Wed Dec 12 13:08:44 2007
@@ -22,7 +22,6 @@
 
 // FIXME:
 // - Labels are usually small, maybe it's better to use SmallString
-// - Something efficient for child storage
 // - Should we use char* during construction?
 // - Should we templatize Empty with traits-like interface?
 // - GraphTraits interface
@@ -39,10 +38,21 @@
       DontMatch      = 0,
       HaveCommonPart
     } 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;
     Payload Data;
-    std::map<char, Node*> Children;
+    NodeVector Children;
   public:
     inline explicit Node(const Payload& data, const std::string& label = ""):
         Label(label), Data(data) { }
@@ -70,9 +80,44 @@
     inline void setLabel(const std::string& label) { Label = label; }
     inline const std::string& getLabel() const { return Label; }
 
-    inline bool addEdge(Node* N) {
-      const std::string& Label = N->getLabel();
-      return Children.insert(std::make_pair(Label[0], N)).second;
+#if 0
+    inline void dump() {
+      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 {
@@ -101,6 +146,8 @@
   std::vector<Node*> Nodes;
   Payload Empty;
 
+  inline Node* getRoot() const { return Nodes[0]; }
+
   inline Node* addNode(const Payload& data, const std::string label = "") {
     Node* N = new Node(data, label);
     Nodes.push_back(N);
@@ -108,21 +155,19 @@
   }
 
   inline Node* splitEdge(Node* N, char Id, size_t index) {
-    assert(N->Children.count(Id) && "Node doesn't exist");
-
-    Node* eNode = N->Children[Id];
+    Node* eNode = N->getEdge(Id);
+    assert(eNode && "Node doesn't exist");
 
     const std::string &l = eNode->Label;
     assert(index > 0 && index < l.length() && "Trying to split too far!");
     std::string l1 = l.substr(0, index);
     std::string l2 = l.substr(index);
 
-    eNode->Label = l2;
-
     Node* nNode = addNode(Empty, l1);
-    nNode->addEdge(eNode);
+    N->setEdge(nNode);
 
-    N->Children[Id] = nNode;
+    eNode->Label = l2;
+    nNode->addEdge(eNode);
 
     return nNode;
   }
@@ -136,8 +181,6 @@
       delete Nodes[i];
   }
 
-  inline Node* getRoot() const { return Nodes[0]; }
-
   bool addString(const std::string& s, const Payload& data) {
     Node* cNode = getRoot();
     Node* tNode = NULL;
@@ -145,8 +188,7 @@
 
     while (tNode == NULL) {
       char Id = s1[0];
-      if (cNode->Children.count(Id)) {
-        Node* nNode = cNode->Children[Id];
+      if (Node* nNode = cNode->getEdge(Id)) {
         typename Node::QueryResult r = nNode->query(s1);
 
         switch (r) {
@@ -167,7 +209,7 @@
          nNode = splitEdge(cNode, Id, r);
          tNode = addNode(data, s1.substr(r));
          nNode->addEdge(tNode);
-        }
+       }
       } else {
         tNode = addNode(data, s1);
         cNode->addEdge(tNode);
@@ -183,8 +225,8 @@
     std::string s1(s);
 
     while (tNode == NULL) {
-      if (cNode->Children.count(s1[0])) {
-        Node* nNode = cNode->Children[s1[0]];
+      char Id = s1[0];
+      if (Node* nNode = cNode->getEdge(Id)) {
         typename Node::QueryResult r = nNode->query(s1);
 
         switch (r) {





More information about the llvm-commits mailing list