X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pspp;a=blobdiff_plain;f=src%2Fmath%2Fmerge.c;fp=src%2Fmath%2Fmerge.c;h=20d26c0420f889f15256b431d02f3c6645ff0317;hp=5b0704d9c26850518041ad52f6457b23344b1952;hb=490ac70d9c9f754f733552d64c23dd6aedced342;hpb=48ae4b998c76c9aaad4dca9090752cb9bd6e9f29 diff --git a/src/math/merge.c b/src/math/merge.c index 5b0704d9c2..20d26c0420 100644 --- a/src/math/merge.c +++ b/src/math/merge.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2009, 2011 Free Software Foundation, Inc. + Copyright (C) 2007, 2009-11, 14 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,17 +45,23 @@ struct merge struct merge_input inputs[MAX_MERGE_ORDER]; size_t input_cnt; struct caseproto *proto; + + merge_distinct_combine_func *combine; + void *aux; }; static void do_merge (struct merge *m); struct merge * -merge_create (const struct subcase *ordering, const struct caseproto *proto) +merge_create (const struct subcase *ordering, const struct caseproto *proto, + merge_distinct_combine_func *combine, void *aux) { struct merge *m = xmalloc (sizeof *m); subcase_clone (&m->ordering, ordering); m->input_cnt = 0; m->proto = caseproto_ref (proto); + m->combine = combine; + m->aux = aux; return m; } @@ -128,6 +134,7 @@ static void do_merge (struct merge *m) { struct casewriter *w; + struct ccase *prev_case; size_t i; assert (m->input_cnt > 1); @@ -140,8 +147,11 @@ do_merge (struct merge *m) for (i = 0; i < m->input_cnt; ) if (read_input_case (m, i)) i++; + + prev_case = NULL; while (m->input_cnt > 0) { + struct ccase *min_case; size_t min; min = 0; @@ -150,11 +160,28 @@ do_merge (struct merge *m) &m->ordering, m->inputs[min].c) < 0) min = i; - casewriter_write (w, m->inputs[min].c); + min_case = m->inputs[min].c; + if (m->combine != NULL) + { + if (prev_case == NULL) + prev_case = min_case; + else if (subcase_equal (&m->ordering, min_case, + &m->ordering, prev_case)) + prev_case = m->combine (prev_case, min_case, m->aux); + else + { + casewriter_write (w, prev_case); + prev_case = min_case; + } + } + else + casewriter_write (w, min_case); + read_input_case (m, min); } + if (prev_case != NULL) + casewriter_write (w, prev_case); m->input_cnt = 1; m->inputs[0].reader = casewriter_make_reader (w); } -