diff --git a/include/libhash.h b/include/libhash.h index 1becdb9..010820b 100644 --- a/include/libhash.h +++ b/include/libhash.h @@ -5,19 +5,19 @@ #define HS_DEFAULT_CAPACITY 50 /** - * A hash table record i.e. key / value pair + * A hash table entry i.e. key / value pair */ typedef struct { char *key; void *value; -} ht_record; +} ht_entry; /** * A hash table */ typedef struct { /** - * Max number of records which may be stored in the hash table. Adjustable. + * Max number of entries which may be stored in the hash table. Adjustable. * Calculated as the first prime subsequent to the base capacity. */ int capacity; @@ -28,14 +28,14 @@ typedef struct { int base_capacity; /** - * Number of non-NULL records in the hash table + * Number of non-NULL entries in the hash table */ int count; /** - * The hash table's records + * The hash table's entries */ - ht_record **records; + ht_entry **entries; } hash_table; /** @@ -57,8 +57,8 @@ void ht_insert(hash_table *ht, const char *key, void *value); /** * Insert a key, value pair into the given hash table. * - * This version of ht_insert will also free the record value. - * Thus, the record value must be allocated on the heap. + * This version of ht_insert will also free the entry value. + * Thus, the entry value must be allocated on the heap. * * @param ht * @param key @@ -67,12 +67,12 @@ void ht_insert(hash_table *ht, const char *key, void *value); void ht_insert_ptr(hash_table *ht, const char *key, void *value); /** - * Search for the record corresponding to the given key + * Search for the entry corresponding to the given key * * @param ht * @param key */ -ht_record *ht_search(hash_table *ht, const char *key); +ht_entry *ht_search(hash_table *ht, const char *key); /** * Eagerly retrieve the value inside of the entry stored at the given key. @@ -93,40 +93,40 @@ void ht_delete_table(hash_table *ht); /** * Delete a hash table and deallocate its memory * - * This version of ht_delete_table will also free the record value. - * Thus, the record value must be allocated on the heap. + * This version of ht_delete_table will also free the entry value. + * Thus, the entry value must be allocated on the heap. * * @param ht Hash table to delete */ void ht_delete_table_ptr(hash_table *ht); /** - * Delete a record for the given key `key`. Because records + * Delete a entry for the given key `key`. Because entries * may be part of a collision chain, and removing them completely - * could cause infinite lookup attempts, we replace the deleted record - * with a NULL sentinel record. + * could cause infinite lookup attempts, we replace the deleted entry + * with a NULL sentinel entry. * * @param ht * @param key * - * @return 1 if a record was deleted, 0 if no record corresponding + * @return 1 if a entry was deleted, 0 if no entry corresponding * to the given key could be found */ int ht_delete(hash_table *ht, const char *key); /** - * Delete a record for the given key `key`. Because records + * Delete a entry for the given key `key`. Because entries * may be part of a collision chain, and removing them completely - * could cause infinite lookup attempts, we replace the deleted record - * with a NULL sentinel record. + * could cause infinite lookup attempts, we replace the deleted entry + * with a NULL sentinel entry. * - * This version of ht_delete will also free the record value. - * Thus, the record value must be allocated on the heap. + * This version of ht_delete will also free the entry value. + * Thus, the entry value must be allocated on the heap. * * @param ht * @param key * - * @return 1 if a record was deleted, 0 if no record corresponding + * @return 1 if a entry was deleted, 0 if no entry corresponding * to the given key could be found */ int ht_delete_ptr(hash_table *ht, const char *key); diff --git a/src/hash.c b/src/hash.c index e45b661..5139830 100644 --- a/src/hash.c +++ b/src/hash.c @@ -18,8 +18,8 @@ static const int H_PRIME_2 = 163; static int h_hash(const char *key, const int prime, const int capacity) { long hash = 0; - const int len_s = strlen(key); - for (int i = 0; i < len_s; i++) { + const size_t len_s = strlen(key); + for (unsigned int i = 0; i < len_s; i++) { // convert the key to a large integer hash += (long)pow(prime, len_s - (i + 1)) * key[i]; // reduce said large integer to a fixed range diff --git a/src/hash_set.c b/src/hash_set.c index 774b1a2..2fc0e79 100644 --- a/src/hash_set.c +++ b/src/hash_set.c @@ -25,7 +25,7 @@ static void hs_resize(hash_set *hs, const int base_capacity) { hash_set *new_hs = hs_init(base_capacity); - for (int i = 0; i < hs->capacity; i++) { + for (unsigned int i = 0; i < hs->capacity; i++) { const char *r = hs->keys[i]; if (r != NULL) { @@ -104,7 +104,7 @@ void hs_insert(hash_set *hs, const void *key) { hs_resize_up(hs); } - void *new_record = strdup(key); + void *new_entry = strdup(key); int idx = h_resolve_hash(key, hs->capacity, 0); char *current_key = hs->keys[idx]; @@ -118,12 +118,12 @@ void hs_insert(hash_set *hs, const void *key) { } // TODO: verify i is 1.. - idx = h_resolve_hash(new_record, hs->capacity, i); + idx = h_resolve_hash(new_entry, hs->capacity, i); current_key = hs->keys[idx]; i++; } - hs->keys[idx] = new_record; + hs->keys[idx] = new_entry; hs->count++; } @@ -152,7 +152,7 @@ int hs_contains(hash_set *hs, const char *key) { } void hs_delete_set(hash_set *hs) { - for (int i = 0; i < hs->capacity; i++) { + for (unsigned int i = 0; i < hs->capacity; i++) { char *r = hs->keys[i]; if (r != NULL) { diff --git a/src/hash_table.c b/src/hash_table.c index 612c470..2142192 100644 --- a/src/hash_table.c +++ b/src/hash_table.c @@ -7,7 +7,7 @@ #include "prime.h" #include "strdup/strdup.h" -static ht_record HT_RECORD_SENTINEL = {NULL, NULL}; +static ht_entry HT_SENTINEL_ENTRY = {NULL, NULL}; static void __ht_insert(hash_table *ht, const char *key, void *value, bool free_value); @@ -18,9 +18,9 @@ static void __ht_delete_table(hash_table *ht, bool free_value); * Resize the hash table. This implementation has a set capacity; * hash collisions rise beyond the capacity and `ht_insert` will fail. * To mitigate this, we resize up if the load (measured as the ratio of - * records count to capacity) is less than .1, or down if the load exceeds + * entries count to capacity) is less than .1, or down if the load exceeds * .7. To resize, we create a new table approx. 1/2x or 2x times the current - * table size, then insert into it all non-deleted records. + * table size, then insert into it all non-deleted entries. * * @param ht * @param base_capacity @@ -34,10 +34,10 @@ static void ht_resize(hash_table *ht, const int base_capacity, hash_table *new_ht = ht_init(base_capacity); - for (int i = 0; i < ht->capacity; i++) { - ht_record *r = ht->records[i]; + for (unsigned int i = 0; i < ht->capacity; i++) { + ht_entry *r = ht->entries[i]; - if (r != NULL && r != &HT_RECORD_SENTINEL) { + if (r != NULL && r != &HT_SENTINEL_ENTRY) { __ht_insert(new_ht, r->key, r->value, free_value); } } @@ -50,9 +50,9 @@ static void ht_resize(hash_table *ht, const int base_capacity, ht->capacity = new_ht->capacity; new_ht->capacity = tmp_capacity; - ht_record **tmp_records = ht->records; - ht->records = new_ht->records; - new_ht->records = tmp_records; + ht_entry **tmp_entries = ht->entries; + ht->entries = new_ht->entries; + new_ht->entries = tmp_entries; ht_delete_table(new_ht); } @@ -82,14 +82,14 @@ static void ht_resize_down(hash_table *ht, bool free_value) { } /** - * Initialize a new hash table record with the given k, v pair + * Initialize a new hash table entry with the given k, v pair * - * @param k Record key - * @param v Record value - * @return ht_record* + * @param k entry key + * @param v entry value + * @return ht_entry* */ -static ht_record *ht_record_init(const char *k, void *v) { - ht_record *r = malloc(sizeof(ht_record)); +static ht_entry *ht_entry_init(const char *k, void *v) { + ht_entry *r = malloc(sizeof(ht_entry)); r->key = strdup(k); r->value = v; @@ -97,11 +97,11 @@ static ht_record *ht_record_init(const char *k, void *v) { } /** - * Delete a record and deallocate its memory + * Delete a entry and deallocate its memory * - * @param r Record to delete + * @param r entry to delete */ -static void ht_delete_record(ht_record *r, bool free_value) { +static void ht_delete_entry(ht_entry *r, bool free_value) { free(r->key); if (free_value) { free(r->value); @@ -121,30 +121,30 @@ static void __ht_insert(hash_table *ht, const char *key, void *value, ht_resize_up(ht, free_value); } - ht_record *new_record = ht_record_init(key, value); + ht_entry *new_entry = ht_entry_init(key, value); - int idx = h_resolve_hash(new_record->key, ht->capacity, 0); + int idx = h_resolve_hash(new_entry->key, ht->capacity, 0); - ht_record *current_record = ht->records[idx]; + ht_entry *current_entry = ht->entries[idx]; int i = 1; // i.e. if there was a collision - while (current_record != NULL && current_record != &HT_RECORD_SENTINEL) { + while (current_entry != NULL && current_entry != &HT_SENTINEL_ENTRY) { // update existing key/value - if (strcmp(current_record->key, key) == 0) { - ht_delete_record(current_record, free_value); - ht->records[idx] = new_record; + if (strcmp(current_entry->key, key) == 0) { + ht_delete_entry(current_entry, free_value); + ht->entries[idx] = new_entry; return; } // TODO verify i is 1.. - idx = h_resolve_hash(new_record->key, ht->capacity, i); - current_record = ht->records[idx]; + idx = h_resolve_hash(new_entry->key, ht->capacity, i); + current_entry = ht->entries[idx]; i++; } - ht->records[idx] = new_record; + ht->entries[idx] = new_entry; ht->count++; } @@ -158,12 +158,12 @@ static int __ht_delete(hash_table *ht, const char *key, bool free_value) { int i = 0; int idx = h_resolve_hash(key, ht->capacity, i); - ht_record *current_record = ht->records[idx]; + ht_entry *current_entry = ht->entries[idx]; - while (current_record != NULL && current_record != &HT_RECORD_SENTINEL) { - if (strcmp(current_record->key, key) == 0) { - ht_delete_record(current_record, free_value); - ht->records[idx] = &HT_RECORD_SENTINEL; + while (current_entry != NULL && current_entry != &HT_SENTINEL_ENTRY) { + if (strcmp(current_entry->key, key) == 0) { + ht_delete_entry(current_entry, free_value); + ht->entries[idx] = &HT_SENTINEL_ENTRY; ht->count--; @@ -171,22 +171,22 @@ static int __ht_delete(hash_table *ht, const char *key, bool free_value) { } idx = h_resolve_hash(key, ht->capacity, ++i); - current_record = ht->records[idx]; + current_entry = ht->entries[idx]; } return 0; } static void __ht_delete_table(hash_table *ht, bool free_value) { - for (int i = 0; i < ht->capacity; i++) { - ht_record *r = ht->records[i]; + for (unsigned int i = 0; i < ht->capacity; i++) { + ht_entry *r = ht->entries[i]; - if (r != NULL && r != &HT_RECORD_SENTINEL) { - ht_delete_record(r, free_value); + if (r != NULL && r != &HT_SENTINEL_ENTRY) { + ht_delete_entry(r, free_value); } } - free(ht->records); + free(ht->entries); free(ht); } @@ -200,7 +200,7 @@ hash_table *ht_init(int base_capacity) { ht->capacity = next_prime(ht->base_capacity); ht->count = 0; - ht->records = calloc((size_t)ht->capacity, sizeof(ht_record *)); + ht->entries = calloc((size_t)ht->capacity, sizeof(ht_entry *)); return ht; } @@ -213,18 +213,18 @@ void ht_insert_ptr(hash_table *ht, const char *key, void *value) { __ht_insert(ht, key, value, true); } -ht_record *ht_search(hash_table *ht, const char *key) { +ht_entry *ht_search(hash_table *ht, const char *key) { int idx = h_resolve_hash(key, ht->capacity, 0); - ht_record *current_record = ht->records[idx]; + ht_entry *current_entry = ht->entries[idx]; int i = 1; - while (current_record != NULL && current_record != &HT_RECORD_SENTINEL) { - if (strcmp(current_record->key, key) == 0) { - return current_record; + while (current_entry != NULL && current_entry != &HT_SENTINEL_ENTRY) { + if (strcmp(current_entry->key, key) == 0) { + return current_entry; } idx = h_resolve_hash(key, ht->capacity, i); - current_record = ht->records[idx]; + current_entry = ht->entries[idx]; i++; } @@ -232,7 +232,7 @@ ht_record *ht_search(hash_table *ht, const char *key) { } void *ht_get(hash_table *ht, const char *key) { - ht_record *r = ht_search(ht, key); + ht_entry *r = ht_search(ht, key); return r ? r->value : NULL; } diff --git a/src/prime.c b/src/prime.c index b83860c..c722bcf 100644 --- a/src/prime.c +++ b/src/prime.c @@ -18,7 +18,7 @@ int is_prime(const int x) { if ((x % 2) == 0) { return 0; } - for (int i = 3; i <= floor(sqrt((double)x)); i += 2) { + for (unsigned int i = 3; i <= floor(sqrt((double)x)); i += 2) { if ((x % i) == 0) { return 0; } diff --git a/t/hash_set_test.c b/t/hash_set_test.c index 426a59a..f0ceec4 100644 --- a/t/hash_set_test.c +++ b/t/hash_set_test.c @@ -66,7 +66,7 @@ void test_contains(void) { ok(hs_contains(hs, k4) == 0, "returns 0 if the search does not yield a key"); hs_delete(hs, k1); - ok(hs_contains(hs, k1) == 0, "returns 0 if the record was deleted"); + ok(hs_contains(hs, k1) == 0, "returns 0 if the entry was deleted"); } void test_delete(void) { @@ -90,18 +90,18 @@ void test_delete(void) { ok(hs_delete(hs, k1) == 0, "cannot delete the same key twice"); ok(hs_contains(hs, "k1") == 0, - "returns 0 because the record has been deleted"); + "returns 0 because the entry has been deleted"); ok(hs_contains(hs, "k2") == 0, - "returns 0 because the record has been deleted"); + "returns 0 because the entry has been deleted"); ok(hs_contains(hs, "k3") == 0, - "returns 0 because the record has been deleted"); + "returns 0 because the entry has been deleted"); } void test_capacity(void) { int initial_cap = 23; hash_set *hs = hs_init(initial_cap); - for (int i = 0; i < initial_cap; i++) { + for (unsigned int i = 0; i < initial_cap; i++) { double digits = i == 0 ? 1 : floor(log10(abs(i))) + 1; char buf[(int)digits + 2]; @@ -125,7 +125,7 @@ void test_contains_miss(void) { ok(hs_contains(hs, "key2") == 0, "does not contain the key"); } -int main(int argc, char *argv[]) { +int main() { plan(31); test_initialization(); diff --git a/t/hash_table_test.c b/t/hash_table_test.c index d36e02e..35837be 100644 --- a/t/hash_table_test.c +++ b/t/hash_table_test.c @@ -13,7 +13,7 @@ void test_initialization(void) { char *v = "value"; hash_table *ht = ht_init(capacity); - ht_record *r = ht_record_init(k, v); + ht_entry *r = ht_entry_init(k, v); ok(ht != NULL, "hash table is not NULL"); ok(ht->base_capacity == capacity, "given base capacity has been set"); @@ -27,7 +27,7 @@ void test_initialization(void) { is(r->key, k, "key match"); is(r->value, v, "value match"); - lives_ok({ ht_delete_record(r, false); }, "frees the record heap memory"); + lives_ok({ ht_delete_entry(r, false); }, "frees the entry heap memory"); } void test_insert(void) { @@ -35,10 +35,10 @@ void test_insert(void) { ht_insert(ht, "k1", "v1"); - ok(ht->count == 1, "increments the count when a record is inserted"); + ok(ht->count == 1, "increments the count when a entry is inserted"); ht_insert(ht, "k2", "v2"); - ok(ht->count == 2, "increments the count when another record is inserted"); + ok(ht->count == 2, "increments the count when another entry is inserted"); is(ht_get(ht, "k1"), "v1", "retrieves the correct value"); is(ht_get(ht, "k2"), "v2", "retrieves the correct value"); @@ -54,7 +54,7 @@ void test_insert(void) { ht_insert(ht, "k1", "v1"); ok(ht->count == 2, "count after insertion"); is(ht_get(ht, "k1"), "v1", - "inserts the record clean after having been deleted"); + "inserts the entry clean after having been deleted"); } void test_search(void) { @@ -69,10 +69,10 @@ void test_search(void) { is(ht_get(ht, "k2"), "v2", "retrieves the value"); is(ht_get(ht, "k3"), "v3", "retrieves the value"); is(ht_get(ht, "k4"), NULL, - "returns NULL if the search does not yield a record"); + "returns NULL if the search does not yield a entry"); ht_delete(ht, "k1"); - is(ht_get(ht, "k1"), NULL, "returns NULL if the record was deleted"); + is(ht_get(ht, "k1"), NULL, "returns NULL if the entry was deleted"); } void test_delete(void) { @@ -82,20 +82,17 @@ void test_delete(void) { ht_insert(ht, "k2", "v2"); ht_insert(ht, "k3", "v3"); - ok(ht_delete(ht, "k1") == 1, "returns 1 when record deletion was successful"); - ok(ht_delete(ht, "k2") == 1, "returns 1 when record deletion was successful"); - ok(ht_delete(ht, "k3") == 1, "returns 1 when record deletion was successful"); + ok(ht_delete(ht, "k1") == 1, "returns 1 when entry deletion was successful"); + ok(ht_delete(ht, "k2") == 1, "returns 1 when entry deletion was successful"); + ok(ht_delete(ht, "k3") == 1, "returns 1 when entry deletion was successful"); ok(ht_delete(ht, "k4") == 0, - "returns 0 when record deletion was unsuccessful"); - ok(ht_delete(ht, "k1") == 0, "cannot delete the same record twice"); - - is(ht_get(ht, "k1"), NULL, - "returns NULL because the record has been deleted"); - is(ht_get(ht, "k2"), NULL, - "returns NULL because the record has been deleted"); - is(ht_get(ht, "k3"), NULL, - "returns NULL because the record has been deleted"); + "returns 0 when entry deletion was unsuccessful"); + ok(ht_delete(ht, "k1") == 0, "cannot delete the same entry twice"); + + is(ht_get(ht, "k1"), NULL, "returns NULL because the entry has been deleted"); + is(ht_get(ht, "k2"), NULL, "returns NULL because the entry has been deleted"); + is(ht_get(ht, "k3"), NULL, "returns NULL because the entry has been deleted"); } void test_capacity(void) { @@ -129,30 +126,27 @@ void test_delete_ptr(void) { ht_insert_ptr(ht, "k3", v3); ok(ht_delete_ptr(ht, "k1") == 1, - "returns 1 when record deletion was successful"); + "returns 1 when entry deletion was successful"); ok(ht_delete_ptr(ht, "k2") == 1, - "returns 1 when record deletion was successful"); + "returns 1 when entry deletion was successful"); ok(ht_delete_ptr(ht, "k3") == 1, - "returns 1 when record deletion was successful"); + "returns 1 when entry deletion was successful"); ok(ht_delete_ptr(ht, "k4") == 0, - "returns 0 when record deletion was unsuccessful"); - ok(ht_delete_ptr(ht, "k1") == 0, "cannot delete the same record twice"); + "returns 0 when entry deletion was unsuccessful"); + ok(ht_delete_ptr(ht, "k1") == 0, "cannot delete the same entry twice"); - is(ht_get(ht, "k1"), NULL, - "returns NULL because the record has been deleted"); - is(ht_get(ht, "k2"), NULL, - "returns NULL because the record has been deleted"); - is(ht_get(ht, "k3"), NULL, - "returns NULL because the record has been deleted"); + is(ht_get(ht, "k1"), NULL, "returns NULL because the entry has been deleted"); + is(ht_get(ht, "k2"), NULL, "returns NULL because the entry has been deleted"); + is(ht_get(ht, "k3"), NULL, "returns NULL because the entry has been deleted"); // It'll be some junk value - just not the og value. - isnt(v1, "v1", "frees the record value"); - isnt(v2, "v2", "frees the record value"); - isnt(v3, "v3", "frees the record value"); + isnt(v1, "v1", "frees the entry value"); + isnt(v2, "v2", "frees the entry value"); + isnt(v3, "v3", "frees the entry value"); } -int main(int argc, char *argv[]) { +int main() { plan(44); test_initialization(); diff --git a/t/prime_test.c b/t/prime_test.c index b3ec90e..4f1b392 100644 --- a/t/prime_test.c +++ b/t/prime_test.c @@ -7,7 +7,7 @@ static const int prime_map[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 67, 71, 73, 79, 83, 89, 97}; void test_is_prime(void) { - for (int i = 0; i < sizeof(prime_map) / sizeof(int); i++) { + for (unsigned int i = 0; i < sizeof(prime_map) / sizeof(int); i++) { int prime = prime_map[i]; ok(is_prime(prime) == 1, "expected prime %d", prime); @@ -15,7 +15,7 @@ void test_is_prime(void) { } void test_next_prime(void) { - for (int i = 2; i < sizeof(prime_map) / sizeof(int); i++) { + for (unsigned int i = 2; i < sizeof(prime_map) / sizeof(int); i++) { int prime = prime_map[i]; ok(next_prime(prime - 1) == prime_map[i], "expected next prime %d", prime);