Skip to content

Commit

Permalink
chore: rename record -> entry
Browse files Browse the repository at this point in the history
  • Loading branch information
exbotanical committed Jan 17, 2024
1 parent f3021bf commit 85b77dd
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 119 deletions.
44 changes: 22 additions & 22 deletions include/libhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

/**
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions src/hash_set.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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];
Expand All @@ -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++;
}

Expand Down Expand Up @@ -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) {
Expand Down
94 changes: 47 additions & 47 deletions src/hash_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand All @@ -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);
}
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -82,26 +82,26 @@ 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;

return r;
}

/**
* 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);
Expand All @@ -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++;
}

Expand All @@ -158,35 +158,35 @@ 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--;

return 1;
}

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);
}

Expand All @@ -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;
}
Expand All @@ -213,26 +213,26 @@ 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++;
}

return NULL;
}

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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/prime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading

0 comments on commit 85b77dd

Please sign in to comment.