4 * Copyright (c) 2011 project bchan
6 * This software is provided 'as-is', without any express or implied
7 * warranty. In no event will the authors be held liable for any damages
8 * arising from the use of this software.
10 * Permission is granted to anyone to use this software for any purpose,
11 * including commercial applications, and to alter it and redistribute it
12 * freely, subject to the following restrictions:
14 * 1. The origin of this software must not be misrepresented; you must not
15 * claim that you wrote the original software. If you use this software
16 * in a product, an acknowledgment in the product documentation would be
17 * appreciated but is not required.
19 * 2. Altered source versions must be plainly marked as such, and must not be
20 * misrepresented as being the original software.
22 * 3. This notice may not be removed or altered from any source
33 #include "subjectlist.h"
34 #include "subjectparser.h"
37 #ifdef BCHANL_CONFIG_DEBUG
38 # define DP(arg) printf arg
39 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
42 # define DP_ER(msg, err) /**/
45 struct sbjtlist_tuple_t_ {
46 sbjtparser_thread_t *parser_thread;
47 W index; /* by subject.txt */
53 struct sbjtlist_originarray_t_ {
56 typedef struct sbjtlist_originarray_t_ sbjtlist_originarray_t;
58 struct sbjtlist_sortedarray_t_ {
61 typedef struct sbjtlist_sortedarray_t_ sbjtlist_sortedarray_t;
64 sbjtlist_originarray_t origin;
65 sbjtlist_sortedarray_t sorted;
69 struct sbjtlist_iterator_t_ {
72 sbjtlist_sortedarray_t *array;
75 EXPORT VOID sbjtlist_tuple_gettitle(sbjtlist_tuple_t *tuple, TC **str, W *len)
77 sbjtparser_thread_gettitlestr(tuple->parser_thread, str, len);
80 EXPORT VOID sbjtlist_tuple_getthreadnumberstr(sbjtlist_tuple_t *tuple, UB **str, W *len)
82 *str = tuple->parser_thread->number;
83 *len = tuple->parser_thread->number_len;
86 EXPORT VOID sbjtlist_tuple_getnumber(sbjtlist_tuple_t *tuple, W *num)
88 *num = tuple->index + 1;
91 EXPORT VOID sbjtlist_tuple_getresnumber(sbjtlist_tuple_t *tuple, W *num)
96 EXPORT VOID sbjtlist_tuple_getresnumberstr(sbjtlist_tuple_t *tuple, TC **str, W *len)
98 sbjtparser_thread_getresnumstr(tuple->parser_thread, str, len);
101 EXPORT VOID sbjtlist_tuple_getsinceSTIME(sbjtlist_tuple_t *tuple, STIME *since)
103 *since = tuple->since;
106 EXPORT VOID sbjtlist_tuple_getsince(sbjtlist_tuple_t *tuple, DATE_TIM *since)
109 sbjtlist_tuple_getsinceSTIME(tuple, &tim);
110 get_tod(since, tim, 0);
113 EXPORT VOID sbjtlist_tuple_getvigor(sbjtlist_tuple_t *tuple, W *vigor)
115 *vigor = tuple->vigor * 10;
118 LOCAL W sbjtlist_tuple_compare_resnumber(sbjtlist_tuple_t *t1, sbjtlist_tuple_t *t2)
121 sbjtlist_tuple_getresnumber(t1, &n1);
122 sbjtlist_tuple_getresnumber(t2, &n2);
132 LOCAL W sbjtlist_tuple_compare_vigor(sbjtlist_tuple_t *t1, sbjtlist_tuple_t *t2)
134 if (t1->vigor > t2->vigor) {
137 if (t1->vigor < t2->vigor) {
143 LOCAL W sbjtlist_tuple_initialize(sbjtlist_tuple_t *tuple, sbjtparser_thread_t *parser_thread, W index, STIME current)
148 tuple->parser_thread = parser_thread;
149 tuple->index = index;
151 since_u = atoi(tuple->parser_thread->number);
152 tuple->since = since_u - 473385600;
154 sbjtparser_thread_getresnumstr(tuple->parser_thread, &str, &len);
155 tuple->resnum = tc_atoi(str + 2);
157 tuple->vigor = (DOUBLE)tuple->resnum * 60.0 * 60.0 * 24.0 / (DOUBLE)(current - tuple->since); /* res per day */
162 LOCAL VOID sbjtlist_tuple_finalize(sbjtlist_tuple_t *tuple)
164 sbjtparser_thread_delete(tuple->parser_thread);
169 LOCAL W sbjtlist_originarray_append(sbjtlist_originarray_t *array, sbjtparser_thread_t *parser_thread, STIME current)
171 sbjtlist_tuple_t tuple;
174 err = sbjtlist_tuple_initialize(&tuple, parser_thread, arraybase_length(&array->base), current);
179 return arraybase_appendunit(&array->base, &tuple);
182 LOCAL Bool sbjtlist_originarray_getbyindex(sbjtlist_originarray_t *array, W i, sbjtlist_tuple_t **tuple)
184 return arraybase_getunitbyindex(&array->base, i, (VP*)tuple);
187 LOCAL VOID sbjtlist_originarray_truncate(sbjtlist_originarray_t *array, W newlength)
189 arraybase_truncate(&array->base, newlength);
192 LOCAL W sbjtlist_originarray_length(sbjtlist_originarray_t *array)
194 return arraybase_length(&array->base);
197 LOCAL W sbjtlist_originarray_initialize(sbjtlist_originarray_t *array)
199 return arraybase_initialize(&array->base, sizeof(sbjtlist_tuple_t), 512);
202 LOCAL VOID sbjtlist_originarray_finalize(sbjtlist_originarray_t *array)
204 arraybase_finalize(&array->base);
207 LOCAL W sbjtlist_sortedarray_append(sbjtlist_sortedarray_t *array, sbjtlist_tuple_t *tuple)
209 return arraybase_appendunit(&array->base, &tuple);
212 LOCAL Bool sbjtlist_sortedarray_getbyindex(sbjtlist_sortedarray_t *array, W index, sbjtlist_tuple_t **tuple)
216 ret = arraybase_getunitbyindex(&array->base, index, &p);
220 *tuple = *((sbjtlist_tuple_t**)p);
224 LOCAL VOID sbjtlist_sortedarray_truncate(sbjtlist_sortedarray_t *array, W newlength)
226 arraybase_truncate(&array->base, newlength);
229 LOCAL W sbjtlist_sortedarray_length(sbjtlist_sortedarray_t *array)
231 return arraybase_length(&array->base);
234 LOCAL W sbjtlist_sortedarray_initialize(sbjtlist_sortedarray_t *array)
236 return arraybase_initialize(&array->base, sizeof(sbjtlist_tuple_t*), 512);
239 LOCAL VOID sbjtlist_sortedarray_finalize(sbjtlist_sortedarray_t *array)
241 arraybase_finalize(&array->base);
246 EXPORT W sbjtlist_appendthread(sbjtlist_t *list, sbjtparser_thread_t *parser_thread, STIME current)
248 return sbjtlist_originarray_append(&list->origin, parser_thread, current);
251 LOCAL Bool sbjtlist_checkfilterwordexist(TC *title, W title_len, TC *filterword, W filterword_len)
261 cur = tc_strchr(cur, ch);
265 if (cur > title + title_len) {
268 cmp = tc_strncmp(cur, filterword, filterword_len);
279 LOCAL W sbjtlist_copyarraywithfilter(sbjtlist_t *list, TC *filterword, W filterword_len)
281 W i, len, err, title_len;
284 sbjtlist_tuple_t *tuple;
286 len = sbjtlist_originarray_length(&list->origin);
287 if (filterword != NULL) {
288 for (i = 0; i < len; i++) {
289 found = sbjtlist_originarray_getbyindex(&list->origin, i, &tuple);
290 if (found == False) {
293 sbjtlist_tuple_gettitle(tuple, &title, &title_len);
294 exist = sbjtlist_checkfilterwordexist(title, title_len, filterword, filterword_len);
295 if (exist == False) {
298 err = sbjtlist_sortedarray_append(&list->sorted, tuple);
304 for (i = 0; i < len; i++) {
305 found = sbjtlist_originarray_getbyindex(&list->origin, i, &tuple);
306 if (found == False) {
309 err = sbjtlist_sortedarray_append(&list->sorted, tuple);
319 LOCAL W sbjtlist_sort_compare(sbjtlist_tuple_t *t1, sbjtlist_tuple_t *t2, W by)
321 if (by == SBJTLIST_SORTBY_SINCE) {
322 return strcmp(t1->parser_thread->number, t2->parser_thread->number);
324 if (by == SBJTLIST_SORTBY_RES) {
325 return sbjtlist_tuple_compare_resnumber(t1, t2);
327 if (by == SBJTLIST_SORTBY_VIGOR) {
328 return sbjtlist_tuple_compare_vigor(t1, t2);
330 /* SBJTLIST_SORTBY_NUMBER */
331 if (t1->index > t2->index) {
334 if (t1->index < t2->index) {
340 LOCAL VOID sbjtlist_sort_swap(sbjtlist_tuple_t *t1, sbjtlist_tuple_t *t2)
344 memcpy(&t, t1, sizeof(sbjtlist_tuple_t));
345 memcpy(t1, t2, sizeof(sbjtlist_tuple_t));
346 memcpy(t2, &t, sizeof(sbjtlist_tuple_t));
349 LOCAL VOID sbjtlist_sortedarray_combsort(sbjtlist_sortedarray_t *array, W by)
351 W h, swaps, i, len, result;
352 sbjtlist_tuple_t *tuple_i, *tuple_i_h;
354 len = sbjtlist_sortedarray_length(array);
362 for (i = 0; i + h < len; ++i) {
363 sbjtlist_sortedarray_getbyindex(array, i, &tuple_i);
364 sbjtlist_sortedarray_getbyindex(array, i + h, &tuple_i_h);
365 result = sbjtlist_sort_compare(tuple_i, tuple_i_h, by);
367 sbjtlist_sort_swap(tuple_i, tuple_i_h);
381 EXPORT W sbjtlist_sort(sbjtlist_t *list, W by, TC *filterword, W filterword_len)
385 sbjtlist_sortedarray_truncate(&list->sorted, 0);
387 err = sbjtlist_copyarraywithfilter(list, filterword, filterword_len);
391 sbjtlist_sortedarray_combsort(&list->sorted, by);
396 EXPORT VOID sbjtlist_clear(sbjtlist_t *list)
400 sbjtlist_tuple_t *tuple;
402 len = sbjtlist_originarray_length(&list->origin);
403 for (i = 0; i < len; i++) {
404 found = sbjtlist_originarray_getbyindex(&list->origin, i, &tuple);
406 sbjtlist_tuple_finalize(tuple);
409 sbjtlist_originarray_truncate(&list->origin, 0);
410 sbjtlist_sortedarray_truncate(&list->sorted, 0);
413 LOCAL sbjtlist_iterator_t* sbjtlist_iterator_new(Bool descending, sbjtlist_t *target)
415 sbjtlist_iterator_t *iter;
417 iter = malloc(sizeof(sbjtlist_iterator_t));
421 iter->descending = descending;
422 if (descending == True) {
423 iter->i = sbjtlist_sortedarray_length(&target->sorted) - 1;
427 iter->array = &target->sorted;
432 LOCAL VOID sbjtlist_iterator_delete(sbjtlist_iterator_t *iter)
437 EXPORT Bool sbjtlist_iterator_next(sbjtlist_iterator_t *iter, sbjtlist_tuple_t **item)
441 found = sbjtlist_sortedarray_getbyindex(iter->array, iter->i, item);
442 if (found == False) {
446 if (iter->descending == True) {
455 EXPORT sbjtlist_iterator_t* sbjtlist_startread(sbjtlist_t *list, Bool descending)
457 return sbjtlist_iterator_new(descending, list);
460 EXPORT VOID sbjtlist_endread(sbjtlist_t *list, sbjtlist_iterator_t *iter)
462 return sbjtlist_iterator_delete(iter);
465 EXPORT sbjtlist_t* sbjtlist_new()
470 list = malloc(sizeof(sbjtlist_t));
474 err = sbjtlist_originarray_initialize(&list->origin);
479 err = sbjtlist_sortedarray_initialize(&list->sorted);
481 sbjtlist_originarray_finalize(&list->origin);
485 list->sortby = SBJTLIST_SORTBY_NUMBER;
490 EXPORT VOID sbjtlist_delete(sbjtlist_t *list)
492 sbjtlist_clear(list);
493 sbjtlist_sortedarray_finalize(&list->sorted);
494 sbjtlist_originarray_finalize(&list->origin);