Home | History | Annotate | Download | only in ADT
      1 //===- HashTable.tcc ---------------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 //===--------------------------------------------------------------------===//
     11 // template implementation of HashTable
     12 template<typename HashEntryTy,
     13          typename HashFunctionTy,
     14          typename EntryFactoryTy>
     15 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::HashTable(size_type pSize)
     16   : HashTableImpl<HashEntryTy, HashFunctionTy>(pSize), m_EntryFactory()
     17 {
     18 }
     19 
     20 template<typename HashEntryTy,
     21          typename HashFunctionTy,
     22          typename EntryFactoryTy>
     23 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::~HashTable()
     24 {
     25   if (BaseTy::empty())
     26     return;
     27 
     28   /** clean up **/
     29   for (unsigned int i=0; i < BaseTy::m_NumOfBuckets; ++i) {
     30     if (bucket_type::getEmptyBucket() != BaseTy::m_Buckets[i].Entry &&
     31         bucket_type::getTombstone() != BaseTy::m_Buckets[i].Entry ) {
     32       m_EntryFactory.destroy(BaseTy::m_Buckets[i].Entry);
     33     }
     34   }
     35 }
     36 
     37 template<typename HashEntryTy,
     38          typename HashFunctionTy,
     39          typename EntryFactoryTy>
     40 void HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::clear()
     41 {
     42   if (BaseTy::empty())
     43     return;
     44 
     45   /** clean up **/
     46   for (unsigned int i=0; i < BaseTy::m_NumOfBuckets; ++i) {
     47     if (bucket_type::getEmptyBucket() != BaseTy::m_Buckets[i].Entry ) {
     48       if (bucket_type::getTombstone() != BaseTy::m_Buckets[i].Entry ) {
     49         m_EntryFactory.destroy(BaseTy::m_Buckets[i].Entry);
     50       }
     51       BaseTy::m_Buckets[i].Entry = bucket_type::getEmptyBucket();
     52     }
     53   }
     54 
     55   BaseTy::clear();
     56 }
     57 
     58 /// insert - insert a new element to the container. If the element already
     59 //  exist, return the element.
     60 template<typename HashEntryTy,
     61          typename HashFunctionTy,
     62          typename EntryFactoryTy>
     63 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::entry_type*
     64 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::insert(
     65   const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey,
     66   bool& pExist)
     67 {
     68   unsigned int index = BaseTy::lookUpBucketFor(pKey);
     69   bucket_type& bucket = BaseTy::m_Buckets[index];
     70   entry_type* entry = bucket.Entry;
     71   if (bucket_type::getEmptyBucket() != entry &&
     72       bucket_type::getTombstone() != entry) {
     73     // Already exist in the table
     74     pExist = true;
     75     return entry;
     76   }
     77 
     78   // find a tombstone
     79   if (bucket_type::getTombstone() == entry)
     80     --BaseTy::m_NumOfTombstones;
     81 
     82   entry = bucket.Entry = m_EntryFactory.produce(pKey);
     83   ++BaseTy::m_NumOfEntries;
     84   BaseTy::mayRehash();
     85   pExist = false;
     86   return entry;
     87 }
     88 
     89 /// erase - remove the elements with the pKey
     90 //  @return the number of removed elements.
     91 template<typename HashEntryTy,
     92          typename HashFunctionTy,
     93          typename EntryFactoryTy>
     94 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::size_type
     95 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::erase(
     96         const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
     97 {
     98   int index;
     99   if (-1 == (index = BaseTy::findKey(pKey)))
    100     return 0;
    101 
    102   bucket_type& bucket = BaseTy::m_Buckets[index];
    103   m_EntryFactory.destroy(bucket.Entry);
    104   bucket.Entry = bucket_type::getTombstone();
    105 
    106   --BaseTy::m_NumOfEntries;
    107   ++BaseTy::m_NumOfTombstones;
    108   BaseTy::mayRehash();
    109   return 1;
    110 }
    111 
    112 template<typename HashEntryTy,
    113          typename HashFunctionTy,
    114          typename EntryFactoryTy>
    115 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::iterator
    116 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::find(
    117   const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
    118 {
    119   int index;
    120   if (-1 == (index = BaseTy::findKey(pKey)))
    121     return end();
    122   return iterator(this, index);
    123 }
    124 
    125 template<typename HashEntryTy,
    126          typename HashFunctionTy,
    127          typename EntryFactoryTy>
    128 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_iterator
    129 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::find(
    130   const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
    131 {
    132   int index;
    133   if (-1 == (index = BaseTy::findKey(pKey)))
    134     return end();
    135   return const_iterator(this, index);
    136 }
    137 
    138 template<typename HashEntryTy,
    139          typename HashFunctionTy,
    140          typename EntryFactoryTy>
    141 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::size_type
    142 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::count(
    143   const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
    144 {
    145   const_chain_iterator bucket, bEnd = end(pKey);
    146   size_type count = 0;
    147   for (bucket = begin(pKey); bucket != bEnd; ++bucket)
    148     ++count;
    149   return count;
    150 }
    151 
    152 template<typename HashEntryTy,
    153          typename HashFunctionTy,
    154          typename EntryFactoryTy>
    155 float HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::load_factor() const
    156 {
    157   return ((float)BaseTy::m_NumOfEntries/(float)BaseTy::m_NumOfBuckets);
    158 }
    159 
    160 template<typename HashEntryTy,
    161          typename HashFunctionTy,
    162          typename EntryFactoryTy>
    163 void
    164 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::rehash()
    165 {
    166   BaseTy::mayRehash();
    167 }
    168 
    169 template<typename HashEntryTy,
    170          typename HashFunctionTy,
    171          typename EntryFactoryTy>
    172 void
    173 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::rehash(
    174        typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::size_type pCount)
    175 {
    176   BaseTy::doRehash(pCount);
    177 }
    178 
    179 template<typename HashEntryTy,
    180          typename HashFunctionTy,
    181          typename EntryFactoryTy>
    182 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::iterator
    183 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin()
    184 {
    185   if (BaseTy::empty())
    186     return end();
    187   unsigned int index = 0;
    188   while (bucket_type::getTombstone() == BaseTy::m_Buckets[index].Entry ||
    189          bucket_type::getEmptyBucket() == BaseTy::m_Buckets[index].Entry) {
    190     ++index;
    191   }
    192   return iterator(this, index);
    193 }
    194 
    195 template<typename HashEntryTy,
    196          typename HashFunctionTy,
    197          typename EntryFactoryTy>
    198 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::iterator
    199 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end()
    200 {
    201   return iterator(NULL, 0);
    202 }
    203 
    204 template<typename HashEntryTy,
    205          typename HashFunctionTy,
    206          typename EntryFactoryTy>
    207 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_iterator
    208 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin() const
    209 {
    210   if (BaseTy::empty())
    211     return end();
    212   unsigned int index = 0;
    213   while (bucket_type::getTombstone() == BaseTy::m_Buckets[index].Entry ||
    214          bucket_type::getEmptyBucket() == BaseTy::m_Buckets[index].Entry) {
    215     ++index;
    216   }
    217   return const_iterator(this, index);
    218 }
    219 
    220 template<typename HashEntryTy,
    221          typename HashFunctionTy,
    222          typename EntryFactoryTy>
    223 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_iterator
    224 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end() const
    225 {
    226   return const_iterator(NULL, 0);
    227 }
    228 
    229 template<typename HashEntryTy,
    230          typename HashFunctionTy,
    231          typename EntryFactoryTy>
    232 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::chain_iterator
    233 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin(
    234     const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
    235 {
    236   return chain_iterator(this, pKey, 0x0);
    237 }
    238 
    239 template<typename HashEntryTy,
    240          typename HashFunctionTy,
    241          typename EntryFactoryTy>
    242 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::chain_iterator
    243 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end(
    244     const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey)
    245 {
    246   return chain_iterator();
    247 }
    248 
    249 template<typename HashEntryTy,
    250          typename HashFunctionTy,
    251          typename EntryFactoryTy>
    252 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_chain_iterator
    253 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::begin(
    254   const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
    255 {
    256   return const_chain_iterator(this, pKey, 0x0);
    257 }
    258 
    259 template<typename HashEntryTy,
    260          typename HashFunctionTy,
    261          typename EntryFactoryTy>
    262 typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::const_chain_iterator
    263 HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::end(
    264   const typename HashTable<HashEntryTy, HashFunctionTy, EntryFactoryTy>::key_type& pKey) const
    265 {
    266   return const_chain_iterator();
    267 }
    268 
    269