Exemple #1
0
static void
mt_hash_insert_pair(MtHash* hash, MtPair* pair)
{
  assert(hash != NULL);
  assert(pair != NULL);

  size_t index = pair->key->hash % hash->size;
  MtPair* element = hash->buckets[index];

  // No Collision
  if (element == NULL)
  {
    hash->buckets[index] = pair;
    ++hash->length;

    // Expand the hash if necessary
    if (hash->length >= 0.75 * hash->size)
      mt_hash_double_size(hash);
  }

  // Collision handling, linear probing
  while (element != NULL)
  {
    // Key already exists in the hash, replace the value
    if (mt_string_compare(element->key, pair->key) == 0)
    {
      hash->buckets[index] = pair;
      return;
    }

    ++index;
    index %= hash->size;
    element = hash->buckets[index];
  }
}
Exemple #2
0
void
mt_hash_move_pair(MtHash* hash, MtPair* pair)
{
  assert(hash != NULL);
  assert(pair != NULL);

  // Can only be moved from another hash
  // Had better have a key if that is the case
  assert(pair->key->hash != 0);

  size_t index = pair->key->hash % hash->size;

  MtHashElement* element = &hash->buckets[index];
  assert(element != NULL);

  // Collision
  if (element->data != NULL)
  {
    // Standard Collision
    if (element->is_tree)
    {
      mt_tree_move_pair((MtTree*) element->data, pair);
    }
    // First Collision
    else
    {
      // Have to handle both pairs being moved into the tree
      MtPair* old_pair = element->data;

      element->data = mt_tree_new();

      mt_tree_move_pair((MtTree*) element->data, pair);
      mt_tree_move_pair((MtTree*) element->data, old_pair);

      element->is_tree = true;
    }
  }
  // No Collision
  else
  {
    element->data = pair;

    ++hash->length;

    // Grow the table if is 75% or more full
    if (hash->length >= 0.75 * hash->size)
      mt_hash_double_size(hash);
  }
}
Exemple #3
0
void
mt_hash_insert(MtHash* hash, MtString* key, void* value)
{
  assert(hash != NULL);
  assert(key != NULL);

  if (key->hash == 0)
    key->hash = Murmur3(mt_string_get_utf8(key), mt_string_get_length(key));

  size_t index = key->hash % hash->size;

  MtHashElement* element = &hash->buckets[index];
  assert(element != NULL);

  // Collision handling
  if (element->data != NULL)
  {
    if (element->is_tree)
    {
      // Collision, tree already made
      mt_tree_insert((MtTree *) element->data, key, value);
    }
    else
    {
      // First collision, make a tree
      MtPair* pair = element->data;

      element->data = mt_tree_new();
      mt_tree_move_pair((MtTree *) element->data, pair);
      
      ++hash->length;

      mt_tree_insert((MtTree *) element->data, key, value);

      element->is_tree = true;
    }
  }
  // No collision
  else
  {
    element->data = mt_pair_new(key, value);

    ++hash->length;

    if (hash->length >= 0.75 * hash->size)
      mt_hash_double_size(hash);
  }
}