//===- HashBase.tcc -------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

//===--------------------------------------------------------------------===//
// internal non-member functions
inline static unsigned int compute_bucket_count(unsigned int pNumOfBuckets)
{
  static const unsigned int bucket_size[] =
  {
    1, 3, 17, 37, 67, 97, 197, 419, 977, 2593, 4099, 8209, 12289,
    16411, 20483, 32771, 49157, 65537, 98317, 131101, 196613
  };

  const unsigned int buckets_count =
      sizeof(bucket_size) / sizeof(bucket_size[0]);
  unsigned int idx = 0;
  do {
    if (pNumOfBuckets < bucket_size[idx]) {
      return bucket_size[idx];
    }
    ++idx;
  } while(idx < buckets_count);

  return (pNumOfBuckets+131101); // rare case. increase constantly
}

//===--------------------------------------------------------------------===//
// template implementation of HashBucket
template<typename DataType>
typename HashBucket<DataType>::entry_type*
HashBucket<DataType>::getEmptyBucket()
{
  static entry_type* empty_bucket = reinterpret_cast<entry_type*>(0x0);
  return empty_bucket;
}

template<typename DataType>
typename HashBucket<DataType>::entry_type*
HashBucket<DataType>::getTombstone()
{
  static entry_type* tombstone = reinterpret_cast<entry_type*>(0x1);
  return tombstone;
}

//===--------------------------------------------------------------------===//
// template implementation of HashTableImpl
template<typename HashEntryTy,
         typename HashFunctionTy>
HashTableImpl<HashEntryTy, HashFunctionTy>::HashTableImpl()
  : m_Buckets(0),
    m_NumOfBuckets(0),
    m_NumOfEntries(0),
    m_NumOfTombstones(0),
    m_Hasher() {
}

template<typename HashEntryTy,
         typename HashFunctionTy>
HashTableImpl<HashEntryTy, HashFunctionTy>::HashTableImpl(
  unsigned int pInitSize)
  : m_Hasher() {
  if (pInitSize) {
    init(pInitSize);
    return;
  }

  m_Buckets = 0;
  m_NumOfBuckets = 0;
  m_NumOfEntries = 0;
  m_NumOfTombstones = 0;
}

template<typename HashEntryTy,
         typename HashFunctionTy>
HashTableImpl<HashEntryTy, HashFunctionTy>::~HashTableImpl()
{
  clear();
}

/// empty - check if the hash table is empty
template<typename HashEntryTy,
         typename HashFunctionTy>
bool HashTableImpl<HashEntryTy, HashFunctionTy>::empty() const
{
  return (0 == m_NumOfEntries);
}

/// init - initialize the hash table.
template<typename HashEntryTy,
         typename HashFunctionTy>
void HashTableImpl<HashEntryTy, HashFunctionTy>::init(unsigned int pInitSize)
{
  m_NumOfBuckets = pInitSize? compute_bucket_count(pInitSize): NumOfInitBuckets;

  m_NumOfEntries = 0;
  m_NumOfTombstones = 0;

  /** calloc also set bucket.Item = bucket_type::getEmptyStone() **/
  m_Buckets = (bucket_type*)calloc(m_NumOfBuckets, sizeof(bucket_type));
}

/// clear - clear the hash table.
template<typename HashEntryTy,
         typename HashFunctionTy>
void HashTableImpl<HashEntryTy, HashFunctionTy>::clear()
{
  free(m_Buckets);

  m_Buckets = 0;
  m_NumOfBuckets = 0;
  m_NumOfEntries = 0;
  m_NumOfTombstones = 0;
}

/// lookUpBucketFor - look up the bucket whose key is pKey
template<typename HashEntryTy,
         typename HashFunctionTy>
unsigned int
HashTableImpl<HashEntryTy, HashFunctionTy>::lookUpBucketFor(
  const typename HashTableImpl<HashEntryTy, HashFunctionTy>::key_type& pKey)
{
  if (0 == m_NumOfBuckets) {
    // NumOfBuckets is changed after init(pInitSize)
    init(NumOfInitBuckets);
  }

  unsigned int full_hash = m_Hasher(pKey);
  unsigned int index = full_hash % m_NumOfBuckets;

  const unsigned int probe = 1;
  int firstTombstone = -1;

  // linear probing
  while(true) {
    bucket_type& bucket = m_Buckets[index];
    // If we found an empty bucket, this key isn't in the table yet, return it.
    if (bucket_type::getEmptyBucket() == bucket.Entry) {
      if (-1 != firstTombstone) {
        m_Buckets[firstTombstone].FullHashValue = full_hash;
        return firstTombstone;
      }

      bucket.FullHashValue = full_hash;
      return index;
    }

    if (bucket_type::getTombstone() == bucket.Entry) {
      if (-1 == firstTombstone) {
        firstTombstone = index;
      }
    }
    else if (bucket.FullHashValue == full_hash) {
      if (bucket.Entry->compare(pKey)) {
        return index;
      }
    }

    index += probe;
    if (index == m_NumOfBuckets)
      index = 0;
  }
}

template<typename HashEntryTy,
         typename HashFunctionTy>
int
HashTableImpl<HashEntryTy, HashFunctionTy>::findKey(
  const typename HashTableImpl<HashEntryTy, HashFunctionTy>::key_type& pKey) const
{
  if (0 == m_NumOfBuckets)
    return -1;

  unsigned int full_hash = m_Hasher(pKey);
  unsigned int index = full_hash % m_NumOfBuckets;

  const unsigned int probe = 1;
  // linear probing
  while (true) {
    bucket_type &bucket = m_Buckets[index];

    if (bucket_type::getEmptyBucket() == bucket.Entry)
      return -1;

    if (bucket_type::getTombstone() == bucket.Entry) {
      // Ignore tombstones.
    }
    else if (full_hash == bucket.FullHashValue) {
      // get string, compare, if match, return index
      if (bucket.Entry->compare(pKey))
        return index;
    }
    index += probe;
    if (index == m_NumOfBuckets)
      index = 0;
  }
}

template<typename HashEntryTy,
         typename HashFunctionTy>
void HashTableImpl<HashEntryTy, HashFunctionTy>::mayRehash()
{

  unsigned int new_size;
  // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
  // the buckets are empty (meaning that many are filled with tombstones),
  // grow/rehash the table.
  if ((m_NumOfEntries<<2) > m_NumOfBuckets*3)
    new_size = compute_bucket_count(m_NumOfBuckets);
  else if (((m_NumOfBuckets-(m_NumOfEntries+m_NumOfTombstones))<<3) < m_NumOfBuckets)
    new_size = m_NumOfBuckets;
  else
    return;

  doRehash(new_size);
}

template<typename HashEntryTy,
         typename HashFunctionTy>
void HashTableImpl<HashEntryTy, HashFunctionTy>::doRehash(unsigned int pNewSize)
{
  bucket_type* new_table = (bucket_type*)calloc(pNewSize, sizeof(bucket_type));

  // Rehash all the items into their new buckets.  Luckily :) we already have
  // the hash values available, so we don't have to recall hash function again.
  for (bucket_type *IB = m_Buckets, *E = m_Buckets+m_NumOfBuckets; IB != E; ++IB) {
    if (IB->Entry != bucket_type::getEmptyBucket() &&
        IB->Entry != bucket_type::getTombstone()) {
      // Fast case, bucket available.
      unsigned full_hash = IB->FullHashValue;
      unsigned new_bucket = full_hash % pNewSize;
      if (bucket_type::getEmptyBucket() == new_table[new_bucket].Entry) {
        new_table[new_bucket].Entry = IB->Entry;
        new_table[new_bucket].FullHashValue = full_hash;
        continue;
      }

      // Otherwise probe for a spot.
      const unsigned int probe = 1;
      do {
        new_bucket += probe;
        if (new_bucket == pNewSize)
          new_bucket = 0;
      } while (new_table[new_bucket].Entry != bucket_type::getEmptyBucket());

      // Finally found a slot.  Fill it in.
      new_table[new_bucket].Entry = IB->Entry;
      new_table[new_bucket].FullHashValue = full_hash;
    }
  }

  free(m_Buckets);

  m_Buckets = new_table;
  m_NumOfBuckets = pNewSize;
  m_NumOfTombstones = 0;
}

