2 * UCW Library -- Universal Sorter: Operations on Contexts, Buffers and Buckets
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.
11 #include "lib/fastbuf.h"
12 #include "lib/mempool.h"
13 #include "lib/sorter/common.h"
18 sorter_alloc(struct sort_context *ctx, uns size)
20 return mp_alloc_zero(ctx->pool, size);
24 sbuck_new(struct sort_context *ctx)
26 struct sort_bucket *b = sorter_alloc(ctx, sizeof(struct sort_bucket));
32 sbuck_drop(struct sort_bucket *b)
36 ASSERT(!(b->flags & SBF_DESTROYED));
41 b->flags = SBF_DESTROYED;
46 sbuck_size(struct sort_bucket *b)
48 if ((b->flags & SBF_OPEN_WRITE) && !(b->flags & SBF_SWAPPED_OUT))
55 sbuck_have(struct sort_bucket *b)
57 return b && sbuck_size(b);
61 sbuck_has_file(struct sort_bucket *b)
63 return (b->fb || (b->flags & SBF_SWAPPED_OUT));
67 sbuck_swap_in(struct sort_bucket *b)
69 if (b->flags & SBF_SWAPPED_OUT)
71 if (sorter_stream_bufsize) /* FIXME: Needs better configuration, probably semi-automatic one */
72 b->fb = bopen(b->filename, O_RDWR, sorter_stream_bufsize);
74 b->fb = fbdir_open(b->filename, O_RDWR, NULL);
75 if (b->flags & SBF_OPEN_WRITE)
76 bseek(b->fb, 0, SEEK_END);
77 bconfig(b->fb, BCONFIG_IS_TEMP_FILE, 1);
78 b->flags &= ~SBF_SWAPPED_OUT;
79 SORT_XTRACE(2, "Swapped in %s", b->filename);
84 sbuck_read(struct sort_bucket *b)
87 if (b->flags & SBF_OPEN_READ)
89 else if (b->flags & SBF_OPEN_WRITE)
91 b->size = btell(b->fb);
92 b->flags = (b->flags & ~SBF_OPEN_WRITE) | SBF_OPEN_READ;
101 sbuck_write(struct sort_bucket *b)
104 if (b->flags & SBF_OPEN_WRITE)
108 ASSERT(!(b->flags & (SBF_OPEN_READ | SBF_DESTROYED)));
109 if (sorter_stream_bufsize)
110 b->fb = bopen_tmp(sorter_stream_bufsize);
112 b->fb = fbdir_open_tmp(NULL);
113 if (sorter_debug & SORT_DEBUG_KEEP_BUCKETS)
114 bconfig(b->fb, BCONFIG_IS_TEMP_FILE, 0);
115 b->flags |= SBF_OPEN_WRITE;
116 b->filename = mp_strdup(b->ctx->pool, b->fb->name);
122 sbuck_swap_out(struct sort_bucket *b)
124 if ((b->flags & (SBF_OPEN_READ | SBF_OPEN_WRITE)) && b->fb && !(b->flags & SBF_SOURCE))
126 if (b->flags & SBF_OPEN_WRITE)
127 b->size = btell(b->fb);
128 bconfig(b->fb, BCONFIG_IS_TEMP_FILE, 0);
131 b->flags |= SBF_SWAPPED_OUT;
132 SORT_XTRACE(2, "Swapped out %s", b->filename);
137 sorter_alloc_buf(struct sort_context *ctx)
141 u64 bs = MAX(sorter_bufsize/2, 1);
142 bs = ALIGN_TO(bs, (u64)CPU_PAGE_SIZE);
143 ctx->big_buf = big_alloc(2*bs);
144 ctx->big_buf_size = 2*bs;
145 ctx->big_buf_half = ((byte*) ctx->big_buf) + bs;
146 ctx->big_buf_half_size = bs;
147 SORT_XTRACE(2, "Allocated sorting buffer (2*%jd bytes)", (uintmax_t) bs);
151 sorter_free_buf(struct sort_context *ctx)
155 big_free(ctx->big_buf, ctx->big_buf_size);
157 SORT_XTRACE(2, "Freed sorting buffer");
161 format_size(byte *buf, u64 x)
164 sprintf(buf, "%.1fK", (double)x/(1<<10));
166 sprintf(buf, "%dK", (int)(x/(1<<10)));
168 sprintf(buf, "%.1fM", (double)x/(1<<20));
170 sprintf(buf, "%dM", (int)(x/(1<<20)));
171 else if (x < (u64)10<<30)
172 sprintf(buf, "%.1fG", (double)x/(1<<30));
173 else if (x != ~(u64)0)
174 sprintf(buf, "%dG", (int)(x/(1<<30)));
176 strcpy(buf, "unknown");