Backport from xs (new xs_set() API).

This commit is contained in:
default 2022-11-21 11:14:24 +01:00
parent 935089ae3f
commit b487b41be6
3 changed files with 55 additions and 33 deletions

8
html.c
View File

@ -773,11 +773,13 @@ d_char *html_timeline(snac *snac, char *list, int local)
/* returns the HTML for the timeline */ /* returns the HTML for the timeline */
{ {
d_char *s = xs_str_new(NULL); d_char *s = xs_str_new(NULL);
xs_set *seen = xs_set_new(4096); xs_set seen;
char *v; char *v;
double t = ftime(); double t = ftime();
int num = 0; int num = 0;
xs_set_init(&seen);
s = html_user_header(snac, s, local); s = html_user_header(snac, s, local);
if (!local) if (!local)
@ -789,7 +791,7 @@ d_char *html_timeline(snac *snac, char *list, int local)
while (xs_list_iter(&list, &v)) { while (xs_list_iter(&list, &v)) {
xs *msg = timeline_get(snac, v); xs *msg = timeline_get(snac, v);
s = html_entry(snac, s, msg, seen, local, 0, &num); s = html_entry(snac, s, msg, &seen, local, 0, &num);
} }
s = xs_str_cat(s, "</div>\n"); s = xs_str_cat(s, "</div>\n");
@ -828,7 +830,7 @@ d_char *html_timeline(snac *snac, char *list, int local)
s = xs_str_cat(s, "</body>\n</html>\n"); s = xs_str_cat(s, "</body>\n</html>\n");
xs_set_free(seen); xs_set_free(&seen);
return s; return s;
} }

View File

@ -7,42 +7,40 @@
typedef struct _xs_set { typedef struct _xs_set {
int elems; /* number of hash entries */ int elems; /* number of hash entries */
int used; /* number of used hash entries */ int used; /* number of used hash entries */
int *hash; /* hashed offsets */
d_char *list; /* list of stored data */ d_char *list; /* list of stored data */
int hash[]; /* hashed offsets */
} xs_set; } xs_set;
xs_set *xs_set_new(int elems); void xs_set_init(xs_set *s);
void xs_set_free(xs_set *s); void xs_set_free(xs_set *s);
int xs_set_add(xs_set *s, const char *data); int xs_set_add(xs_set *s, const char *data);
#ifdef XS_IMPLEMENTATION #ifdef XS_IMPLEMENTATION
xs_set *xs_set_new(int elems)
/* creates a new set with a maximum of size hashed data */ void xs_set_init(xs_set *s)
/* initializes a set */
{ {
int sz = sizeof(struct _xs_set) + sizeof(int) * elems; /* arbitrary default */
xs_set *s = xs_realloc(NULL, sz); s->elems = 256;
s->used = 0;
memset(s, '\0', sz); s->hash = xs_realloc(NULL, s->elems * sizeof(int));
/* initialize */
s->elems = elems;
s->list = xs_list_new(); s->list = xs_list_new();
return s; memset(s->hash, '\0', s->elems * sizeof(int));
} }
void xs_set_free(xs_set *s) void xs_set_free(xs_set *s)
/* frees a set */ /* frees a set */
{ {
xs_free(s->list); s->hash = xs_free(s->hash);
xs_free(s); s->list = xs_free(s->list);
} }
unsigned int _xs_set_hash(const char *data, int size) static unsigned int _calc_hash(const char *data, int size)
{ {
unsigned int hash = 0x666; unsigned int hash = 0x666;
int n; int n;
@ -56,14 +54,12 @@ unsigned int _xs_set_hash(const char *data, int size)
} }
int xs_set_add(xs_set *s, const char *data) static int _store_hash(xs_set *s, const char *data, int value)
/* adds the data to the set */
/* returns: 1 if added, 0 if already there, -1 if it's full */
{ {
unsigned int hash, i; unsigned int hash, i;
int sz = xs_size(data); int sz = xs_size(data);
hash = _xs_set_hash(data, sz); hash = _calc_hash(data, sz);
while (s->hash[(i = hash % s->elems)]) { while (s->hash[(i = hash % s->elems)]) {
/* get the pointer to the stored data */ /* get the pointer to the stored data */
@ -77,21 +73,45 @@ int xs_set_add(xs_set *s, const char *data)
hash++; hash++;
} }
/* is it full? fail */ /* store the new value */
if (s->used == s->elems / 2) s->hash[i] = value;
return -1;
/* store the position */
s->hash[i] = xs_size(s->list);
/* add the data */
s->list = xs_list_append_m(s->list, data, sz);
s->used++; s->used++;
return 1; return 1;
} }
int xs_set_add(xs_set *s, const char *data)
/* adds the data to the set */
/* returns: 1 if added, 0 if already there */
{
/* is it 'full'? */
if (s->used >= s->elems / 2) {
char *p, *v;
/* expand! */
s->elems *= 2;
s->used = 0;
s->hash = xs_realloc(s->hash, s->elems * sizeof(int));
memset(s->hash, '\0', s->elems * sizeof(int));
/* add the list elements back */
p = s->list;
while (xs_list_iter(&p, &v))
_store_hash(s, v, v - s->list);
}
int ret = _store_hash(s, data, xs_size(s->list));
/* if it's new, add the data */
if (ret)
s->list = xs_list_append_m(s->list, data, xs_size(data));
return ret;
}
#endif /* XS_IMPLEMENTATION */ #endif /* XS_IMPLEMENTATION */
#endif /* XS_SET_H */ #endif /* XS_SET_H */

View File

@ -1 +1 @@
/* 1cde797082a259158b181f9c1e4bda4c5204109d */ /* a78beb97d364ff31cbaa504e275118afeaea7a59 */