summaryrefslogtreecommitdiff
path: root/word.c
blob: 1e8d56a0ab293d00bf15fddb761093e8dd4a08ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdlib.h>
#include <string.h>

#include "word.h"
#include "sdbm.h"

struct word_t *words;

void word_init() {
	words = malloc(sizeof(struct word_t) * WORDS_MAX);
	memset(words, 0, sizeof(struct word_t) * WORDS_MAX);
}

struct word_t *word_get(char *name) {
	unsigned long hash = sdbm(name);
	int index = hash % WORDS_MAX;

	struct word_t *word = &words[index];
	/* Fetch next word if hash doesn't match or the word differ (hash matching first). */
	while((word->hash != hash || (word->name && strcmp(name, word->name) != 0)) && word->next) word = word->next;
	/* Add new word if the word exists, but both hash and name doesn't match. */
	if(word->name && (word->hash != hash || strcmp(name, word->name) != 0)) {
		struct word_t *temp_word = malloc(sizeof(struct word_t));
		word->next = temp_word;
		word = temp_word;
		word->name = NULL;
	}
	if(!word->name) {
		word->hash = hash;
		word->name = strdup(name);
		word->count = 0;
		word->next = NULL;
	}
	return word;
}

void word_free() {
	struct word_t *word;
	for(int i = 0; i < WORDS_MAX; i++) {
		if(words[i].name)
			free(words[i].name);
		word = words[i].next;
		while(word) {
			struct word_t *temp = word->next;
			free(word->name);
			free(word);
			word = temp;
		}
	}
	free(words);
}