2 * UCW Library -- Universal Sorter: Multi-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 typedef struct P(mwt_node) {
17 static inline void P(update_tree)(P(key) *keys, P(mwt_node) *tree, uns i)
24 else if (tree[2*i+1].i < 0)
28 int cmp = P(compare)(&keys[tree[2*i].i], &keys[tree[2*i+1].i]);
38 #ifdef SORT_UNIFY_XXX // FIXME
39 /* If we are not unifying, the keys are usually distinct, so this check is pointless */
40 if (!memcmp(&tree[i], &new, sizeof(new)))
47 static inline void P(set_tree)(P(key) *keys, P(mwt_node) *tree, uns i, int val)
50 P(update_tree)(keys, tree, i);
53 static void P(multiway_merge)(struct sort_context *ctx UNUSED, struct sort_bucket **ins, struct sort_bucket *out)
63 struct fastbuf *fout = sbuck_write(out);
64 struct fastbuf *fins[num_ins];
66 P(mwt_node) tree[2*n2]; // A complete binary tree, leaves are input streams, each internal vertex contains a minimum of its sons
67 for (uns i=1; i<2*n2; i++)
75 for (uns i=0; i<num_ins; i++)
77 fins[i] = sbuck_read(ins[i]);
78 if (P(read_key)(fins[i], &keys[i]))
79 P(set_tree)(keys, tree, n2+i, i);
85 P(key) *mkeys[num_ins], *key;
86 struct fastbuf *mfb[num_ins];
88 while (likely(tree[1].i >= 0))
91 if (!tree[1].eq && 0) // FIXME: This does not work for some reason
93 /* The key is unique, so let's go through the fast path */
94 P(copy_data)(&keys[i], fins[i], fout);
95 if (unlikely(!P(read_key)(fins[i], &keys[i])))
97 P(update_tree)(keys, tree, n2+i);
109 P(set_tree)(keys, tree, n2+i, -1);
114 while (!P(compare)(key, &keys[i]));
116 P(copy_merged)(mkeys, mfb, m, fout);
118 for (uns j=0; j<m; j++)
121 if (likely(P(read_key)(fins[i], &keys[i])))
122 P(set_tree)(keys, tree, n2+i, i);
128 /* Simplified version which does not support any unification */
129 while (likely(tree[1].i >= 0))
132 P(key) UNUSED key = keys[i];
133 P(copy_data)(&keys[i], fins[i], fout);
134 if (unlikely(!P(read_key)(fins[i], &keys[i])))
136 P(update_tree)(keys, tree, n2+i);
137 #ifdef SORT_ASSERT_UNIQUE
138 ASSERT(tree[1].i < 0 || P(compare)(&key, &keys[tree[1].i]) < 0);