summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar default2022-11-21 11:14:24 +0100
committerGravatar default2022-11-21 11:14:24 +0100
commitb487b41be63315b6c0994b43418fb3b4fd181d03 (patch)
tree11af29cfe81301e41bd548e429a714ad79bb5747
parentChanged debug level to grampa max_levels reached. (diff)
downloadpenes-snac2-b487b41be63315b6c0994b43418fb3b4fd181d03.tar.gz
penes-snac2-b487b41be63315b6c0994b43418fb3b4fd181d03.tar.xz
penes-snac2-b487b41be63315b6c0994b43418fb3b4fd181d03.zip
Backport from xs (new xs_set() API).
-rw-r--r--html.c8
-rw-r--r--xs_set.h78
-rw-r--r--xs_version.h2
3 files changed, 55 insertions, 33 deletions
diff --git a/html.c b/html.c
index dc35062..2743be9 100644
--- a/html.c
+++ b/html.c
@@ -773,11 +773,13 @@ d_char *html_timeline(snac *snac, char *list, int local)
773/* returns the HTML for the timeline */ 773/* returns the HTML for the timeline */
774{ 774{
775 d_char *s = xs_str_new(NULL); 775 d_char *s = xs_str_new(NULL);
776 xs_set *seen = xs_set_new(4096); 776 xs_set seen;
777 char *v; 777 char *v;
778 double t = ftime(); 778 double t = ftime();
779 int num = 0; 779 int num = 0;
780 780
781 xs_set_init(&seen);
782
781 s = html_user_header(snac, s, local); 783 s = html_user_header(snac, s, local);
782 784
783 if (!local) 785 if (!local)
@@ -789,7 +791,7 @@ d_char *html_timeline(snac *snac, char *list, int local)
789 while (xs_list_iter(&list, &v)) { 791 while (xs_list_iter(&list, &v)) {
790 xs *msg = timeline_get(snac, v); 792 xs *msg = timeline_get(snac, v);
791 793
792 s = html_entry(snac, s, msg, seen, local, 0, &num); 794 s = html_entry(snac, s, msg, &seen, local, 0, &num);
793 } 795 }
794 796
795 s = xs_str_cat(s, "</div>\n"); 797 s = xs_str_cat(s, "</div>\n");
@@ -828,7 +830,7 @@ d_char *html_timeline(snac *snac, char *list, int local)
828 830
829 s = xs_str_cat(s, "</body>\n</html>\n"); 831 s = xs_str_cat(s, "</body>\n</html>\n");
830 832
831 xs_set_free(seen); 833 xs_set_free(&seen);
832 834
833 return s; 835 return s;
834} 836}
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
diff --git a/xs_version.h b/xs_version.h
index a4b8489..ac5d43f 100644
--- a/xs_version.h
+++ b/xs_version.h
@@ -1 +1 @@
/* 1cde797082a259158b181f9c1e4bda4c5204109d */ /* a78beb97d364ff31cbaa504e275118afeaea7a59 */