- /* Order of merge. */
- int order;
-
- /* Idiot check. */
- assert (MIN_BUFFER_SIZE_RECS * 2 <= MIN_BUFFER_TOTAL_SIZE_RECS - 1);
-
- /* Close all the input files. I hope that the boundary conditions
- are correct on this but I'm not sure. */
- if (run_no < max_handles)
- {
- int i;
-
- for (i = 0; i < run_no; )
- if (!close_handle (i++))
- {
- for (; i < run_no; i++)
- close_handle (i);
- return 0;
- }
- }
-
- /* Determine order of merge. */
- order = MAX_MERGE_ORDER;
- if (x_max / order < MIN_BUFFER_SIZE_RECS)
- order = x_max / MIN_BUFFER_SIZE_RECS;
- else if (x_max / order * sizeof (union value) * default_dict.nval
- < MIN_BUFFER_SIZE_BYTES)
- order = x_max / (MIN_BUFFER_SIZE_BYTES
- / (sizeof (union value) * (default_dict.nval - 1)));
-
- /* Make sure the order of merge is bounded. */
- if (order < 2)
- order = 2;
- if (order > rmax)
- order = rmax;
- assert (x_max / order > 0);
-
- /* Calculate number of records per buffer. */
- records_per_buffer = x_max / order;
-
- /* Add (1 - S) mod (P - 1) dummy runs of length 0. */
- {
- int n_dummy_runs = mod (1 - rmax, order - 1);
- debug_printf (("rmax=%d, order=%d, n_dummy_runs=%d\n",
- rmax, order, n_dummy_runs));
- assert (n_dummy_runs >= 0);
- while (n_dummy_runs--)
- {
- heap_insert (huffman_queue, -2, 0);
- rmax++;
- }
- }
-
- /* Repeatedly merge the P shortest existing runs until only one run
- is left. */
- while (rmax > 1)
- {
- int run_index[MAX_MERGE_ORDER];
- int run_length[MAX_MERGE_ORDER];
- int total_run_length = 0;
- int i;
-
- assert (rmax >= order);
-
- /* Find the shortest runs; put them in runs[] in reverse order
- of length, to force dummy runs of length 0 to the end of the
- list. */
- debug_printf ((_("merging runs")));
- for (i = order - 1; i >= 0; i--)
- {
- run_index[i] = heap_delete (huffman_queue, &run_length[i]);
- assert (run_index[i] != -1);
- total_run_length += run_length[i];
- debug_printf ((" %d(%d)", run_index[i], run_length[i]));
- }
- debug_printf ((_(" into run %d(%d)\n"), run_no, total_run_length));
-
- if (!merge_once (run_index, run_length, order))
- {
- int index;
-
- while (-1 != (index = heap_delete (huffman_queue, NULL)))
- {
- sprintf (tmp_extname, "%08x", index);
- if (remove (tmp_basename) != 0)
- msg (SE, _("%s: Error removing temporary file: %s."),
- tmp_basename, strerror (errno));
- }
-
- return 0;
- }
-
- if (!heap_insert (huffman_queue, run_no++, total_run_length))
- {
- msg (SE, _("Out of memory expanding Huffman priority queue."));
- return 0;
- }
-
- rmax -= order - 1;
- }
-
- /* There should be exactly one element in the priority queue after
- all that merging. This represents the entire sorted active file.
- So we could find a total case count by deleting this element from
- the queue. */
- assert (heap_size (huffman_queue) == 1);
-
- return 1;