-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest2.c
115 lines (102 loc) · 2.36 KB
/
test2.c
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rhmap.h"
typedef enum {false, true} bool; /* C89 compat */
struct entry {
char *name;
long number;
};
struct entry *create_entry(char *name, long number)
{
struct entry *e = malloc(sizeof(*e));
e->name = malloc(strlen(name));
strcpy(e->name, name);
e->number = number;
return e;
}
void destroy_entry(struct entry *e)
{
free(e->name);
free(e);
}
RHMAP_DECLARE(phonebook, struct entry *)
#define INIT_SIZE 64
struct phonebook *create_phonebook(void)
{
struct phonebook *p = malloc(sizeof(*p));
struct phonebook_bucket *b = malloc(INIT_SIZE);
phonebook_init(p, b, INIT_SIZE);
return p;
}
void destroy_phonebook(struct phonebook *p)
{
phonebook_clear(p, destroy_entry);
free(p->buckets);
free(p);
}
#define LOAD_THRESHOLD 0.9
bool maybe_resize(struct phonebook *p)
{
size_t s;
struct phonebook_bucket *b;
if ((double)p->population/p->capacity < LOAD_THRESHOLD)
return false;
s = sizeof(*b) * p->capacity * 2;
b = malloc(s);
free(phonebook_rehash(p, b, s));
return true;
}
size_t djb2(const char *str, size_t n)
{
size_t k = 5381;
while (n --> 0)
k = (k << 5) + k + *str++;
return k;
}
int main()
{
struct phonebook *book = create_phonebook();
puts("Available commands:");
puts("set <name> <number>");
puts("get <name>");
puts("del <name>");
for (;;) {
char buf[160], name[80];
long num;
if (fgets(buf, sizeof(buf), stdin) == NULL)
break;
if (sscanf(buf, "set %s %ld", name, &num) >= 2) {
unsigned long h = djb2(name, strlen(name));
struct entry **e = phonebook_search(book, h);
if (e != NULL) {
(*e)->number = num;
puts("Updated");
} else if (phonebook_insert(book, h, create_entry(name, num)) != NULL) {
puts("Inserted");
} else {
puts("Failed");
}
if (maybe_resize(book))
printf("Resized to %lu\n", book->capacity);
} else if (sscanf(buf, "get %s", name) >= 1) {
struct entry **e = phonebook_search(book, djb2(name, strlen(name)));
if (e != NULL)
printf("%s: %ld\n", (*e)->name, (*e)->number);
else
puts("Not found");
} else if (sscanf(buf, "del %s", name) >= 1) {
struct entry **e = phonebook_remove(book, djb2(name, strlen(name)));
if (e != NULL) {
destroy_entry(*e);
puts("Deleted");
} else {
puts("Not found");
}
} else {
puts("Unknown command");
}
}
destroy_phonebook(book);
return 0;
}