~brenns10/sc-examples

ref: bb2c08bd2f3c21cf185feb43e2e449fcfdf4c5e2 sc-examples/hash-tester/hash-tester.c -rw-r--r-- 2.2 KiB
bb2c08bdStephen Brennan Update the hash-tester for version 0.2.0 of sc-collections 2 years ago
                                                                                
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
 * hash-tester.c: simple store or retrieve REPL to demo the hash table
 *
 * usage: hash-tester
 * > key=value
 * > key
 * value
 * > exit
 */
#define _POSIX_C_SOURCE 200809L

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

#include "sc-collections.h"

int main(int argc, char **argv)
{
	struct sc_hashtable hash;
	struct sc_iterator iter;
	char *line = NULL, *key, *value, *oldvalue, *index;
	size_t len = 0;
	size_t keylen, vallen;

	sc_ht_init(&hash, sc_ht_string_hash, sc_ht_string_comp, sizeof(char *),
	           sizeof(char *));

	printf("> ");
	while (getline(&line, &len, stdin) != -1) {
		/* remove newline */
		index = strchr(line, '\n');
		if (index)
			*index = '\0';

		if (strcmp(line, "exit") == 0)
			break;

		index = strchr(line, '=');
		if (index) {
			/* Set key=val */
			*index = '\0';
			key = line;

			/* Since we're creating a new value, we'll need to
			 * allocate a new buffer regardless. Do that now. */
			index++;
			vallen = strlen(index);
			value = malloc(vallen + 1);
			strncpy(value, index, vallen + 1);

			/* Check whether the key already exists in the hash */
			oldvalue = sc_ht_get_ptr(&hash, key);
			if (oldvalue) {
				/* If so, free the old value associated. */
				printf("deleting %s=%s\n", key, oldvalue);
				free(oldvalue);
			} else {
				/* If not, we'll need to allocate a new key
				 * object which will be stored into the hash. */
				keylen = strlen(line);
				key = malloc(keylen + 1);
				strncpy(key, line, keylen + 1);
			}
			sc_ht_insert_ptr(&hash, key, value);
		} else {
			value = sc_ht_get_ptr(&hash, line);
			if (value) {
				printf("%s\n", value);
			} else {
				printf("Not found!\n");
			}
		}
		printf("> ");
	}

	/* Free each key and value from the hash table. */
	iter = sc_ht_iter_keys_ptr(&hash);
	while (iter.has_next(&iter)) {
		key = iter.next(&iter);
		value = sc_ht_get_ptr(&hash, key);
		/* NOTE: here we do not use sc_ht_remove_ptr(). This is because
		 * modifying a hash while iterating is not yet supported.
		 * There's no harm in leaving values in the hash table as we
		 * free them; the hash table will never try to dereference
		 * pointers. */
		free(key);
		free(value);
	}
	iter.close(&iter);

	free(line);
	sc_ht_destroy(&hash);
}