1*16467b97STreehugger RobotANTLR_BEGIN_NAMESPACE() 2*16467b97STreehugger Robot 3*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 4*16467b97STreehugger RobotANTLR_INLINE TrieEntry<ImplTraits, DataType>::TrieEntry(const DataType& data, TrieEntry* next) 5*16467b97STreehugger Robot :m_data(data) 6*16467b97STreehugger Robot{ 7*16467b97STreehugger Robot m_next = next; 8*16467b97STreehugger Robot} 9*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 10*16467b97STreehugger RobotANTLR_INLINE DataType& TrieEntry<ImplTraits, DataType>::get_data() 11*16467b97STreehugger Robot{ 12*16467b97STreehugger Robot return m_data; 13*16467b97STreehugger Robot} 14*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 15*16467b97STreehugger RobotANTLR_INLINE const DataType& TrieEntry<ImplTraits, DataType>::get_data() const 16*16467b97STreehugger Robot{ 17*16467b97STreehugger Robot return m_data; 18*16467b97STreehugger Robot} 19*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 20*16467b97STreehugger RobotANTLR_INLINE TrieEntry<ImplTraits, DataType>* TrieEntry<ImplTraits, DataType>::get_next() const 21*16467b97STreehugger Robot{ 22*16467b97STreehugger Robot return m_next; 23*16467b97STreehugger Robot} 24*16467b97STreehugger Robot 25*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 26*16467b97STreehugger RobotANTLR_INLINE void TrieEntry<ImplTraits, DataType>::set_next( TrieEntry* next ) 27*16467b97STreehugger Robot{ 28*16467b97STreehugger Robot m_next = next; 29*16467b97STreehugger Robot} 30*16467b97STreehugger Robot 31*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 32*16467b97STreehugger RobotANTLR_INLINE ANTLR_UINT32 IntTrieNode<ImplTraits, DataType>::get_bitNum() const 33*16467b97STreehugger Robot{ 34*16467b97STreehugger Robot return m_bitNum; 35*16467b97STreehugger Robot} 36*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 37*16467b97STreehugger RobotANTLR_INLINE ANTLR_INTKEY IntTrieNode<ImplTraits, DataType>::get_key() const 38*16467b97STreehugger Robot{ 39*16467b97STreehugger Robot return m_key; 40*16467b97STreehugger Robot} 41*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 42*16467b97STreehugger RobotANTLR_INLINE typename IntTrieNode<ImplTraits, DataType>::BucketsType* IntTrieNode<ImplTraits, DataType>::get_buckets() const 43*16467b97STreehugger Robot{ 44*16467b97STreehugger Robot return m_buckets; 45*16467b97STreehugger Robot} 46*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 47*16467b97STreehugger RobotANTLR_INLINE IntTrieNode<ImplTraits, DataType>* IntTrieNode<ImplTraits, DataType>::get_leftN() const 48*16467b97STreehugger Robot{ 49*16467b97STreehugger Robot return m_leftN; 50*16467b97STreehugger Robot} 51*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 52*16467b97STreehugger RobotANTLR_INLINE IntTrieNode<ImplTraits, DataType>* IntTrieNode<ImplTraits, DataType>::get_rightN() const 53*16467b97STreehugger Robot{ 54*16467b97STreehugger Robot return m_rightN; 55*16467b97STreehugger Robot} 56*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 57*16467b97STreehugger RobotANTLR_INLINE void IntTrieNode<ImplTraits, DataType>::set_bitNum( ANTLR_UINT32 bitNum ) 58*16467b97STreehugger Robot{ 59*16467b97STreehugger Robot m_bitNum = bitNum; 60*16467b97STreehugger Robot} 61*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 62*16467b97STreehugger RobotANTLR_INLINE void IntTrieNode<ImplTraits, DataType>::set_key( ANTLR_INTKEY key ) 63*16467b97STreehugger Robot{ 64*16467b97STreehugger Robot m_key = key; 65*16467b97STreehugger Robot} 66*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 67*16467b97STreehugger RobotANTLR_INLINE void IntTrieNode<ImplTraits, DataType>::set_buckets( BucketsType* buckets ) 68*16467b97STreehugger Robot{ 69*16467b97STreehugger Robot m_buckets = buckets; 70*16467b97STreehugger Robot} 71*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 72*16467b97STreehugger RobotANTLR_INLINE void IntTrieNode<ImplTraits, DataType>::set_leftN( IntTrieNode* leftN ) 73*16467b97STreehugger Robot{ 74*16467b97STreehugger Robot m_leftN = leftN; 75*16467b97STreehugger Robot} 76*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 77*16467b97STreehugger RobotANTLR_INLINE void IntTrieNode<ImplTraits, DataType>::set_rightN( IntTrieNode* rightN ) 78*16467b97STreehugger Robot{ 79*16467b97STreehugger Robot m_rightN = rightN; 80*16467b97STreehugger Robot} 81*16467b97STreehugger Robot 82*16467b97STreehugger RobotANTLR_INLINE const ANTLR_UINT8* IntTrieBase::get_bitIndex() 83*16467b97STreehugger Robot{ 84*16467b97STreehugger Robot static ANTLR_UINT8 bitIndex[256] = 85*16467b97STreehugger Robot { 86*16467b97STreehugger Robot 0, // 0 - Just for padding 87*16467b97STreehugger Robot 0, // 1 88*16467b97STreehugger Robot 1, 1, // 2..3 89*16467b97STreehugger Robot 2, 2, 2, 2, // 4..7 90*16467b97STreehugger Robot 3, 3, 3, 3, 3, 3, 3, 3, // 8+ 91*16467b97STreehugger Robot 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 16+ 92*16467b97STreehugger Robot 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 32+ 93*16467b97STreehugger Robot 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 94*16467b97STreehugger Robot 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 64+ 95*16467b97STreehugger Robot 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 96*16467b97STreehugger Robot 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 97*16467b97STreehugger Robot 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 98*16467b97STreehugger Robot 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 128+ 99*16467b97STreehugger Robot 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 100*16467b97STreehugger Robot 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 101*16467b97STreehugger Robot 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 102*16467b97STreehugger Robot 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 103*16467b97STreehugger Robot 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 104*16467b97STreehugger Robot 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 105*16467b97STreehugger Robot 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 106*16467b97STreehugger Robot }; 107*16467b97STreehugger Robot return bitIndex; 108*16467b97STreehugger Robot} 109*16467b97STreehugger Robot 110*16467b97STreehugger RobotANTLR_INLINE const ANTLR_UINT64* IntTrieBase::get_bitMask() 111*16467b97STreehugger Robot{ 112*16467b97STreehugger Robot static ANTLR_UINT64 bitMask[64] = 113*16467b97STreehugger Robot { 114*16467b97STreehugger Robot 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000004ULL, 0x0000000000000008ULL, 115*16467b97STreehugger Robot 0x0000000000000010ULL, 0x0000000000000020ULL, 0x0000000000000040ULL, 0x0000000000000080ULL, 116*16467b97STreehugger Robot 0x0000000000000100ULL, 0x0000000000000200ULL, 0x0000000000000400ULL, 0x0000000000000800ULL, 117*16467b97STreehugger Robot 0x0000000000001000ULL, 0x0000000000002000ULL, 0x0000000000004000ULL, 0x0000000000008000ULL, 118*16467b97STreehugger Robot 0x0000000000010000ULL, 0x0000000000020000ULL, 0x0000000000040000ULL, 0x0000000000080000ULL, 119*16467b97STreehugger Robot 0x0000000000100000ULL, 0x0000000000200000ULL, 0x0000000000400000ULL, 0x0000000000800000ULL, 120*16467b97STreehugger Robot 0x0000000001000000ULL, 0x0000000002000000ULL, 0x0000000004000000ULL, 0x0000000008000000ULL, 121*16467b97STreehugger Robot 0x0000000010000000ULL, 0x0000000020000000ULL, 0x0000000040000000ULL, 0x0000000080000000ULL, 122*16467b97STreehugger Robot 0x0000000100000000ULL, 0x0000000200000000ULL, 0x0000000400000000ULL, 0x0000000800000000ULL, 123*16467b97STreehugger Robot 0x0000001000000000ULL, 0x0000002000000000ULL, 0x0000004000000000ULL, 0x0000008000000000ULL, 124*16467b97STreehugger Robot 0x0000010000000000ULL, 0x0000020000000000ULL, 0x0000040000000000ULL, 0x0000080000000000ULL, 125*16467b97STreehugger Robot 0x0000100000000000ULL, 0x0000200000000000ULL, 0x0000400000000000ULL, 0x0000800000000000ULL, 126*16467b97STreehugger Robot 0x0001000000000000ULL, 0x0002000000000000ULL, 0x0004000000000000ULL, 0x0008000000000000ULL, 127*16467b97STreehugger Robot 0x0010000000000000ULL, 0x0020000000000000ULL, 0x0040000000000000ULL, 0x0080000000000000ULL, 128*16467b97STreehugger Robot 0x0100000000000000ULL, 0x0200000000000000ULL, 0x0400000000000000ULL, 0x0800000000000000ULL, 129*16467b97STreehugger Robot 0x1000000000000000ULL, 0x2000000000000000ULL, 0x4000000000000000ULL, 0x8000000000000000ULL 130*16467b97STreehugger Robot }; 131*16467b97STreehugger Robot 132*16467b97STreehugger Robot return bitMask; 133*16467b97STreehugger Robot} 134*16467b97STreehugger Robot 135*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 136*16467b97STreehugger RobotIntTrie<ImplTraits, DataType>::IntTrie( ANTLR_UINT32 depth ) 137*16467b97STreehugger Robot{ 138*16467b97STreehugger Robot /* Now we need to allocate the root node. This makes it easier 139*16467b97STreehugger Robot * to use the tree as we don't have to do anything special 140*16467b97STreehugger Robot * for the root node. 141*16467b97STreehugger Robot */ 142*16467b97STreehugger Robot m_root = new IntTrieNodeType; 143*16467b97STreehugger Robot 144*16467b97STreehugger Robot /* Now we seed the root node with the index being the 145*16467b97STreehugger Robot * highest left most bit we want to test, which limits the 146*16467b97STreehugger Robot * keys in the trie. This is the trie 'depth'. The limit for 147*16467b97STreehugger Robot * this implementation is 63 (bits 0..63). 148*16467b97STreehugger Robot */ 149*16467b97STreehugger Robot m_root->set_bitNum( depth ); 150*16467b97STreehugger Robot 151*16467b97STreehugger Robot /* And as we have nothing in here yet, we set both child pointers 152*16467b97STreehugger Robot * of the root node to point back to itself. 153*16467b97STreehugger Robot */ 154*16467b97STreehugger Robot m_root->set_leftN( m_root ); 155*16467b97STreehugger Robot m_root->set_rightN( m_root ); 156*16467b97STreehugger Robot m_count = 0; 157*16467b97STreehugger Robot 158*16467b97STreehugger Robot /* Finally, note that the key for this root node is 0 because 159*16467b97STreehugger Robot * we use calloc() to initialise it. 160*16467b97STreehugger Robot */ 161*16467b97STreehugger Robot m_allowDups = false; 162*16467b97STreehugger Robot m_current = NULL; 163*16467b97STreehugger Robot} 164*16467b97STreehugger Robot 165*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 166*16467b97STreehugger RobotIntTrie<ImplTraits, DataType>::~IntTrie() 167*16467b97STreehugger Robot{ 168*16467b97STreehugger Robot /* Descend from the root and free all the nodes 169*16467b97STreehugger Robot */ 170*16467b97STreehugger Robot delete m_root; 171*16467b97STreehugger Robot 172*16467b97STreehugger Robot /* the nodes are all gone now, so we need only free the memory 173*16467b97STreehugger Robot * for the structure itself 174*16467b97STreehugger Robot */ 175*16467b97STreehugger Robot} 176*16467b97STreehugger Robot 177*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 178*16467b97STreehugger Robottypename IntTrie<ImplTraits, DataType>::TrieEntryType* IntTrie<ImplTraits, DataType>::get( ANTLR_INTKEY key) 179*16467b97STreehugger Robot{ 180*16467b97STreehugger Robot IntTrieNodeType* thisNode; 181*16467b97STreehugger Robot IntTrieNodeType* nextNode; 182*16467b97STreehugger Robot 183*16467b97STreehugger Robot if (m_count == 0) 184*16467b97STreehugger Robot return NULL; /* Nothing in this trie yet */ 185*16467b97STreehugger Robot 186*16467b97STreehugger Robot /* Starting at the root node in the trie, compare the bit index 187*16467b97STreehugger Robot * of the current node with its next child node (starts left from root). 188*16467b97STreehugger Robot * When the bit index of the child node is greater than the bit index of the current node 189*16467b97STreehugger Robot * then by definition (as the bit index decreases as we descent the trie) 190*16467b97STreehugger Robot * we have reached a 'backward' pointer. A backward pointer means we 191*16467b97STreehugger Robot * have reached the only node that can be reached by the bits given us so far 192*16467b97STreehugger Robot * and it must either be the key we are looking for, or if not then it 193*16467b97STreehugger Robot * means the entry was not in the trie, and we return NULL. A backward pointer 194*16467b97STreehugger Robot * points back in to the tree structure rather than down (deeper) within the 195*16467b97STreehugger Robot * tree branches. 196*16467b97STreehugger Robot */ 197*16467b97STreehugger Robot thisNode = m_root; /* Start at the root node */ 198*16467b97STreehugger Robot nextNode = thisNode->get_leftN(); /* Examine the left node from the root */ 199*16467b97STreehugger Robot 200*16467b97STreehugger Robot /* While we are descending the tree nodes... 201*16467b97STreehugger Robot */ 202*16467b97STreehugger Robot const ANTLR_UINT64* bitMask = this->get_bitMask(); 203*16467b97STreehugger Robot while( thisNode->get_bitNum() > nextNode->get_bitNum() ) 204*16467b97STreehugger Robot { 205*16467b97STreehugger Robot /* Next node now becomes the new 'current' node 206*16467b97STreehugger Robot */ 207*16467b97STreehugger Robot thisNode = nextNode; 208*16467b97STreehugger Robot 209*16467b97STreehugger Robot /* We now test the bit indicated by the bitmap in the next node 210*16467b97STreehugger Robot * in the key we are searching for. The new next node is the 211*16467b97STreehugger Robot * right node if that bit is set and the left node it is not. 212*16467b97STreehugger Robot */ 213*16467b97STreehugger Robot if (key & bitMask[nextNode->get_bitNum()]) 214*16467b97STreehugger Robot { 215*16467b97STreehugger Robot nextNode = nextNode->get_rightN(); /* 1 is right */ 216*16467b97STreehugger Robot } 217*16467b97STreehugger Robot else 218*16467b97STreehugger Robot { 219*16467b97STreehugger Robot nextNode = nextNode->get_leftN(); /* 0 is left */ 220*16467b97STreehugger Robot } 221*16467b97STreehugger Robot } 222*16467b97STreehugger Robot 223*16467b97STreehugger Robot /* Here we have reached a node where the bitMap index is lower than 224*16467b97STreehugger Robot * its parent. This means it is pointing backward in the tree and 225*16467b97STreehugger Robot * must therefore be a terminal node, being the only point than can 226*16467b97STreehugger Robot * be reached with the bits seen so far. It is either the actual key 227*16467b97STreehugger Robot * we wanted, or if that key is not in the trie it is another key 228*16467b97STreehugger Robot * that is currently the only one that can be reached by those bits. 229*16467b97STreehugger Robot * That situation would obviously change if the key was to be added 230*16467b97STreehugger Robot * to the trie. 231*16467b97STreehugger Robot * 232*16467b97STreehugger Robot * Hence it only remains to test whether this is actually the key or not. 233*16467b97STreehugger Robot */ 234*16467b97STreehugger Robot if (nextNode->get_key() == key) 235*16467b97STreehugger Robot { 236*16467b97STreehugger Robot /* This was the key, so return the entry pointer 237*16467b97STreehugger Robot */ 238*16467b97STreehugger Robot return nextNode->get_buckets(); 239*16467b97STreehugger Robot } 240*16467b97STreehugger Robot else 241*16467b97STreehugger Robot { 242*16467b97STreehugger Robot return NULL; /* That key is not in the trie (note that we set the pointer to -1 if no payload) */ 243*16467b97STreehugger Robot } 244*16467b97STreehugger Robot} 245*16467b97STreehugger Robot 246*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 247*16467b97STreehugger Robotbool IntTrie<ImplTraits, DataType>::del( ANTLR_INTKEY key) 248*16467b97STreehugger Robot{ 249*16467b97STreehugger Robot IntTrieNodeType* p; 250*16467b97STreehugger Robot 251*16467b97STreehugger Robot p = m_root; 252*16467b97STreehugger Robot 253*16467b97STreehugger Robot return false; 254*16467b97STreehugger Robot 255*16467b97STreehugger Robot} 256*16467b97STreehugger Robot 257*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 258*16467b97STreehugger Robotbool IntTrie<ImplTraits, DataType>::add( ANTLR_INTKEY key, const DataType& data ) 259*16467b97STreehugger Robot{ 260*16467b97STreehugger Robot IntTrieNodeType* thisNode; 261*16467b97STreehugger Robot IntTrieNodeType* nextNode; 262*16467b97STreehugger Robot IntTrieNodeType* entNode; 263*16467b97STreehugger Robot ANTLR_UINT32 depth; 264*16467b97STreehugger Robot TrieEntryType* newEnt; 265*16467b97STreehugger Robot TrieEntryType* nextEnt; 266*16467b97STreehugger Robot ANTLR_INTKEY xorKey; 267*16467b97STreehugger Robot 268*16467b97STreehugger Robot /* Cache the bit depth of this trie, which is always the highest index, 269*16467b97STreehugger Robot * which is in the root node 270*16467b97STreehugger Robot */ 271*16467b97STreehugger Robot depth = m_root->get_bitNum(); 272*16467b97STreehugger Robot 273*16467b97STreehugger Robot thisNode = m_root; /* Start with the root node */ 274*16467b97STreehugger Robot nextNode = m_root->get_leftN(); /* And assume we start to the left */ 275*16467b97STreehugger Robot 276*16467b97STreehugger Robot /* Now find the only node that can be currently reached by the bits in the 277*16467b97STreehugger Robot * key we are being asked to insert. 278*16467b97STreehugger Robot */ 279*16467b97STreehugger Robot const ANTLR_UINT64* bitMask = this->get_bitMask(); 280*16467b97STreehugger Robot while (thisNode->get_bitNum() > nextNode->get_bitNum() ) 281*16467b97STreehugger Robot { 282*16467b97STreehugger Robot /* Still descending the structure, next node becomes current. 283*16467b97STreehugger Robot */ 284*16467b97STreehugger Robot thisNode = nextNode; 285*16467b97STreehugger Robot 286*16467b97STreehugger Robot if (key & bitMask[nextNode->get_bitNum()]) 287*16467b97STreehugger Robot { 288*16467b97STreehugger Robot /* Bit at the required index was 1, so travers the right node from here 289*16467b97STreehugger Robot */ 290*16467b97STreehugger Robot nextNode = nextNode->get_rightN(); 291*16467b97STreehugger Robot } 292*16467b97STreehugger Robot else 293*16467b97STreehugger Robot { 294*16467b97STreehugger Robot /* Bit at the required index was 0, so we traverse to the left 295*16467b97STreehugger Robot */ 296*16467b97STreehugger Robot nextNode = nextNode->get_leftN(); 297*16467b97STreehugger Robot } 298*16467b97STreehugger Robot } 299*16467b97STreehugger Robot /* Here we have located the only node that can be reached by the 300*16467b97STreehugger Robot * bits in the requested key. It could in fact be that key or the node 301*16467b97STreehugger Robot * we need to use to insert the new key. 302*16467b97STreehugger Robot */ 303*16467b97STreehugger Robot if (nextNode->get_key() == key) 304*16467b97STreehugger Robot { 305*16467b97STreehugger Robot /* We have located an exact match, but we will only append to the bucket chain 306*16467b97STreehugger Robot * if this trie accepts duplicate keys. 307*16467b97STreehugger Robot */ 308*16467b97STreehugger Robot if (m_allowDups ==true) 309*16467b97STreehugger Robot { 310*16467b97STreehugger Robot /* Yes, we are accepting duplicates 311*16467b97STreehugger Robot */ 312*16467b97STreehugger Robot newEnt = new TrieEntryType(data, NULL); 313*16467b97STreehugger Robot 314*16467b97STreehugger Robot /* We want to be able to traverse the stored elements in the order that they were 315*16467b97STreehugger Robot * added as duplicate keys. We might need to revise this opinion if we end up having many duplicate keys 316*16467b97STreehugger Robot * as perhaps reverse order is just as good, so long as it is ordered. 317*16467b97STreehugger Robot */ 318*16467b97STreehugger Robot nextEnt = nextNode->get_buckets(); 319*16467b97STreehugger Robot while (nextEnt->get_next() != NULL) 320*16467b97STreehugger Robot { 321*16467b97STreehugger Robot nextEnt = nextEnt->get_next(); 322*16467b97STreehugger Robot } 323*16467b97STreehugger Robot nextEnt->set_next(newEnt); 324*16467b97STreehugger Robot 325*16467b97STreehugger Robot m_count++; 326*16467b97STreehugger Robot return true; 327*16467b97STreehugger Robot } 328*16467b97STreehugger Robot else 329*16467b97STreehugger Robot { 330*16467b97STreehugger Robot /* We found the key is already there and we are not allowed duplicates in this 331*16467b97STreehugger Robot * trie. 332*16467b97STreehugger Robot */ 333*16467b97STreehugger Robot return false; 334*16467b97STreehugger Robot } 335*16467b97STreehugger Robot } 336*16467b97STreehugger Robot 337*16467b97STreehugger Robot /* Here we have discovered the only node that can be reached by the bits in the key 338*16467b97STreehugger Robot * but we have found that this node is not the key we need to insert. We must find the 339*16467b97STreehugger Robot * the leftmost bit by which the current key for that node and the new key we are going 340*16467b97STreehugger Robot * to insert, differ. While this nested series of ifs may look a bit strange, experimentation 341*16467b97STreehugger Robot * showed that it allows a machine code path that works well with predicated execution 342*16467b97STreehugger Robot */ 343*16467b97STreehugger Robot xorKey = (key ^ nextNode->get_key() ); /* Gives 1 bits only where they differ then we find the left most 1 bit*/ 344*16467b97STreehugger Robot 345*16467b97STreehugger Robot /* Most common case is a 32 bit key really 346*16467b97STreehugger Robot */ 347*16467b97STreehugger Robot const ANTLR_UINT8* bitIndex = this->get_bitIndex(); 348*16467b97STreehugger Robot#ifdef ANTLR_USE_64BIT 349*16467b97STreehugger Robot if (xorKey & 0xFFFFFFFF00000000) 350*16467b97STreehugger Robot { 351*16467b97STreehugger Robot if (xorKey & 0xFFFF000000000000) 352*16467b97STreehugger Robot { 353*16467b97STreehugger Robot if (xorKey & 0xFF00000000000000) 354*16467b97STreehugger Robot { 355*16467b97STreehugger Robot depth = 56 + bitIndex[((xorKey & 0xFF00000000000000)>>56)]; 356*16467b97STreehugger Robot } 357*16467b97STreehugger Robot else 358*16467b97STreehugger Robot { 359*16467b97STreehugger Robot depth = 48 + bitIndex[((xorKey & 0x00FF000000000000)>>48)]; 360*16467b97STreehugger Robot } 361*16467b97STreehugger Robot } 362*16467b97STreehugger Robot else 363*16467b97STreehugger Robot { 364*16467b97STreehugger Robot if (xorKey & 0x0000FF0000000000) 365*16467b97STreehugger Robot { 366*16467b97STreehugger Robot depth = 40 + bitIndex[((xorKey & 0x0000FF0000000000)>>40)]; 367*16467b97STreehugger Robot } 368*16467b97STreehugger Robot else 369*16467b97STreehugger Robot { 370*16467b97STreehugger Robot depth = 32 + bitIndex[((xorKey & 0x000000FF00000000)>>32)]; 371*16467b97STreehugger Robot } 372*16467b97STreehugger Robot } 373*16467b97STreehugger Robot } 374*16467b97STreehugger Robot else 375*16467b97STreehugger Robot#endif 376*16467b97STreehugger Robot { 377*16467b97STreehugger Robot if (xorKey & 0x00000000FFFF0000) 378*16467b97STreehugger Robot { 379*16467b97STreehugger Robot if (xorKey & 0x00000000FF000000) 380*16467b97STreehugger Robot { 381*16467b97STreehugger Robot depth = 24 + bitIndex[((xorKey & 0x00000000FF000000)>>24)]; 382*16467b97STreehugger Robot } 383*16467b97STreehugger Robot else 384*16467b97STreehugger Robot { 385*16467b97STreehugger Robot depth = 16 + bitIndex[((xorKey & 0x0000000000FF0000)>>16)]; 386*16467b97STreehugger Robot } 387*16467b97STreehugger Robot } 388*16467b97STreehugger Robot else 389*16467b97STreehugger Robot { 390*16467b97STreehugger Robot if (xorKey & 0x000000000000FF00) 391*16467b97STreehugger Robot { 392*16467b97STreehugger Robot depth = 8 + bitIndex[((xorKey & 0x0000000000000FF00)>>8)]; 393*16467b97STreehugger Robot } 394*16467b97STreehugger Robot else 395*16467b97STreehugger Robot { 396*16467b97STreehugger Robot depth = bitIndex[xorKey & 0x00000000000000FF]; 397*16467b97STreehugger Robot } 398*16467b97STreehugger Robot } 399*16467b97STreehugger Robot } 400*16467b97STreehugger Robot 401*16467b97STreehugger Robot /* We have located the leftmost differing bit, indicated by the depth variable. So, we know what 402*16467b97STreehugger Robot * bit index we are to insert the new entry at. There are two cases, being where the two keys 403*16467b97STreehugger Robot * differ at a bit position that is not currently part of the bit testing, where they differ on a bit 404*16467b97STreehugger Robot * that is currently being skipped in the indexed comparisons, and where they differ on a bit 405*16467b97STreehugger Robot * that is merely lower down in the current bit search. If the bit index went bit 4, bit 2 and they differ 406*16467b97STreehugger Robot * at bit 3, then we have the "skipped" bit case. But if that chain was Bit 4, Bit 2 and they differ at bit 1 407*16467b97STreehugger Robot * then we have the easy bit <pun>. 408*16467b97STreehugger Robot * 409*16467b97STreehugger Robot * So, set up to descend the tree again, but this time looking for the insert point 410*16467b97STreehugger Robot * according to whether we skip the bit that differs or not. 411*16467b97STreehugger Robot */ 412*16467b97STreehugger Robot thisNode = m_root; 413*16467b97STreehugger Robot entNode = m_root->get_leftN(); 414*16467b97STreehugger Robot 415*16467b97STreehugger Robot /* Note the slight difference in the checks here to cover both cases 416*16467b97STreehugger Robot */ 417*16467b97STreehugger Robot while (thisNode->get_bitNum() > entNode->get_bitNum() && entNode->get_bitNum() > depth) 418*16467b97STreehugger Robot { 419*16467b97STreehugger Robot /* Still descending the structure, next node becomes current. 420*16467b97STreehugger Robot */ 421*16467b97STreehugger Robot thisNode = entNode; 422*16467b97STreehugger Robot 423*16467b97STreehugger Robot if (key & bitMask[entNode->get_bitNum()]) 424*16467b97STreehugger Robot { 425*16467b97STreehugger Robot /* Bit at the required index was 1, so traverse the right node from here 426*16467b97STreehugger Robot */ 427*16467b97STreehugger Robot entNode = entNode->get_rightN(); 428*16467b97STreehugger Robot } 429*16467b97STreehugger Robot else 430*16467b97STreehugger Robot { 431*16467b97STreehugger Robot /* Bit at the required index was 0, so we traverse to the left 432*16467b97STreehugger Robot */ 433*16467b97STreehugger Robot entNode = entNode->get_leftN(); 434*16467b97STreehugger Robot } 435*16467b97STreehugger Robot } 436*16467b97STreehugger Robot 437*16467b97STreehugger Robot /* We have located the correct insert point for this new key, so we need 438*16467b97STreehugger Robot * to allocate our entry and insert it etc. 439*16467b97STreehugger Robot */ 440*16467b97STreehugger Robot nextNode = new IntTrieNodeType(); 441*16467b97STreehugger Robot 442*16467b97STreehugger Robot /* Build a new entry block for the new node 443*16467b97STreehugger Robot */ 444*16467b97STreehugger Robot newEnt = new TrieEntryType(data, NULL); 445*16467b97STreehugger Robot 446*16467b97STreehugger Robot /* Install it 447*16467b97STreehugger Robot */ 448*16467b97STreehugger Robot nextNode->set_buckets(newEnt); 449*16467b97STreehugger Robot nextNode->set_key(key); 450*16467b97STreehugger Robot nextNode->set_bitNum( depth ); 451*16467b97STreehugger Robot 452*16467b97STreehugger Robot /* Work out the right and left pointers for this new node, which involve 453*16467b97STreehugger Robot * terminating with the current found node either right or left according 454*16467b97STreehugger Robot * to whether the current index bit is 1 or 0 455*16467b97STreehugger Robot */ 456*16467b97STreehugger Robot if (key & bitMask[depth]) 457*16467b97STreehugger Robot { 458*16467b97STreehugger Robot nextNode->set_leftN(entNode); /* Terminates at previous position */ 459*16467b97STreehugger Robot nextNode->set_rightN(nextNode); /* Terminates with itself */ 460*16467b97STreehugger Robot } 461*16467b97STreehugger Robot else 462*16467b97STreehugger Robot { 463*16467b97STreehugger Robot nextNode->set_rightN(entNode); /* Terminates at previous position */ 464*16467b97STreehugger Robot nextNode->set_leftN(nextNode); /* Terminates with itself */ 465*16467b97STreehugger Robot } 466*16467b97STreehugger Robot 467*16467b97STreehugger Robot /* Finally, we need to change the pointers at the node we located 468*16467b97STreehugger Robot * for inserting. If the key bit at its index is set then the right 469*16467b97STreehugger Robot * pointer for that node becomes the newly created node, otherwise the left 470*16467b97STreehugger Robot * pointer does. 471*16467b97STreehugger Robot */ 472*16467b97STreehugger Robot if (key & bitMask[thisNode->get_bitNum()] ) 473*16467b97STreehugger Robot { 474*16467b97STreehugger Robot thisNode->set_rightN( nextNode ); 475*16467b97STreehugger Robot } 476*16467b97STreehugger Robot else 477*16467b97STreehugger Robot { 478*16467b97STreehugger Robot thisNode->set_leftN(nextNode); 479*16467b97STreehugger Robot } 480*16467b97STreehugger Robot 481*16467b97STreehugger Robot /* Et voila 482*16467b97STreehugger Robot */ 483*16467b97STreehugger Robot m_count++; 484*16467b97STreehugger Robot return true; 485*16467b97STreehugger Robot} 486*16467b97STreehugger Robot 487*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 488*16467b97STreehugger RobotIntTrieNode<ImplTraits, DataType>::IntTrieNode() 489*16467b97STreehugger Robot{ 490*16467b97STreehugger Robot m_bitNum = 0; 491*16467b97STreehugger Robot m_key = 0; 492*16467b97STreehugger Robot m_buckets = NULL; 493*16467b97STreehugger Robot m_leftN = NULL; 494*16467b97STreehugger Robot m_rightN = NULL; 495*16467b97STreehugger Robot} 496*16467b97STreehugger Robot 497*16467b97STreehugger Robottemplate< class ImplTraits, class DataType > 498*16467b97STreehugger RobotIntTrieNode<ImplTraits, DataType>::~IntTrieNode() 499*16467b97STreehugger Robot{ 500*16467b97STreehugger Robot TrieEntryType* thisEntry; 501*16467b97STreehugger Robot TrieEntryType* nextEntry; 502*16467b97STreehugger Robot 503*16467b97STreehugger Robot /* If this node has a left pointer that is not a back pointer 504*16467b97STreehugger Robot * then recursively call to free this 505*16467b97STreehugger Robot */ 506*16467b97STreehugger Robot if ( m_bitNum > m_leftN->get_bitNum()) 507*16467b97STreehugger Robot { 508*16467b97STreehugger Robot /* We have a left node that needs descending, so do it. 509*16467b97STreehugger Robot */ 510*16467b97STreehugger Robot delete m_leftN; 511*16467b97STreehugger Robot } 512*16467b97STreehugger Robot 513*16467b97STreehugger Robot /* The left nodes from here should now be dealt with, so 514*16467b97STreehugger Robot * we need to descend any right nodes that are not back pointers 515*16467b97STreehugger Robot */ 516*16467b97STreehugger Robot if ( m_bitNum > m_rightN->get_bitNum() ) 517*16467b97STreehugger Robot { 518*16467b97STreehugger Robot /* There are some right nodes to descend and deal with. 519*16467b97STreehugger Robot */ 520*16467b97STreehugger Robot delete m_rightN; 521*16467b97STreehugger Robot } 522*16467b97STreehugger Robot 523*16467b97STreehugger Robot /* Now all the children are dealt with, we can destroy 524*16467b97STreehugger Robot * this node too 525*16467b97STreehugger Robot */ 526*16467b97STreehugger Robot thisEntry = m_buckets; 527*16467b97STreehugger Robot 528*16467b97STreehugger Robot while (thisEntry != NULL) 529*16467b97STreehugger Robot { 530*16467b97STreehugger Robot nextEntry = thisEntry->get_next(); 531*16467b97STreehugger Robot 532*16467b97STreehugger Robot /* Now free the data for this bucket entry 533*16467b97STreehugger Robot */ 534*16467b97STreehugger Robot delete thisEntry; 535*16467b97STreehugger Robot thisEntry = nextEntry; /* See if there are any more to free */ 536*16467b97STreehugger Robot } 537*16467b97STreehugger Robot 538*16467b97STreehugger Robot /* The bucket entry is now gone, so we can free the memory for 539*16467b97STreehugger Robot * the entry itself. 540*16467b97STreehugger Robot */ 541*16467b97STreehugger Robot 542*16467b97STreehugger Robot /* And that should be it for everything under this node and itself 543*16467b97STreehugger Robot */ 544*16467b97STreehugger Robot} 545*16467b97STreehugger Robot 546*16467b97STreehugger Robot/** 547*16467b97STreehugger Robot * Allocate and initialize a new ANTLR3 topological sorter, which can be 548*16467b97STreehugger Robot * used to define edges that identify numerical node indexes that depend on other 549*16467b97STreehugger Robot * numerical node indexes, which can then be sorted topologically such that 550*16467b97STreehugger Robot * any node is sorted after all its dependent nodes. 551*16467b97STreehugger Robot * 552*16467b97STreehugger Robot * Use: 553*16467b97STreehugger Robot * 554*16467b97STreehugger Robot * /verbatim 555*16467b97STreehugger Robot 556*16467b97STreehugger Robot pANTLR3_TOPO topo; 557*16467b97STreehugger Robot topo = antlr3NewTopo(); 558*16467b97STreehugger Robot 559*16467b97STreehugger Robot if (topo == NULL) { out of memory } 560*16467b97STreehugger Robot 561*16467b97STreehugger Robot topo->addEdge(topo, 3, 0); // Node 3 depends on node 0 562*16467b97STreehugger Robot topo->addEdge(topo, 0, 1); // Node - depends on node 1 563*16467b97STreehugger Robot topo->sortVector(topo, myVector); // Sort the vector in place (node numbers are the vector entry numbers) 564*16467b97STreehugger Robot 565*16467b97STreehugger Robot * /verbatim 566*16467b97STreehugger Robot */ 567*16467b97STreehugger Robottemplate<class ImplTraits> 568*16467b97STreehugger RobotTopo<ImplTraits>::Topo() 569*16467b97STreehugger Robot{ 570*16467b97STreehugger Robot // Initialize variables 571*16467b97STreehugger Robot // 572*16467b97STreehugger Robot m_visited = NULL; // Don't know how big it is yet 573*16467b97STreehugger Robot m_limit = 1; // No edges added yet 574*16467b97STreehugger Robot m_edges = NULL; // No edges added yet 575*16467b97STreehugger Robot m_sorted = NULL; // Nothing sorted at the start 576*16467b97STreehugger Robot m_cycle = NULL; // No cycles at the start 577*16467b97STreehugger Robot m_cycleMark = 0; // No cycles at the start 578*16467b97STreehugger Robot m_hasCycle = false; // No cycle at the start 579*16467b97STreehugger Robot} 580*16467b97STreehugger Robot 581*16467b97STreehugger Robot// Topological sorter 582*16467b97STreehugger Robot// 583*16467b97STreehugger Robottemplate<class ImplTraits> 584*16467b97STreehugger Robotvoid Topo<ImplTraits>::addEdge(ANTLR_UINT32 edge, ANTLR_UINT32 dependency) 585*16467b97STreehugger Robot{ 586*16467b97STreehugger Robot ANTLR_UINT32 i; 587*16467b97STreehugger Robot ANTLR_UINT32 maxEdge; 588*16467b97STreehugger Robot BitsetType* edgeDeps; 589*16467b97STreehugger Robot 590*16467b97STreehugger Robot if (edge>dependency) 591*16467b97STreehugger Robot { 592*16467b97STreehugger Robot maxEdge = edge; 593*16467b97STreehugger Robot } 594*16467b97STreehugger Robot else 595*16467b97STreehugger Robot { 596*16467b97STreehugger Robot maxEdge = dependency; 597*16467b97STreehugger Robot } 598*16467b97STreehugger Robot // We need to add an edge to says that the node indexed by 'edge' is 599*16467b97STreehugger Robot // dependent on the node indexed by 'dependency' 600*16467b97STreehugger Robot // 601*16467b97STreehugger Robot 602*16467b97STreehugger Robot // First see if we have enough room in the edges array to add the edge? 603*16467b97STreehugger Robot // 604*16467b97STreehugger Robot if ( m_edges == NULL) 605*16467b97STreehugger Robot { 606*16467b97STreehugger Robot // We don't have any edges yet, so create an array to hold them 607*16467b97STreehugger Robot // 608*16467b97STreehugger Robot m_edges = AllocPolicyType::alloc0(sizeof(BitsetType*) * (maxEdge + 1)); 609*16467b97STreehugger Robot 610*16467b97STreehugger Robot // Set the limit to what we have now 611*16467b97STreehugger Robot // 612*16467b97STreehugger Robot m_limit = maxEdge + 1; 613*16467b97STreehugger Robot } 614*16467b97STreehugger Robot else if (m_limit <= maxEdge) 615*16467b97STreehugger Robot { 616*16467b97STreehugger Robot // WE have some edges but not enough 617*16467b97STreehugger Robot // 618*16467b97STreehugger Robot m_edges = AllocPolicyType::realloc(m_edges, sizeof(BitsetType*) * (maxEdge + 1)); 619*16467b97STreehugger Robot 620*16467b97STreehugger Robot // Initialize the new bitmaps to ;indicate we have no edges defined yet 621*16467b97STreehugger Robot // 622*16467b97STreehugger Robot for (i = m_limit; i <= maxEdge; i++) 623*16467b97STreehugger Robot { 624*16467b97STreehugger Robot *((m_edges) + i) = NULL; 625*16467b97STreehugger Robot } 626*16467b97STreehugger Robot 627*16467b97STreehugger Robot // Set the limit to what we have now 628*16467b97STreehugger Robot // 629*16467b97STreehugger Robot m_limit = maxEdge + 1; 630*16467b97STreehugger Robot } 631*16467b97STreehugger Robot 632*16467b97STreehugger Robot // If the edge was flagged as depending on itself, then we just 633*16467b97STreehugger Robot // do nothing as it means this routine was just called to add it 634*16467b97STreehugger Robot // in to the list of nodes. 635*16467b97STreehugger Robot // 636*16467b97STreehugger Robot if (edge == dependency) 637*16467b97STreehugger Robot { 638*16467b97STreehugger Robot return; 639*16467b97STreehugger Robot } 640*16467b97STreehugger Robot 641*16467b97STreehugger Robot // Pick up the bit map for the requested edge 642*16467b97STreehugger Robot // 643*16467b97STreehugger Robot edgeDeps = *((m_edges) + edge); 644*16467b97STreehugger Robot 645*16467b97STreehugger Robot if (edgeDeps == NULL) 646*16467b97STreehugger Robot { 647*16467b97STreehugger Robot // No edges are defined yet for this node 648*16467b97STreehugger Robot // 649*16467b97STreehugger Robot edgeDeps = new BitsetType(0); 650*16467b97STreehugger Robot *((m_edges) + edge) = edgeDeps; 651*16467b97STreehugger Robot } 652*16467b97STreehugger Robot 653*16467b97STreehugger Robot // Set the bit in the bitmap that corresponds to the requested 654*16467b97STreehugger Robot // dependency. 655*16467b97STreehugger Robot // 656*16467b97STreehugger Robot edgeDeps->add(dependency); 657*16467b97STreehugger Robot 658*16467b97STreehugger Robot // And we are all set 659*16467b97STreehugger Robot // 660*16467b97STreehugger Robot return; 661*16467b97STreehugger Robot 662*16467b97STreehugger Robot} 663*16467b97STreehugger Robot 664*16467b97STreehugger Robot/** 665*16467b97STreehugger Robot * Given a starting node, descend its dependent nodes (ones that it has edges 666*16467b97STreehugger Robot * to) until we find one without edges. Having found a node without edges, we have 667*16467b97STreehugger Robot * discovered the bottom of a depth first search, which we can then ascend, adding 668*16467b97STreehugger Robot * the nodes in order from the bottom, which gives us the dependency order. 669*16467b97STreehugger Robot */ 670*16467b97STreehugger Robottemplate<class ImplTraits> 671*16467b97STreehugger Robotvoid Topo<ImplTraits>::DFS(ANTLR_UINT32 node) 672*16467b97STreehugger Robot{ 673*16467b97STreehugger Robot BitsetType* edges; 674*16467b97STreehugger Robot 675*16467b97STreehugger Robot // Guard against a revisit and check for cycles 676*16467b97STreehugger Robot // 677*16467b97STreehugger Robot if (m_hasCycle == true) 678*16467b97STreehugger Robot { 679*16467b97STreehugger Robot return; // We don't do anything else if we found a cycle 680*16467b97STreehugger Robot } 681*16467b97STreehugger Robot 682*16467b97STreehugger Robot if ( m_visited->isMember(node)) 683*16467b97STreehugger Robot { 684*16467b97STreehugger Robot // Check to see if we found a cycle. To do this we search the 685*16467b97STreehugger Robot // current cycle stack and see if we find this node already in the stack. 686*16467b97STreehugger Robot // 687*16467b97STreehugger Robot ANTLR_UINT32 i; 688*16467b97STreehugger Robot 689*16467b97STreehugger Robot for (i=0; i< m_cycleMark; i++) 690*16467b97STreehugger Robot { 691*16467b97STreehugger Robot if ( m_cycle[i] == node) 692*16467b97STreehugger Robot { 693*16467b97STreehugger Robot // Stop! We found a cycle in the input, so rejig the cycle 694*16467b97STreehugger Robot // stack so that it only contains the cycle and set the cycle flag 695*16467b97STreehugger Robot // which will tell the caller what happened 696*16467b97STreehugger Robot // 697*16467b97STreehugger Robot ANTLR_UINT32 l; 698*16467b97STreehugger Robot 699*16467b97STreehugger Robot for (l = i; l < m_cycleMark; l++) 700*16467b97STreehugger Robot { 701*16467b97STreehugger Robot m_cycle[l - i] = m_cycle[l]; // Move to zero base in the cycle list 702*16467b97STreehugger Robot } 703*16467b97STreehugger Robot 704*16467b97STreehugger Robot // Recalculate the limit 705*16467b97STreehugger Robot // 706*16467b97STreehugger Robot m_cycleMark -= i; 707*16467b97STreehugger Robot 708*16467b97STreehugger Robot // Signal disaster 709*16467b97STreehugger Robot // 710*16467b97STreehugger Robot m_hasCycle = true; 711*16467b97STreehugger Robot } 712*16467b97STreehugger Robot } 713*16467b97STreehugger Robot return; 714*16467b97STreehugger Robot } 715*16467b97STreehugger Robot 716*16467b97STreehugger Robot // So far, no cycles have been found and we have not visited this node yet, 717*16467b97STreehugger Robot // so this node needs to go into the cycle stack before we continue 718*16467b97STreehugger Robot // then we will take it out of the stack once we have descended all its 719*16467b97STreehugger Robot // dependencies. 720*16467b97STreehugger Robot // 721*16467b97STreehugger Robot m_cycle[m_cycleMark++] = node; 722*16467b97STreehugger Robot 723*16467b97STreehugger Robot // First flag that we have visited this node 724*16467b97STreehugger Robot // 725*16467b97STreehugger Robot m_visited->add(node); 726*16467b97STreehugger Robot 727*16467b97STreehugger Robot // Now, if this node has edges, then we want to ensure we visit 728*16467b97STreehugger Robot // them all before we drop through and add this node into the sorted 729*16467b97STreehugger Robot // list. 730*16467b97STreehugger Robot // 731*16467b97STreehugger Robot edges = *((m_edges) + node); 732*16467b97STreehugger Robot if (edges != NULL) 733*16467b97STreehugger Robot { 734*16467b97STreehugger Robot // We have some edges, so visit each of the edge nodes 735*16467b97STreehugger Robot // that have not already been visited. 736*16467b97STreehugger Robot // 737*16467b97STreehugger Robot ANTLR_UINT32 numBits; // How many bits are in the set 738*16467b97STreehugger Robot ANTLR_UINT32 i; 739*16467b97STreehugger Robot ANTLR_UINT32 range; 740*16467b97STreehugger Robot 741*16467b97STreehugger Robot numBits = edges->numBits(); 742*16467b97STreehugger Robot range = edges->size(); // Number of set bits 743*16467b97STreehugger Robot 744*16467b97STreehugger Robot // Stop if we exahust the bit list or have checked the 745*16467b97STreehugger Robot // number of edges that this node refers to (so we don't 746*16467b97STreehugger Robot // check bits at the end that cannot possibly be set). 747*16467b97STreehugger Robot // 748*16467b97STreehugger Robot for (i=0; i<= numBits && range > 0; i++) 749*16467b97STreehugger Robot { 750*16467b97STreehugger Robot if (edges->isMember(i)) 751*16467b97STreehugger Robot { 752*16467b97STreehugger Robot range--; // About to check another one 753*16467b97STreehugger Robot 754*16467b97STreehugger Robot // Found an edge, make sure we visit and descend it 755*16467b97STreehugger Robot // 756*16467b97STreehugger Robot this->DFS(i); 757*16467b97STreehugger Robot } 758*16467b97STreehugger Robot } 759*16467b97STreehugger Robot } 760*16467b97STreehugger Robot 761*16467b97STreehugger Robot // At this point we will have visited all the dependencies 762*16467b97STreehugger Robot // of this node and they will be ordered (even if there are cycles) 763*16467b97STreehugger Robot // So we just add the node into the sorted list at the 764*16467b97STreehugger Robot // current index position. 765*16467b97STreehugger Robot // 766*16467b97STreehugger Robot m_sorted[m_limit++] = node; 767*16467b97STreehugger Robot 768*16467b97STreehugger Robot // Remove this node from the cycle list if we have not detected a cycle 769*16467b97STreehugger Robot // 770*16467b97STreehugger Robot if (m_hasCycle == false) 771*16467b97STreehugger Robot { 772*16467b97STreehugger Robot m_cycleMark--; 773*16467b97STreehugger Robot } 774*16467b97STreehugger Robot 775*16467b97STreehugger Robot return; 776*16467b97STreehugger Robot} 777*16467b97STreehugger Robot 778*16467b97STreehugger Robottemplate<class ImplTraits> 779*16467b97STreehugger RobotANTLR_UINT32* Topo<ImplTraits>::sortToArray() 780*16467b97STreehugger Robot{ 781*16467b97STreehugger Robot ANTLR_UINT32 v; 782*16467b97STreehugger Robot ANTLR_UINT32 oldLimit; 783*16467b97STreehugger Robot 784*16467b97STreehugger Robot // Guard against being called with no edges defined 785*16467b97STreehugger Robot // 786*16467b97STreehugger Robot if (m_edges == NULL) 787*16467b97STreehugger Robot { 788*16467b97STreehugger Robot return 0; 789*16467b97STreehugger Robot } 790*16467b97STreehugger Robot // First we need a vector to populate with enough 791*16467b97STreehugger Robot // entries to accomodate the sorted list and another to accomodate 792*16467b97STreehugger Robot // the maximum cycle we could detect which is all nodes such as 0->1->2->3->0 793*16467b97STreehugger Robot // 794*16467b97STreehugger Robot m_sorted = AllocPolicyType::alloc( m_limit * sizeof(ANTLR_UINT32) ); 795*16467b97STreehugger Robot m_cycle = AllocPolicyType::alloc( m_limit * sizeof(ANTLR_UINT32)); 796*16467b97STreehugger Robot 797*16467b97STreehugger Robot // Next we need an empty bitset to show whether we have visited a node 798*16467b97STreehugger Robot // or not. This is the bit that gives us linear time of course as we are essentially 799*16467b97STreehugger Robot // dropping through the nodes in depth first order and when we get to a node that 800*16467b97STreehugger Robot // has no edges, we pop back up the stack adding the nodes we traversed in reverse 801*16467b97STreehugger Robot // order. 802*16467b97STreehugger Robot // 803*16467b97STreehugger Robot m_visited = new BitsetType(0); 804*16467b97STreehugger Robot 805*16467b97STreehugger Robot // Now traverse the nodes as if we were just going left to right, but 806*16467b97STreehugger Robot // then descend each node unless it has already been visited. 807*16467b97STreehugger Robot // 808*16467b97STreehugger Robot oldLimit = m_limit; // Number of nodes to traverse linearly 809*16467b97STreehugger Robot m_limit = 0; // Next entry in the sorted table 810*16467b97STreehugger Robot 811*16467b97STreehugger Robot for (v = 0; v < oldLimit; v++) 812*16467b97STreehugger Robot { 813*16467b97STreehugger Robot // If we did not already visit this node, then descend it until we 814*16467b97STreehugger Robot // get a node without edges or arrive at a node we have already visited. 815*16467b97STreehugger Robot // 816*16467b97STreehugger Robot if (m_visited->isMember(v) == false) 817*16467b97STreehugger Robot { 818*16467b97STreehugger Robot // We have not visited this one so descend it 819*16467b97STreehugger Robot // 820*16467b97STreehugger Robot this->DFS(v); 821*16467b97STreehugger Robot } 822*16467b97STreehugger Robot 823*16467b97STreehugger Robot // Break the loop if we detect a cycle as we have no need to go any 824*16467b97STreehugger Robot // further 825*16467b97STreehugger Robot // 826*16467b97STreehugger Robot if (m_hasCycle == true) 827*16467b97STreehugger Robot { 828*16467b97STreehugger Robot break; 829*16467b97STreehugger Robot } 830*16467b97STreehugger Robot } 831*16467b97STreehugger Robot 832*16467b97STreehugger Robot // Reset the limit to the number we recorded as if we hit a 833*16467b97STreehugger Robot // cycle, then limit will have stopped at the node where we 834*16467b97STreehugger Robot // discovered the cycle, but in order to free the edge bitmaps 835*16467b97STreehugger Robot // we need to know how many we may have allocated and traverse them all. 836*16467b97STreehugger Robot // 837*16467b97STreehugger Robot m_limit = oldLimit; 838*16467b97STreehugger Robot 839*16467b97STreehugger Robot // Having traversed all the nodes we were given, we 840*16467b97STreehugger Robot // are guaranteed to have ordered all the nodes or detected a 841*16467b97STreehugger Robot // cycle. 842*16467b97STreehugger Robot // 843*16467b97STreehugger Robot return m_sorted; 844*16467b97STreehugger Robot} 845*16467b97STreehugger Robot 846*16467b97STreehugger Robottemplate<class ImplTraits> 847*16467b97STreehugger Robot template<typename DataType> 848*16467b97STreehugger Robotvoid Topo<ImplTraits>::sortVector( typename ImplTraits::template VectorType<DataType>& v ) 849*16467b97STreehugger Robot{ 850*16467b97STreehugger Robot // To sort a vector, we first perform the 851*16467b97STreehugger Robot // sort to an array, then use the results to reorder the vector 852*16467b97STreehugger Robot // we are given. This is just a convenience routine that allows you to 853*16467b97STreehugger Robot // sort the children of a tree node into topological order before or 854*16467b97STreehugger Robot // during an AST walk. This can be useful for optimizations that require 855*16467b97STreehugger Robot // dag reorders and also when the input stream defines thigns that are 856*16467b97STreehugger Robot // interdependent and you want to walk the list of the generated trees 857*16467b97STreehugger Robot // for those things in topological order so you can ignore the interdependencies 858*16467b97STreehugger Robot // at that point. 859*16467b97STreehugger Robot // 860*16467b97STreehugger Robot ANTLR_UINT32 i; 861*16467b97STreehugger Robot 862*16467b97STreehugger Robot // Used as a lookup index to find the current location in the vector of 863*16467b97STreehugger Robot // the vector entry that was originally at position [0], [1], [2] etc 864*16467b97STreehugger Robot // 865*16467b97STreehugger Robot ANTLR_UINT32* vIndex; 866*16467b97STreehugger Robot 867*16467b97STreehugger Robot // Sort into an array, then we can use the array that is 868*16467b97STreehugger Robot // stored in the topo 869*16467b97STreehugger Robot // 870*16467b97STreehugger Robot if (this->sortToArray() == 0) 871*16467b97STreehugger Robot { 872*16467b97STreehugger Robot return; // There were no edges 873*16467b97STreehugger Robot } 874*16467b97STreehugger Robot 875*16467b97STreehugger Robot if (m_hasCycle == true) 876*16467b97STreehugger Robot { 877*16467b97STreehugger Robot return; // Do nothing if we detected a cycle 878*16467b97STreehugger Robot } 879*16467b97STreehugger Robot 880*16467b97STreehugger Robot // Ensure that the vector we are sorting is at least as big as the 881*16467b97STreehugger Robot // the input sequence we were adsked to sort. It does not matter if it is 882*16467b97STreehugger Robot // bigger as thaat probably just means that nodes numbered higher than the 883*16467b97STreehugger Robot // limit had no dependencies and so can be left alone. 884*16467b97STreehugger Robot // 885*16467b97STreehugger Robot if (m_limit > v.size() ) 886*16467b97STreehugger Robot { 887*16467b97STreehugger Robot // We can only sort the entries that we have dude! The caller is 888*16467b97STreehugger Robot // responsible for ensuring the vector is the correct one and is the 889*16467b97STreehugger Robot // correct size etc. 890*16467b97STreehugger Robot // 891*16467b97STreehugger Robot m_limit = v.size(); 892*16467b97STreehugger Robot } 893*16467b97STreehugger Robot // We need to know the locations of each of the entries 894*16467b97STreehugger Robot // in the vector as we don't want to duplicate them in a new vector. We 895*16467b97STreehugger Robot // just use an indirection table to get the vector entry for a particular sequence 896*16467b97STreehugger Robot // acording to where we moved it last. Then we can just swap vector entries until 897*16467b97STreehugger Robot // we are done :-) 898*16467b97STreehugger Robot // 899*16467b97STreehugger Robot vIndex = AllocPolicyType::alloc(m_limit * sizeof(ANTLR_UINT32)); 900*16467b97STreehugger Robot 901*16467b97STreehugger Robot // Start index, each vector entry is located where you think it is 902*16467b97STreehugger Robot // 903*16467b97STreehugger Robot for (i = 0; i < m_limit; i++) 904*16467b97STreehugger Robot { 905*16467b97STreehugger Robot vIndex[i] = i; 906*16467b97STreehugger Robot } 907*16467b97STreehugger Robot 908*16467b97STreehugger Robot // Now we traverse the sorted array and moved the entries of 909*16467b97STreehugger Robot // the vector around according to the sort order and the indirection 910*16467b97STreehugger Robot // table we just created. The index telsl us where in the vector the 911*16467b97STreehugger Robot // original element entry n is now located via vIndex[n]. 912*16467b97STreehugger Robot // 913*16467b97STreehugger Robot for (i=0; i < m_limit; i++) 914*16467b97STreehugger Robot { 915*16467b97STreehugger Robot ANTLR_UINT32 ind; 916*16467b97STreehugger Robot 917*16467b97STreehugger Robot // If the vector entry at i is already the one that it 918*16467b97STreehugger Robot // should be, then we skip moving it of course. 919*16467b97STreehugger Robot // 920*16467b97STreehugger Robot if (vIndex[m_sorted[i]] == i) 921*16467b97STreehugger Robot { 922*16467b97STreehugger Robot continue; 923*16467b97STreehugger Robot } 924*16467b97STreehugger Robot 925*16467b97STreehugger Robot // The vector entry at i, should be replaced with the 926*16467b97STreehugger Robot // vector entry indicated by topo->sorted[i]. The vector entry 927*16467b97STreehugger Robot // at topo->sorted[i] may have already been swapped out though, so we 928*16467b97STreehugger Robot // find where it is now and move it from there to i. 929*16467b97STreehugger Robot // 930*16467b97STreehugger Robot ind = vIndex[m_sorted[i]]; 931*16467b97STreehugger Robot std::swap( v[i], v[ind] ); 932*16467b97STreehugger Robot 933*16467b97STreehugger Robot // Update our index. The element at i is now the one we wanted 934*16467b97STreehugger Robot // to be sorted here and the element we swapped out is now the 935*16467b97STreehugger Robot // element that was at i just before we swapped it. If you are lost now 936*16467b97STreehugger Robot // don't worry about it, we are just reindexing on the fly is all. 937*16467b97STreehugger Robot // 938*16467b97STreehugger Robot vIndex[m_sorted[i]] = i; 939*16467b97STreehugger Robot vIndex[i] = ind; 940*16467b97STreehugger Robot } 941*16467b97STreehugger Robot 942*16467b97STreehugger Robot // Having traversed all the entries, we have sorted the vector in place. 943*16467b97STreehugger Robot // 944*16467b97STreehugger Robot AllocPolicyType::free(vIndex); 945*16467b97STreehugger Robot return; 946*16467b97STreehugger Robot} 947*16467b97STreehugger Robot 948*16467b97STreehugger Robottemplate<class ImplTraits> 949*16467b97STreehugger RobotTopo<ImplTraits>::~Topo() 950*16467b97STreehugger Robot{ 951*16467b97STreehugger Robot ANTLR_UINT32 i; 952*16467b97STreehugger Robot 953*16467b97STreehugger Robot // Free the result vector 954*16467b97STreehugger Robot // 955*16467b97STreehugger Robot if (m_sorted != NULL) 956*16467b97STreehugger Robot { 957*16467b97STreehugger Robot AllocPolicyType::free(m_sorted); 958*16467b97STreehugger Robot } 959*16467b97STreehugger Robot 960*16467b97STreehugger Robot // Free the visited map 961*16467b97STreehugger Robot // 962*16467b97STreehugger Robot if (m_visited != NULL) 963*16467b97STreehugger Robot { 964*16467b97STreehugger Robot delete m_visited; 965*16467b97STreehugger Robot } 966*16467b97STreehugger Robot 967*16467b97STreehugger Robot // Free any edgemaps 968*16467b97STreehugger Robot // 969*16467b97STreehugger Robot if (m_edges != NULL) 970*16467b97STreehugger Robot { 971*16467b97STreehugger Robot Bitset<AllocPolicyType>* edgeList; 972*16467b97STreehugger Robot 973*16467b97STreehugger Robot for (i=0; i<m_limit; i++) 974*16467b97STreehugger Robot { 975*16467b97STreehugger Robot edgeList = *((m_edges) + i); 976*16467b97STreehugger Robot if (edgeList != NULL) 977*16467b97STreehugger Robot { 978*16467b97STreehugger Robot delete edgeList; 979*16467b97STreehugger Robot } 980*16467b97STreehugger Robot } 981*16467b97STreehugger Robot 982*16467b97STreehugger Robot AllocPolicyType::free( m_edges ); 983*16467b97STreehugger Robot } 984*16467b97STreehugger Robot m_edges = NULL; 985*16467b97STreehugger Robot 986*16467b97STreehugger Robot // Free any cycle map 987*16467b97STreehugger Robot // 988*16467b97STreehugger Robot if (m_cycle != NULL) 989*16467b97STreehugger Robot { 990*16467b97STreehugger Robot AllocPolicyType::free(m_cycle); 991*16467b97STreehugger Robot } 992*16467b97STreehugger Robot} 993*16467b97STreehugger Robot 994*16467b97STreehugger Robot 995*16467b97STreehugger RobotANTLR_END_NAMESPACE() 996