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) /* returns the HTML for the timeline */ { d_char *s = xs_str_new(NULL); - xs_set *seen = xs_set_new(4096); + xs_set seen; char *v; double t = ftime(); int num = 0; + xs_set_init(&seen); + s = html_user_header(snac, s, local); if (!local) @@ -789,7 +791,7 @@ d_char *html_timeline(snac *snac, char *list, int local) while (xs_list_iter(&list, &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, "\n"); @@ -828,7 +830,7 @@ d_char *html_timeline(snac *snac, char *list, int local) s = xs_str_cat(s, "\n\n"); - xs_set_free(seen); + xs_set_free(&seen); return s; } 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 @@ typedef struct _xs_set { int elems; /* number of hash entries */ int used; /* number of used hash entries */ + int *hash; /* hashed offsets */ d_char *list; /* list of stored data */ - int hash[]; /* hashed offsets */ } xs_set; -xs_set *xs_set_new(int elems); +void xs_set_init(xs_set *s); void xs_set_free(xs_set *s); int xs_set_add(xs_set *s, const char *data); #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; - xs_set *s = xs_realloc(NULL, sz); + /* arbitrary default */ + s->elems = 256; + s->used = 0; + s->hash = xs_realloc(NULL, s->elems * sizeof(int)); + s->list = xs_list_new(); - memset(s, '\0', sz); - - /* initialize */ - s->elems = elems; - s->list = xs_list_new(); - - return s; + memset(s->hash, '\0', s->elems * sizeof(int)); } void xs_set_free(xs_set *s) /* frees a set */ { - xs_free(s->list); - xs_free(s); + s->hash = xs_free(s->hash); + 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; 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) -/* adds the data to the set */ -/* returns: 1 if added, 0 if already there, -1 if it's full */ +static int _store_hash(xs_set *s, const char *data, int value) { unsigned int hash, i; int sz = xs_size(data); - hash = _xs_set_hash(data, sz); + hash = _calc_hash(data, sz); while (s->hash[(i = hash % s->elems)]) { /* get the pointer to the stored data */ @@ -77,21 +73,45 @@ int xs_set_add(xs_set *s, const char *data) hash++; } - /* is it full? fail */ - if (s->used == s->elems / 2) - 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); + /* store the new value */ + s->hash[i] = value; s->used++; 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_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 */