Skip to content

Commit

Permalink
feat(hashtable): add grow_hashtable method
Browse files Browse the repository at this point in the history
feat(commands): add all length data showing to HLEN
chore(hashtable): change uint64 types to uint32
  • Loading branch information
aloima committed Oct 12, 2024
1 parent 2f326ce commit 804df73
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 29 deletions.
9 changes: 4 additions & 5 deletions headers/hashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ struct HashTable {
};

uint64_t hash(char *key);
struct HashTable *create_hashtable(uint64_t default_size, double grow_factor);
struct HashTable *create_hashtable(uint32_t default_size, double grow_factor);
struct FVPair *get_fv_from_hashtable(struct HashTable *table, char *name);
void free_hashtable(struct HashTable *table);

void set_fv_value(struct FVPair *pair, void *value);
void free_fv(struct FVPair *pair);
void set_fv_value(struct FVPair *fv, void *value);
void free_fv(struct FVPair *fv);

// void grow_hashtable(struct HashTable *table);
void set_fv_of_hashtable(struct HashTable *table, char *name, void *value, enum TellyTypes type);
void add_fv_to_hashtable(struct HashTable *table, char *name, void *value, enum TellyTypes type);
30 changes: 24 additions & 6 deletions src/commands/hashtable/hlen.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "../../../headers/database.h"
#include "../../../headers/commands.h"
#include "../../../headers/hashtable.h"
#include "../../../headers/utils.h"

#include <stdio.h>
#include <stdint.h>
Expand All @@ -15,18 +16,35 @@ static void run(struct Client *client, respdata_t *data) {

const char *key = data->value.array[1]->value.string.value;
const struct KVPair *kv = get_data(key);
const uint64_t count = (kv && kv->type == TELLY_HASHTABLE) ? kv->value->hashtable->size.all : 0;

const uint32_t buf_len = 3 + get_digit_count(count);
char buf[buf_len + 1];
sprintf(buf, ":%ld\r\n", count);
_write(client, buf, buf_len);
if (kv) {
if (kv->type == TELLY_HASHTABLE) {
struct HashTable *table = kv->value->hashtable;

const uint32_t buf_len = 59 + get_digit_count(table->size.allocated) +
get_digit_count(table->size.filled) + get_digit_count(table->size.all);

char buf[buf_len + 1];
sprintf(buf, (
"*3\r\n"
"+Allocated: %d\r\n"
"+Filled: %d\r\n"
"+All (includes next count): %d\r\n"
), table->size.allocated, table->size.filled, table->size.all);

_write(client, buf, buf_len);
} else {
_write(client, "-Invalid type for 'HLEN' command\r\n", 34);
}
} else {
_write(client, "$-1\r\n", 5);
}
}
}

struct Command cmd_hlen = {
.name = "HLEN",
.summary = "Returns field count of the hash table for the key.",
.summary = "Returns field count information of the hash table for the key.",
.since = "0.1.3",
.complexity = "O(1)",
.subcommands = NULL,
Expand Down
10 changes: 5 additions & 5 deletions src/commands/hashtable/hset.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static void run(struct Client *client, respdata_t *data) {
if (kv && kv->type == TELLY_HASHTABLE) {
table = kv->value->hashtable;
} else {
table = create_hashtable(32, 0.6);
table = create_hashtable(16, 0.5);
set_data(kv, key, (value_t) {
.hashtable = table
}, TELLY_HASHTABLE);
Expand All @@ -38,13 +38,13 @@ static void run(struct Client *client, respdata_t *data) {

if (is_integer(value)) {
int value_as_int = atoi(value);
set_fv_of_hashtable(table, name, &value_as_int, TELLY_INT);
add_fv_to_hashtable(table, name, &value_as_int, TELLY_INT);
} else if (is_true || streq(value, "false")) {
set_fv_of_hashtable(table, name, &is_true, TELLY_BOOL);
add_fv_to_hashtable(table, name, &is_true, TELLY_BOOL);
} else if (streq(value, "null")) {
set_fv_of_hashtable(table, name, NULL, TELLY_NULL);
add_fv_to_hashtable(table, name, NULL, TELLY_NULL);
} else {
set_fv_of_hashtable(table, name, value, TELLY_STR);
add_fv_to_hashtable(table, name, value, TELLY_STR);
}
}

Expand Down
34 changes: 30 additions & 4 deletions src/hashtable/grow.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
#include "../../headers/hashtable.h"
#include "../../headers/utils.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

void set_fv_of_hashtable(struct HashTable *table, char *name, void *value, enum TellyTypes type) {
// if (table->size.filled == table->size.allocated) grow_hashtable(table);
void grow_hashtable(struct HashTable *table) {
const uint32_t allocated_size = (table->size.allocated * (1 + table->grow_factor));
struct FVPair **fvs = calloc(allocated_size, sizeof(struct FVPair *));
table->size.filled = 0;

const uint64_t index = hash(name) % table->size.allocated;
for (uint32_t i = 0; i < table->size.allocated; ++i) {
struct FVPair *fv = table->fvs[i];

while (fv) {
struct FVPair *next = fv->next;
fv->next = NULL;
const uint32_t index = hash(fv->name.value) % allocated_size;
struct FVPair **area = &fvs[index];

if (!*area) table->size.filled += 1;
while (*area) area = &(*area)->next;

*area = fv;
fv = next;
}
}

free(table->fvs);
table->size.allocated = allocated_size;
table->fvs = fvs;
}

void add_fv_to_hashtable(struct HashTable *table, char *name, void *value, enum TellyTypes type) {
if (table->size.filled == table->size.allocated) grow_hashtable(table);

const uint32_t index = hash(name) % table->size.allocated;
table->size.all += 1;
table->size.filled += 1;

Expand Down
11 changes: 5 additions & 6 deletions src/hashtable/hashtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ uint64_t hash(char *key) {
char c;

while ((c = *key++)) hash = ((hash << 5) + hash) + c;

return 8;
return hash;
}

struct HashTable *create_hashtable(uint64_t default_size, double grow_factor) {
struct HashTable *create_hashtable(const uint32_t default_size, const double grow_factor) {
struct HashTable *table = malloc(sizeof(struct HashTable));
table->fvs = calloc(default_size, sizeof(struct FVPair *));
table->size.allocated = default_size;
Expand All @@ -25,17 +24,17 @@ struct HashTable *create_hashtable(uint64_t default_size, double grow_factor) {
}

struct FVPair *get_fv_from_hashtable(struct HashTable *table, char *name) {
const uint64_t index = hash(name) % table->size.allocated;
const uint32_t index = hash(name) % table->size.allocated;
struct FVPair *fv = table->fvs[index];

while (fv && !streq(fv->name.value, name)) fv = fv->next;
return fv;
}

void free_hashtable(struct HashTable *table) {
const uint64_t allocated_size = table->size.allocated;
const uint32_t allocated_size = table->size.allocated;

for (uint64_t i = 0; i < allocated_size; ++i) {
for (uint32_t i = 0; i < allocated_size; ++i) {
struct FVPair *fv = table->fvs[i];

while (fv) {
Expand Down
5 changes: 2 additions & 3 deletions src/utils/value.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

void write_value(struct Client *client, value_t value, enum TellyTypes type) {
switch (type) {
Expand Down Expand Up @@ -42,11 +41,11 @@ void write_value(struct Client *client, value_t value, enum TellyTypes type) {
break;

case TELLY_HASHTABLE:
_write(client, "+a hash table\r\n", 15);
_write(client, "+hash table\r\n", 13);
break;

case TELLY_LIST:
_write(client, "+a list\r\n", 9);
_write(client, "+list\r\n", 9);
break;

default:
Expand Down

0 comments on commit 804df73

Please sign in to comment.