diff options
| author | 2022-11-21 11:14:24 +0100 | |
|---|---|---|
| committer | 2022-11-21 11:14:24 +0100 | |
| commit | b487b41be63315b6c0994b43418fb3b4fd181d03 (patch) | |
| tree | 11af29cfe81301e41bd548e429a714ad79bb5747 | |
| parent | Changed debug level to grampa max_levels reached. (diff) | |
| download | penes-snac2-b487b41be63315b6c0994b43418fb3b4fd181d03.tar.gz penes-snac2-b487b41be63315b6c0994b43418fb3b4fd181d03.tar.xz penes-snac2-b487b41be63315b6c0994b43418fb3b4fd181d03.zip | |
Backport from xs (new xs_set() API).
| -rw-r--r-- | html.c | 8 | ||||
| -rw-r--r-- | xs_set.h | 78 | ||||
| -rw-r--r-- | xs_version.h | 2 |
3 files changed, 55 insertions, 33 deletions
| @@ -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 | } |
| @@ -7,42 +7,40 @@ | |||
| 7 | typedef struct _xs_set { | 7 | typedef 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 | ||
| 14 | xs_set *xs_set_new(int elems); | 14 | void xs_set_init(xs_set *s); |
| 15 | void xs_set_free(xs_set *s); | 15 | void xs_set_free(xs_set *s); |
| 16 | int xs_set_add(xs_set *s, const char *data); | 16 | int xs_set_add(xs_set *s, const char *data); |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | #ifdef XS_IMPLEMENTATION | 19 | #ifdef XS_IMPLEMENTATION |
| 20 | 20 | ||
| 21 | xs_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 */ | 22 | void 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 | ||
| 37 | void xs_set_free(xs_set *s) | 35 | void 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 | ||
| 45 | unsigned int _xs_set_hash(const char *data, int size) | 43 | static 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 | ||
| 59 | int xs_set_add(xs_set *s, const char *data) | 57 | static 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 | |||
| 85 | int 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 */ | ||