summaryrefslogtreecommitdiff
path: root/xs_set.h
diff options
context:
space:
mode:
authorGravatar default2022-11-21 11:14:24 +0100
committerGravatar default2022-11-21 11:14:24 +0100
commitb487b41be63315b6c0994b43418fb3b4fd181d03 (patch)
tree11af29cfe81301e41bd548e429a714ad79bb5747 /xs_set.h
parentChanged debug level to grampa max_levels reached. (diff)
downloadsnac2-b487b41be63315b6c0994b43418fb3b4fd181d03.tar.gz
snac2-b487b41be63315b6c0994b43418fb3b4fd181d03.tar.xz
snac2-b487b41be63315b6c0994b43418fb3b4fd181d03.zip
Backport from xs (new xs_set() API).
Diffstat (limited to 'xs_set.h')
-rw-r--r--xs_set.h78
1 files changed, 49 insertions, 29 deletions
diff --git a/xs_set.h b/xs_set.h
index 0d76bed..bd1b8ea 100644
--- a/xs_set.h
+++ b/xs_set.h
@@ -7,42 +7,40 @@
7typedef struct _xs_set { 7typedef struct _xs_set {
8 int elems; /* number of hash entries */ 8 int elems; /* number of hash entries */
9 int used; /* number of used hash entries */ 9 int used; /* number of used hash entries */
10 int *hash; /* hashed offsets */
10 d_char *list; /* list of stored data */ 11 d_char *list; /* list of stored data */
11 int hash[]; /* hashed offsets */
12} xs_set; 12} xs_set;
13 13
14xs_set *xs_set_new(int elems); 14void xs_set_init(xs_set *s);
15void xs_set_free(xs_set *s); 15void xs_set_free(xs_set *s);
16int xs_set_add(xs_set *s, const char *data); 16int xs_set_add(xs_set *s, const char *data);
17 17
18 18
19#ifdef XS_IMPLEMENTATION 19#ifdef XS_IMPLEMENTATION
20 20
21xs_set *xs_set_new(int elems)
22/* creates a new set with a maximum of size hashed data */
23{
24 int sz = sizeof(struct _xs_set) + sizeof(int) * elems;
25 xs_set *s = xs_realloc(NULL, sz);
26
27 memset(s, '\0', sz);
28 21
29 /* initialize */ 22void xs_set_init(xs_set *s)
30 s->elems = elems; 23/* initializes a set */
31 s->list = xs_list_new(); 24{
25 /* arbitrary default */
26 s->elems = 256;
27 s->used = 0;
28 s->hash = xs_realloc(NULL, s->elems * sizeof(int));
29 s->list = xs_list_new();
32 30
33 return s; 31 memset(s->hash, '\0', s->elems * sizeof(int));
34} 32}
35 33
36 34
37void xs_set_free(xs_set *s) 35void xs_set_free(xs_set *s)
38/* frees a set */ 36/* frees a set */
39{ 37{
40 xs_free(s->list); 38 s->hash = xs_free(s->hash);
41 xs_free(s); 39 s->list = xs_free(s->list);
42} 40}
43 41
44 42
45unsigned int _xs_set_hash(const char *data, int size) 43static unsigned int _calc_hash(const char *data, int size)
46{ 44{
47 unsigned int hash = 0x666; 45 unsigned int hash = 0x666;
48 int n; 46 int n;
@@ -56,14 +54,12 @@ unsigned int _xs_set_hash(const char *data, int size)
56} 54}
57 55
58 56
59int xs_set_add(xs_set *s, const char *data) 57static int _store_hash(xs_set *s, const char *data, int value)
60/* adds the data to the set */
61/* returns: 1 if added, 0 if already there, -1 if it's full */
62{ 58{
63 unsigned int hash, i; 59 unsigned int hash, i;
64 int sz = xs_size(data); 60 int sz = xs_size(data);
65 61
66 hash = _xs_set_hash(data, sz); 62 hash = _calc_hash(data, sz);
67 63
68 while (s->hash[(i = hash % s->elems)]) { 64 while (s->hash[(i = hash % s->elems)]) {
69 /* get the pointer to the stored data */ 65 /* get the pointer to the stored data */
@@ -77,21 +73,45 @@ int xs_set_add(xs_set *s, const char *data)
77 hash++; 73 hash++;
78 } 74 }
79 75
80 /* is it full? fail */ 76 /* store the new value */
81 if (s->used == s->elems / 2) 77 s->hash[i] = value;
82 return -1;
83
84 /* store the position */
85 s->hash[i] = xs_size(s->list);
86
87 /* add the data */
88 s->list = xs_list_append_m(s->list, data, sz);
89 78
90 s->used++; 79 s->used++;
91 80
92 return 1; 81 return 1;
93} 82}
94 83
84
85int xs_set_add(xs_set *s, const char *data)
86/* adds the data to the set */
87/* returns: 1 if added, 0 if already there */
88{
89 /* is it 'full'? */
90 if (s->used >= s->elems / 2) {
91 char *p, *v;
92
93 /* expand! */
94 s->elems *= 2;
95 s->used = 0;
96 s->hash = xs_realloc(s->hash, s->elems * sizeof(int));
97
98 memset(s->hash, '\0', s->elems * sizeof(int));
99
100 /* add the list elements back */
101 p = s->list;
102 while (xs_list_iter(&p, &v))
103 _store_hash(s, v, v - s->list);
104 }
105
106 int ret = _store_hash(s, data, xs_size(s->list));
107
108 /* if it's new, add the data */
109 if (ret)
110 s->list = xs_list_append_m(s->list, data, xs_size(data));
111
112 return ret;
113}
114
95#endif /* XS_IMPLEMENTATION */ 115#endif /* XS_IMPLEMENTATION */
96 116
97#endif /* XS_SET_H */ \ No newline at end of file 117#endif /* XS_SET_H */ \ No newline at end of file