+ /*
+ * The trick with automatic joining, which we use for the normal presorter,
+ * is not necessary with the custom presorter, because the custom presorter
+ * is never called in the middle of the sorted data.
+ */
}
return ctx->internal_sort(ctx, in, out, out_only);
}
}
return ctx->internal_sort(ctx, in, out, out_only);
}
static sh_off_t
sbuck_ins_or_join(struct sort_bucket *b, cnode *list_pos, struct sort_bucket *join, sh_off_t join_size)
{
static sh_off_t
sbuck_ins_or_join(struct sort_bucket *b, cnode *list_pos, struct sort_bucket *join, sh_off_t join_size)
{
{
// The final bucket doesn't have any file associated yet, so replace
// it with the new bucket.
{
// The final bucket doesn't have any file associated yet, so replace
// it with the new bucket.
{
sorter_stop_timer(ctx, &ctx->total_pre_time);
sh_off_t size = sbuck_ins_or_join(ins[0], list_pos, join, join_size);
{
sorter_stop_timer(ctx, &ctx->total_pre_time);
sh_off_t size = sbuck_ins_or_join(ins[0], list_pos, join, join_size);
- SORT_XTRACE(((b->flags & SBF_SOURCE) ? 1 : 2), "Sorted in memory (%s, %dMB/s)", stk_fsize(size), sorter_speed(ctx, size));
+ SORT_XTRACE(((b->flags & SBF_SOURCE) ? 1 : 3), "Sorted in memory (%s, %dMB/s)", stk_fsize(size), sorter_speed(ctx, size));
cnode *list_pos = b->n.prev;
sh_off_t join_size;
struct sort_bucket *join = sbuck_join_to(b, &join_size);
cnode *list_pos = b->n.prev;
sh_off_t join_size;
struct sort_bucket *join = sbuck_join_to(b, &join_size);
- sh_off_t size = sbuck_ins_or_join(clist_head(&parts), list_pos, join, join_size);
+ sh_off_t size = sbuck_ins_or_join(clist_head(&parts), list_pos, (part_cnt ? NULL : join), join_size);
SORT_XTRACE(trace_level, "Sorted in memory (%s, %dMB/s)", stk_fsize(size), sorter_speed(ctx, size));
return;
}
SORT_XTRACE(trace_level, "Sorted in memory (%s, %dMB/s)", stk_fsize(size), sorter_speed(ctx, size));
return;
}
F_BSIZE(b), bits, b->hash_bits, stk_fsize(sbuck_size(b) / nbuck));
sorter_free_buf(ctx);
sorter_start_timer(ctx);
F_BSIZE(b), bits, b->hash_bits, stk_fsize(sbuck_size(b) / nbuck));
sorter_free_buf(ctx);
sorter_start_timer(ctx);
// How many bits of bucket size we have to reduce before it fits in the RAM?
// (this is insanely large if the input size is unknown, but it serves our purpose)
u64 insize = sbuck_size(b);
// How many bits of bucket size we have to reduce before it fits in the RAM?
// (this is insanely large if the input size is unknown, but it serves our purpose)
u64 insize = sbuck_size(b);
stk_fsize(insize), stk_fsize(mem), b->runs, bits, b->hash_bits,
radix_bits, multiway_bits);
stk_fsize(insize), stk_fsize(mem), b->runs, bits, b->hash_bits,
radix_bits, multiway_bits);
bin->hash_bits = ctx->hash_bits;
clist_add_tail(&ctx->bucket_list, &bin->n);
SORT_XTRACE(2, "Input size: %s, %d hash bits", F_BSIZE(bin), bin->hash_bits);
bin->hash_bits = ctx->hash_bits;
clist_add_tail(&ctx->bucket_list, &bin->n);
SORT_XTRACE(2, "Input size: %s, %d hash bits", F_BSIZE(bin), bin->hash_bits);
sorter_free_buf(ctx);
sbuck_write(bout); // Force empty bucket to a file
SORT_XTRACE(2, "Final size: %s", F_BSIZE(bout));
SORT_XTRACE(2, "Final timings: %.3fs external sorting, %.3fs presorting, %.3fs internal sorting",
ctx->total_ext_time/1000., ctx->total_pre_time/1000., ctx->total_int_time/1000.);
ctx->out_fb = sbuck_read(bout);
sorter_free_buf(ctx);
sbuck_write(bout); // Force empty bucket to a file
SORT_XTRACE(2, "Final size: %s", F_BSIZE(bout));
SORT_XTRACE(2, "Final timings: %.3fs external sorting, %.3fs presorting, %.3fs internal sorting",
ctx->total_ext_time/1000., ctx->total_pre_time/1000., ctx->total_int_time/1000.);
ctx->out_fb = sbuck_read(bout);