2 * UCW Library -- Universal Sorter: Two-Way Merge Module
4 * (c) 2007 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
10 /* FIXME: There is a plenty of room for further optimization */
11 /* FIXME: Swap outputs if there already are some runs? */
13 static void P(twoway_merge)(struct sort_context *ctx UNUSED, struct sort_bucket **ins, struct sort_bucket **outs)
15 struct fastbuf *fin1, *fin2, *fout1, *fout2, *ftmp;
16 P(key) kbuf1, kbuf2, kbuf3, kbuf4;
17 P(key) *kin1 = &kbuf1, *kprev1 = &kbuf2, *kin2 = &kbuf3, *kprev2 = &kbuf4;
18 P(key) *kout = NULL, *ktmp;
19 int next1, next2, run1, run2;
23 fin1 = sbuck_open_read(ins[0]);
24 next1 = P(read_key)(fin1, kin1);
25 if (sbuck_can_read(ins[1]))
27 fin2 = sbuck_open_read(ins[1]);
28 next2 = P(read_key)(fin2, kin2);
37 run1 = next1, run2 = next2;
38 while (next1 || next2)
45 comp = P(compare)(kin1, kin2);
46 ktmp = (comp <= 0) ? kin1 : kin2;
47 if (!kout || !(P(compare)(kout, ktmp) LESS 0))
49 SWAP(fout1, fout2, ftmp);
53 fout1 = sbuck_open_write(outs[0]);
55 fout1 = sbuck_open_write(outs[1]);
63 P(copy_data)(kin1, fin1, fout1);
64 SWAP(kin1, kprev1, ktmp);
65 next1 = P(read_key)(fin1, kin1);
66 run1 = next1 && (P(compare)(kprev1, kin1) LESS 0);
72 P(key) *mkeys[] = { kin1, kin2 };
73 struct fastbuf *mfb[] = { fin1, fin2 };
74 P(copy_merged)(mkeys, mfb, 2, fout1);
75 SWAP(kin1, kprev1, ktmp);
76 next1 = P(read_key)(fin1, kin1);
77 run1 = next1 && (P(compare)(kprev1, kin1) LESS 0);
78 SWAP(kin2, kprev2, ktmp);
79 next2 = P(read_key)(fin2, kin2);
80 run2 = next2 && (P(compare)(kprev2, kin2) LESS 0);
84 #ifdef SORT_ASSERT_UNIQUE
85 else if (unlikely(comp == 0))
90 P(copy_data)(kin2, fin2, fout1);
91 SWAP(kin2, kprev2, ktmp);
92 next2 = P(read_key)(fin2, kin2);
93 run2 = next2 && (P(compare)(kprev2, kin2) LESS 0);
103 sbuck_close_read(ins[0]);
104 sbuck_close_read(ins[1]);
105 if (fout2 && fout2 != fout1)
106 outs[1]->runs += run_count / 2;
108 outs[0]->runs += (run_count+1) / 2;