Allow for static initialisation.
[libeze] / test-set.c
1
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <malloc.h>
6
7 #include "ez-set.h"
8
9 struct entry {
10         ez_node en;
11         char *value;
12 };
13
14 static unsigned int entry_hash(const void *d) {
15         const struct entry *e = d;
16
17         return ez_hash_string(e->value);
18 }
19
20 static int entry_equals(const void *d, const void *e) {
21         const struct entry *a = d;
22         const struct entry *b = e;
23
24         return strcmp(a->value, b->value) == 0;
25 }
26
27 static void entry_free(void *d) {
28         struct entry *a = d;
29
30         free(a->value);
31         free(a);
32 }
33
34 static int load_words(ez_set *set) {
35         FILE *fp = fopen("/usr/share/dict/words", "r");
36         char word[256];
37         int count = 0;
38
39         if (!fp)
40                 fp = fopen("words", "r");
41
42         if (fp) {
43                 while (fgets(word, 256, fp)) {
44                         size_t len = strlen(word);
45                         if (len > 0) {
46                                 struct entry *e = malloc(sizeof(*e));
47
48                                 word[len-1] = 0;
49                                 e->value = strdup(word);
50
51                                 e = ez_set_put(set, e);
52                                 if (e) {
53                                         printf("duplicate! %s\n", e->value);
54                                 }
55                                 count += 1;
56                         }
57                 }
58                 fclose(fp);
59         } else {
60                 for (int i=0;i<10000;i++) {
61                         struct entry *e = malloc(sizeof(*e));
62
63                         sprintf(word, "%x", i*7);
64                         e->value = strdup(word);
65
66                         e = ez_set_put(set, e);
67                         if (e) {
68                                 printf("duplicate! %s\n", e->value);
69                         }
70                         count += 1;
71                 }
72         }
73
74         return count;
75 }
76
77 int main(int argc, char **argv) {
78         ez_set setv, *set;
79         int count;
80
81         ez_set_init(&setv, entry_hash, entry_equals, entry_free);
82         set = &setv;
83
84         count = load_words(set);
85
86         // calc some stats
87         int min = 1000, max = 0;
88         int n = 0, t = 0;
89         int hist[64] = { 0 };
90         for (int i=0;i<=set->mask;i++) {
91                 int c = 0;
92                 for (ez_node *e = set->table[i];e;e=ez_node_next(e))
93                         c++;
94                 min = c < min ? c : min;
95                 max = c > max ? c : max;
96                 if (c != 0) {
97                         n += 1;
98                         t += c;
99                 }
100                 if (0 && c > 4) {
101                         printf(" %5d:", i);
102                         for (ez_node *e = set->table[i];e;e=ez_node_next(e)) {
103                                 char *value = ((struct entry *)e)->value;
104                                 printf(" %08x '%s'", set->hash(e), value);
105                         }
106                         printf("\n");
107                 }
108                 hist[c < 64 ? c : 63] += 1;
109         }
110         printf("chains %d length %d - %d  ave %f (> 0)\n", set->mask+1, min, max, (float)t / n);
111         max = max < 64 ? max : 63;
112         for (int i=0;i<=max;i++) {
113                 printf(" %5d: %d\n", i, hist[i]);
114         }
115         printf("\n");
116
117         {
118                 struct entry *e;
119                 struct entry key = {
120                         .value = "Abner"
121                 };
122                 e = ez_set_get(set, &key);
123                 printf("lookup %s = %p %s\n", key.value, e, e->value);
124                 key.value = "fuckwit";
125                 e = ez_set_get(set, &key);
126                 printf("lookup %s = %p %s\n", key.value, e, e ? e->value : "");
127         }
128
129         ez_set_scan scan;
130
131         // iterate
132         int ncount = 0;
133         for (struct entry *n = ez_set_scan_init(set, &scan); n ; n = ez_set_scan_next(&scan)) {
134                 ncount ++;
135         }
136         printf("size %d insert count %d scan count %d\n", ez_set_size(set), count, ncount);
137
138         printf("set_clear\n");
139         ez_set_clear(set);
140         printf(" size %d\n", ez_set_size(set));
141
142         count = load_words(set);
143
144         // iterate and clear all
145         struct entry *e;
146         e = ez_set_scan_init(set, &scan);
147         int rcount = 0;
148         while (e) {
149                 struct entry *p = e;
150
151                 e = ez_set_scan_remove(&scan);
152                 rcount ++;
153
154                 //printf(" %s\n", p->value);
155
156                 free(p->value);
157                 free(p);
158         }
159         printf("size %d remove count %d\n", ez_set_size(set), rcount);
160
161         ez_set_clear(set);
162 }