commit b487b41
default
·
2022-11-21 10:14:24 +0000 UTC
parent 935089a
Backport from xs (new xs_set() API).
3 files changed,
+55,
-33
M
html.c
+5,
-3
1@@ -773,11 +773,13 @@ d_char *html_timeline(snac *snac, char *list, int local)
2 /* returns the HTML for the timeline */
3 {
4 d_char *s = xs_str_new(NULL);
5- xs_set *seen = xs_set_new(4096);
6+ xs_set seen;
7 char *v;
8 double t = ftime();
9 int num = 0;
10
11+ xs_set_init(&seen);
12+
13 s = html_user_header(snac, s, local);
14
15 if (!local)
16@@ -789,7 +791,7 @@ d_char *html_timeline(snac *snac, char *list, int local)
17 while (xs_list_iter(&list, &v)) {
18 xs *msg = timeline_get(snac, v);
19
20- s = html_entry(snac, s, msg, seen, local, 0, &num);
21+ s = html_entry(snac, s, msg, &seen, local, 0, &num);
22 }
23
24 s = xs_str_cat(s, "</div>\n");
25@@ -828,7 +830,7 @@ d_char *html_timeline(snac *snac, char *list, int local)
26
27 s = xs_str_cat(s, "</body>\n</html>\n");
28
29- xs_set_free(seen);
30+ xs_set_free(&seen);
31
32 return s;
33 }
M
xs_set.h
+49,
-29
1@@ -7,42 +7,40 @@
2 typedef struct _xs_set {
3 int elems; /* number of hash entries */
4 int used; /* number of used hash entries */
5+ int *hash; /* hashed offsets */
6 d_char *list; /* list of stored data */
7- int hash[]; /* hashed offsets */
8 } xs_set;
9
10-xs_set *xs_set_new(int elems);
11+void xs_set_init(xs_set *s);
12 void xs_set_free(xs_set *s);
13 int xs_set_add(xs_set *s, const char *data);
14
15
16 #ifdef XS_IMPLEMENTATION
17
18-xs_set *xs_set_new(int elems)
19-/* creates a new set with a maximum of size hashed data */
20-{
21- int sz = sizeof(struct _xs_set) + sizeof(int) * elems;
22- xs_set *s = xs_realloc(NULL, sz);
23-
24- memset(s, '\0', sz);
25
26- /* initialize */
27- s->elems = elems;
28- s->list = xs_list_new();
29+void xs_set_init(xs_set *s)
30+/* initializes a set */
31+{
32+ /* arbitrary default */
33+ s->elems = 256;
34+ s->used = 0;
35+ s->hash = xs_realloc(NULL, s->elems * sizeof(int));
36+ s->list = xs_list_new();
37
38- return s;
39+ memset(s->hash, '\0', s->elems * sizeof(int));
40 }
41
42
43 void xs_set_free(xs_set *s)
44 /* frees a set */
45 {
46- xs_free(s->list);
47- xs_free(s);
48+ s->hash = xs_free(s->hash);
49+ s->list = xs_free(s->list);
50 }
51
52
53-unsigned int _xs_set_hash(const char *data, int size)
54+static unsigned int _calc_hash(const char *data, int size)
55 {
56 unsigned int hash = 0x666;
57 int n;
58@@ -56,14 +54,12 @@ unsigned int _xs_set_hash(const char *data, int size)
59 }
60
61
62-int xs_set_add(xs_set *s, const char *data)
63-/* adds the data to the set */
64-/* returns: 1 if added, 0 if already there, -1 if it's full */
65+static int _store_hash(xs_set *s, const char *data, int value)
66 {
67 unsigned int hash, i;
68 int sz = xs_size(data);
69
70- hash = _xs_set_hash(data, sz);
71+ hash = _calc_hash(data, sz);
72
73 while (s->hash[(i = hash % s->elems)]) {
74 /* get the pointer to the stored data */
75@@ -77,21 +73,45 @@ int xs_set_add(xs_set *s, const char *data)
76 hash++;
77 }
78
79- /* is it full? fail */
80- if (s->used == s->elems / 2)
81- return -1;
82-
83- /* store the position */
84- s->hash[i] = xs_size(s->list);
85-
86- /* add the data */
87- s->list = xs_list_append_m(s->list, data, sz);
88+ /* store the new value */
89+ s->hash[i] = value;
90
91 s->used++;
92
93 return 1;
94 }
95
96+
97+int xs_set_add(xs_set *s, const char *data)
98+/* adds the data to the set */
99+/* returns: 1 if added, 0 if already there */
100+{
101+ /* is it 'full'? */
102+ if (s->used >= s->elems / 2) {
103+ char *p, *v;
104+
105+ /* expand! */
106+ s->elems *= 2;
107+ s->used = 0;
108+ s->hash = xs_realloc(s->hash, s->elems * sizeof(int));
109+
110+ memset(s->hash, '\0', s->elems * sizeof(int));
111+
112+ /* add the list elements back */
113+ p = s->list;
114+ while (xs_list_iter(&p, &v))
115+ _store_hash(s, v, v - s->list);
116+ }
117+
118+ int ret = _store_hash(s, data, xs_size(s->list));
119+
120+ /* if it's new, add the data */
121+ if (ret)
122+ s->list = xs_list_append_m(s->list, data, xs_size(data));
123+
124+ return ret;
125+}
126+
127 #endif /* XS_IMPLEMENTATION */
128
129 #endif /* XS_SET_H */
+1,
-1
1@@ -1 +1 @@
2-/* 1cde797082a259158b181f9c1e4bda4c5204109d */
3+/* a78beb97d364ff31cbaa504e275118afeaea7a59 */