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
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 }
+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 */