master
  1#include "hash.h"
  2#include "tuple.h"
  3#include <stdio.h>
  4#include <stdlib.h>
  5#include <string.h>
  6
  7/**
  8 * Initialize a new hash table.
  9 *
 10 * @param size The number of buckets to allocate for the chash table.
 11 * @return Returns the hash table.
 12 */
 13Hash *hash_init(int size) {
 14  Hash *hash = malloc(sizeof(Hash));
 15  hash->size = size;
 16  hash->buckets = calloc(size, sizeof(Node));
 17  return hash;
 18}
 19
 20/**
 21 * Computes a hash code for the given key.
 22 *
 23 * @param hash The hash table that the key is used in.
 24 * @param key The key to produce a hash code for
 25 * @return Returns a hash code for the given key.
 26 */
 27unsigned int hash_code(Hash *hash, int key) { return key % hash->size; }
 28
 29/**
 30 * A function to search for a specific key in a linked list.
 31 * This performs a O(n) search to find the matching key.
 32 * A possible optimization would be to convert this to do a binary
 33 * search for the given key using a binary search tree instead of a linked
 34 * list.
 35 *
 36 * @param list The linked list to search for the given key
 37 * @param key The key to search for in the linked list
 38 * @return Returns the data associated with the given key.
 39 */
 40void *search(Node *list, int key) {
 41  Node *current = list;
 42
 43  while (current) {
 44    Tuple *t = current->data;
 45    if (t->key == key)
 46      return t->value;
 47    current = current->next;
 48  }
 49
 50  return NULL;
 51}
 52
 53/**
 54 * A function to fetch a specify value from a hash table by key.
 55 *
 56 * @param hash The hash table to search.
 57 * @param key The key associated with the value to return
 58 * @return Returns the data associated with the key or NULL if the key is not
 59 * found.
 60 */
 61void *hash_get(Hash *hash, int key) {
 62  unsigned int bucket = hash_code(hash, key);
 63  Node *n = hash->buckets + bucket;
 64  return (n->data) ? search(n, key) : NULL;
 65}
 66
 67/**
 68 * A function to set the value associated with a key
 69 * in a hash table.
 70 *
 71 * @param hash The hash table to insert the key/value pair into
 72 * @param key The key associated with the value to insert.
 73 * @param value The value associated with the key to insert.
 74 */
 75void hash_set(Hash *hash, int key, void *value) {
 76  unsigned int bucket = hash_code(hash, key);
 77  Tuple *tuple = tuple_initialize(key, value);
 78  Node *n = hash->buckets + bucket;
 79
 80  if (n->data)
 81    list_add(n, tuple);
 82  else
 83    hash->buckets[bucket] = *list_initialize(tuple);
 84}
 85
 86/**
 87 * A function that pretty prints a key/value pair.
 88 *
 89 * @param data The Tuple to print.
 90 */
 91void print_tuple(void *data) {
 92  Tuple *t = data;
 93
 94  if (t)
 95    printf("(%d:%d)", t->key, t->value);
 96  else
 97    printf("(nil)");
 98}
 99
100/**
101 * Prints a visual representation of a hash table.
102 *
103 * @param hash The hash table to inspect
104 */
105void hash_inspect(Hash *hash) {
106  for (int i = 0; i < hash->size; i++) {
107    printf("%2d: ", i);
108    list_inspect(hash->buckets + i, print_tuple);
109  }
110}