]> mj.ucw.cz Git - libucw.git/blob - lib/sorter/govern.c
aece061c528b9093eadeb8dd057663195ffed07e
[libucw.git] / lib / sorter / govern.c
1 /*
2  *      UCW Library -- Universal Sorter: Governing Routines
3  *
4  *      (c) 2007 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11 #include "lib/fastbuf.h"
12 #include "lib/mempool.h"
13 #include "lib/sorter/common.h"
14
15 struct sort_bucket *
16 sorter_new_bucket(struct sort_context *ctx)
17 {
18   return mp_alloc_zero(ctx->pool, sizeof(struct sort_bucket));
19 }
20
21 struct fastbuf *
22 sorter_open_read(struct sort_bucket *b)
23 {
24   /* FIXME: These functions should handle buckets with no fb and only name. */
25   ASSERT(b->fb);
26   return b->fb;
27 }
28
29 struct fastbuf *
30 sorter_open_write(struct sort_bucket *b)
31 {
32   if (!b->fb)
33     b->fb = bopen_tmp(sorter_stream_bufsize);
34   return b->fb;
35 }
36
37 void
38 sorter_close_read(struct sort_bucket *b)
39 {
40   if (!b)
41     return;
42   ASSERT(b->fb);
43   bclose(b->fb);
44   b->fb = NULL;
45 }
46
47 void
48 sorter_close_write(struct sort_bucket *b)
49 {
50   if (b->fb)
51     {
52       b->size = btell(b->fb);
53       brewind(b->fb);
54     }
55   /* FIXME: Remove empty buckets from the list automatically? */
56 }
57
58 void
59 sorter_run(struct sort_context *ctx)
60 {
61   ctx->pool = mp_new(4096);
62   ASSERT(!ctx->custom_presort);
63   ASSERT(!ctx->out_fb);
64   clist_init(&ctx->bucket_list);
65
66   /* FIXME: There should be a way how to detect size of the input file */
67
68   /* Trivial 2-way merge with no presorting (just a testing hack) */
69   struct sort_bucket *bin = sorter_new_bucket(ctx);
70   bin->flags = SBF_SOURCE;
71   bin->fb = ctx->in_fb;
72   bin->ident = "src";
73   struct sort_bucket *ins[3], *outs[3];
74   ins[0] = bin;
75   ins[1] = NULL;
76
77   do {
78     outs[0] = sorter_new_bucket(ctx);
79     outs[1] = sorter_new_bucket(ctx);
80     outs[2] = NULL;
81     log(L_DEBUG, "Pass...");
82     ctx->twoway_merge(ctx, ins, outs);
83     log(L_DEBUG, "Done (%d+%d runs)", outs[0]->runs, outs[1]->runs);
84     sorter_close_write(outs[0]);
85     sorter_close_write(outs[1]);
86     memcpy(ins, outs, 3*sizeof(struct sort_bucket *));
87   } while (ins[1]->fb);
88
89   ctx->out_fb = sorter_open_read(ins[0]);
90 }