Skip to content

Commit e5612f6

Browse files
committed
Created demonstration file
1 parent 01447d6 commit e5612f6

File tree

6 files changed

+108
-18
lines changed

6 files changed

+108
-18
lines changed

CMakeLists.txt

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@ set(CMAKE_C_STANDARD 11)
55

66
include_directories(include)
77

8-
add_executable(HashTable
9-
src/main.c src/hashtable.c src/article.c)
8+
add_executable(HashTableTests
9+
src/tests.c src/hashtable.c src/article.c)
10+
11+
add_executable(HashTableDemonstration
12+
src/demonstration.c src/hashtable.c src/article.c)

include/hashtable.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void ht_remove(HashTable_t* ht, const char* key);
2626
void ht_resize(HashTable_t* ht, unsigned long new_capacity);
2727
void ht_expand(HashTable_t* ht);
2828
void ht_shrink(HashTable_t* ht);
29-
void ht_display_states(HashTable_t* ht, FILE* out);
29+
void ht_display_states(const HashTable_t* ht, FILE* out);
3030
void ht_dump(const HashTable_t* ht, FILE* out);
3131

3232
#endif //HASH_TABLE_H

src/article.c

-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ Article_t* article_from_file(FILE* in)
102102
read_line_to(in, empty_article->doi);
103103
read_line_to(in, empty_article->title);
104104
read_line_to(in, empty_article->author);
105-
106105
fscanf(in, "%u\n", &empty_article->year);
107106

108107
return empty_article;

src/demonstration.c

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include <stdlib.h>
2+
3+
#include "article.h"
4+
#include "hashtable.h"
5+
6+
int main(void)
7+
{
8+
HashTable_t* ht = ht_new();
9+
10+
// Show initial state and capacity
11+
ht_display_states(ht, stdout);
12+
13+
const char* const key_one = "DOI_one";
14+
Article_t* article_one = make_article(key_one, "Some_Title", "Some Author", 2000);
15+
16+
const char* const key_two = "DOI_two";
17+
Article_t* article_two = make_article(key_two, "Another_Title", "Some other author", 2013);
18+
Article_t* article_two_v2 = make_article(key_two, "Another_Title", "Some other author et al.", 2015);
19+
20+
const char* const key_three = "Yet Another DOI";
21+
Article_t* article_three = make_article(key_three, "Last Title", "Last Author", 2011);
22+
23+
ht_insert(ht, article_one);
24+
ht_insert(ht, article_two);
25+
ht_insert(ht, article_three);
26+
ht_insert(ht, article_two_v2); // Inserting same key again only updates value already in table
27+
28+
delete_article(article_one);
29+
delete_article(article_two);
30+
delete_article(article_two_v2);
31+
delete_article(article_three);
32+
33+
// Should have 3 articles
34+
ht_display_states(ht, stdout);
35+
36+
// Searches
37+
printf("Articles in ht:\n");
38+
display_article(ht_fetch(ht, key_one), stdout);
39+
display_article(ht_fetch(ht, key_two), stdout);
40+
display_article(ht_fetch(ht, key_three), stdout);
41+
42+
// Non-existent keys can be queried through ht_contains
43+
const char* const non_existent_key = "HELLO I AM A DOI THAT DOES NOT EXIST";
44+
printf("%s in ht: %s\n", key_two, ht_contains(ht, key_two) ? "True" : "False");
45+
printf("%s in ht: %s\n", non_existent_key, ht_contains(ht, non_existent_key) ? "True" : "False");
46+
47+
// ht_fetch returns NULL for non-existent keys
48+
printf("Make sure this is NULL: %p\n", ht_fetch(ht, non_existent_key));
49+
50+
// Removing
51+
ht_remove(ht, key_one);
52+
ht_remove(ht, key_three);
53+
54+
// Removed keys are not in table anymore
55+
ht_display_states(ht, stdout);
56+
printf("%s in ht: %s\n", key_one, ht_contains(ht, key_one) ? "True" : "False");
57+
printf("%s in ht: %s\n", key_three, ht_contains(ht, key_three) ? "True" : "False");
58+
59+
// Removing non-valid key does nothing to the table
60+
ht_remove(ht, non_existent_key);
61+
ht_display_states(ht, stdout);
62+
63+
// Table can be expanded
64+
ht_expand(ht);
65+
ht_display_states(ht, stdout);
66+
67+
// ... and shrunk
68+
ht_shrink(ht);
69+
ht_display_states(ht, stdout);
70+
71+
// These last two operations don't work for file-loaded tables, sorry
72+
73+
// The table resizes manually to fit more keys (expand) or save memory (shrink) when if seems fit
74+
// But you can specify the size manually if you're feeling fancy!
75+
ht_resize(ht, 17); // After doing this, expand and shrink don't work anymore
76+
ht_display_states(ht, stdout);
77+
78+
// Table can be dumped to a file
79+
FILE* fp = fopen("demonstration_ht.txt", "w");
80+
ht_dump(ht, fp);
81+
82+
// You can still manipulate ht here...
83+
84+
ht_delete(ht);
85+
86+
// And read back from it
87+
freopen("demonstration_ht.txt", "r", fp);
88+
ht = ht_from_file(fp);
89+
90+
// Dumping / reading and/or resizing 'cleans' the 'REMOVED' cells of the table
91+
ht_display_states(ht, stdout);
92+
93+
ht_delete(ht);
94+
95+
return EXIT_SUCCESS;
96+
}

src/hashtable.c

+6-14
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ ht_index_t ht_hash_key(const HashTable_t* const ht, const char* key)
106106
return candidate_index;
107107
}
108108

109-
bool cell_at_index_has_key(const HashTable_t* ht, const ht_index_t i, const char* const key)
109+
bool item_at_index_has_key(const HashTable_t* ht, const ht_index_t i, const char* const key)
110110
{
111111
return ht->states[i] == OCCUPIED && article_has_key(ht->items[i], key);
112112
}
@@ -126,7 +126,7 @@ ht_index_t find_index_of_key(const HashTable_t* const ht, const char* const key)
126126
if (ht->states[current_index] == OPEN)
127127
return HT_KEY_NOT_FOUND;
128128

129-
if (cell_at_index_has_key(ht, current_index, key))
129+
if (item_at_index_has_key(ht, current_index, key))
130130
return current_index;
131131

132132
current_index = next_index_in_cycle(ht, current_index);
@@ -193,7 +193,7 @@ void ht_insert(HashTable_t* const ht, const Article_t* const article)
193193
if (ht->states[current_index] == OPEN)
194194
return insert_item_at_index(ht, article, current_index);
195195

196-
if (cell_at_index_has_key(ht, current_index, key_of(article)))
196+
if (item_at_index_has_key(ht, current_index, key_of(article)))
197197
return replace_item_at_index(ht, article, current_index);
198198

199199
current_index = next_index_in_cycle(ht, current_index);
@@ -266,7 +266,7 @@ bool item_at_index_was_hashed_directly(const HashTable_t* const ht, const ht_ind
266266
return ht_hash_key(ht, key_of(ht->items[i])) == i;
267267
}
268268

269-
void ht_display_states(HashTable_t* ht, FILE* out)
269+
void ht_display_states(const HashTable_t* const ht, FILE* out)
270270
{
271271
fprintf(out,
272272
"--- Ocupacao da tabela ---------------------------------------\n"
@@ -299,10 +299,7 @@ void ht_display_states(HashTable_t* ht, FILE* out)
299299
break;
300300

301301
case OCCUPIED:
302-
if (item_at_index_was_hashed_directly(ht, i))
303-
putc('H', out);
304-
else
305-
putc('C', out);
302+
putc(item_at_index_was_hashed_directly(ht, i) ? 'H' : 'C', out);
306303
break;
307304

308305
case REMOVED:
@@ -317,7 +314,7 @@ void ht_display_states(HashTable_t* ht, FILE* out)
317314
"-------------------------------------------------------------\n");
318315
}
319316

320-
ht_index_t read_capacity(FILE* in)
317+
ht_index_t read_capacity(FILE* const in)
321318
{
322319
ht_index_t capacity;
323320
fscanf(in, "%lu\n", &capacity);
@@ -332,7 +329,6 @@ HashTable_t* ht_from_file(FILE* const in)
332329

333330
while (!feof(in))
334331
{
335-
puts("Hey there");
336332
Article_t* a = article_from_file(in);
337333
ht_insert(ht, a);
338334
delete_article(a);
@@ -346,10 +342,6 @@ void ht_dump(const HashTable_t* ht, FILE* const out)
346342
fprintf(out, "%lu\n", ht->capacity);
347343

348344
for (ht_index_t i = 0; i < ht_capacity(ht); ++i)
349-
{
350345
if (ht->states[i] == OCCUPIED)
351-
{
352346
dump_article(ht->items[i], out);
353-
}
354-
}
355347
}

src/main.c renamed to src/tests.c

File renamed without changes.

0 commit comments

Comments
 (0)