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