Пример #1
0
void hkl_hash_move_pair(HklHash* hash, HklPair* pair)
{
  assert(hash != NULL);
  assert(pair != NULL);

  // The pair had better have a hash
  // If we are moving, then the old pair's key must
  // have a hash in it
  assert(pair->key->hash != 0);

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

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

  if (element->data != NULL)
  {
    if (element->is_tree)
    {
      hkl_tree_move_pair((HklTree*) element->data, pair);
    }
    else
    {
      // First Collision
      // Since we are moving both pairs into the tree,
      // (the old pair and new one coming in) we need a handle to
      // the old pair.
      HklPair* oldpair = element->data;

      element->data = hkl_tree_new();
      hkl_tree_move_pair((HklTree*) element->data, pair);

      hkl_tree_move_pair((HklTree*) element->data, oldpair);

      // Mark the element as a tree
      element->is_tree = true;
    }
  }
  else
  {
    // Nothing exists here. Assign it the pair
    element->data = pair;

    // The number of entries of the table increases
    ++hash->length;

    // If the hash table is 75% full
    if (hash->length >= 0.75*hash->size)
    {
      // Grow the table
      hkl_hash_double(hash);
    }
  }
}
Пример #2
0
void hkl_hash_insert(HklHash* hash, HklString* key, void* value)
{
  assert(hash != NULL);
  assert(key != NULL);

  // The string doesnt already have a hash
  // give it one
  if (key->hash == 0)
    key->hash = Murmur3(hkl_string_get_utf8(key), hkl_string_get_length(key));

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

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

  // Collision
  if (element->data != NULL)
  {
    if (element->is_tree)
    {
      hkl_tree_insert((HklTree*) element->data, key, value);
    }
    else
    {
      // First Collision
      HklPair* pair = element->data;

      element->data = hkl_tree_new();
      hkl_tree_move_pair((HklTree*) element->data, pair);

      hkl_tree_insert((HklTree*) element->data, key, value);
      
      ++hash->length;

      // Mark the element as a tree
      element->is_tree = true;
    }
  }
  // No Collision
  else
  {
    // Nothing exists here. Make a pair
    element->data = hkl_pair_new_from_data(key, value);

    // The number of entries of the table increases
    ++hash->length;

    // If the hash table is 75% full
    if (hash->length >= 0.75*hash->size)
      hkl_hash_double(hash);
  }
}
Пример #3
0
int main(int argc, const char* argv[])
{

  HklTree* testtree = hkl_tree_new();
  HklString* testname = hkl_string_new();

  // Registered tests

  // This line gives the function "hashtest" defined in test/hash.c
  // external linkage. If you don't know what that means, don't worry bout it.
  // :P :3
  extern HklTestFunction hashtest;
  hkl_string_set_utf8(testname, "hash");
  hkl_tree_insert(testtree, testname, &hashtest);

  extern HklTestFunction gctest;
  hkl_string_set_utf8(testname, "gc");
  hkl_tree_insert(testtree, testname, &gctest);

  extern HklTestFunction traversaltest;
  hkl_string_set_utf8(testname, "traversal");
  hkl_tree_insert(testtree, testname, &traversaltest);

  if (argv[1] == NULL)
  {
    fprintf(stderr, "No test given. Exiting.\n");
    return 1;
  }

  hkl_string_set_utf8(testname, argv[1]);
  HklPair* pair = hkl_tree_search(testtree, testname);
  if (pair == NULL)
  {
    fprintf(stderr, "Test \"%s\" does not exist!\n", argv[1]);
    return 1;
  }
  
  HklTestFunction test = pair->value;

  if (test)
    test(&argv[2]);

  hkl_string_free(testname);
  hkl_tree_free(testtree);
  
  return 0;
}