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}