X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Fsorter.h;h=71fcff1ecc6cbe4011290d7dbfe4b899996e1ad3;hb=d5e8872563f6fde8299db971ffb6494c2438c590;hp=e3beb57470db1b741c13d6d8fd410c7b48d7669b;hpb=e139c5736e5519318d3da5278b26ac39ee696dd1;p=libucw.git diff --git a/lib/sorter.h b/lib/sorter.h index e3beb574..71fcff1e 100644 --- a/lib/sorter.h +++ b/lib/sorter.h @@ -1,7 +1,8 @@ /* - * Sherlock Library -- Universal Sorter + * UCW Library -- Universal Sorter * * (c) 2001--2004 Martin Mares + * (c) 2004 Robert Spalek * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -22,10 +23,9 @@ * the pre-sorting mode, it's quite possible that the * comparison function will be called with both arguments * identical. - * SORT_PRESORT_ONLY a C expression which, if evaluated to non-zero, makes - * the sorter stop after the pre-sorting pass, resulting - * in a file which is not necessarily sorted, but which - * contains long runs. Implies SORT_PRESORT. + * SORT_UP_TO a C expression, if defined, sorting is stopped after the + * average run length in the file exceeds the value of this + * expression (in bytes) * SORT_UNIFY merge items with identical keys * SORT_UNIQUE all items have distinct keys (checked in debug mode) * SORT_REGULAR all items are equally long and they don't contain @@ -50,7 +50,7 @@ * int PREFIX_compare(SORT_KEY *a, *b) * compare two keys, result like strcmp * int PREFIX_fetch_key(struct fastbuf *f, SORT_KEY *k) - * fetch next key, returns 1=ok, 0=eof + * fetch next key, returns nonzero=ok, 0=eof * void PREFIX_copy_data(struct fastbuf *src, *dest, SORT_KEY *k) * write just fetched key k to dest and copy all data * belonging to this key from src to dest. @@ -85,23 +85,7 @@ * undef'd. */ -/* Declarations of externals from sorter.c */ - -#ifndef SORT_DECLS_READ -#define SORT_DECLS_READ - -extern uns sorter_trace; -extern uns sorter_presort_bufsize; -extern uns sorter_stream_bufsize; - -extern uns sorter_pass_counter; - -#endif /* !SORT_DECLS_READ */ - -/* The sorter proper */ - -#ifndef SORT_DECLARE_ONLY - +#include "lib/sorter-globals.h" #include "lib/fastbuf.h" #include #include @@ -124,13 +108,6 @@ extern uns sorter_pass_counter; #define SORT_ASSERT_UNIQUE #endif -#ifdef SORT_PRESORT_ONLY -#undef SORT_PRESORT -#define SORT_PRESORT -#else -#define SORT_PRESORT_ONLY 0 -#endif - #ifdef SORT_REGULAR static inline int @@ -167,8 +144,12 @@ P(flush_out)(struct fastbuf *out) return out; } -static void -P(pass)(struct fastbuf **fb1, struct fastbuf **fb2) +static uns +P(pass)(struct fastbuf **fb1, struct fastbuf **fb2 +#ifdef SORT_UP_TO + , uns stop_sorting +#endif +) { struct fastbuf *in1 = *fb1; struct fastbuf *in2 = *fb2; @@ -199,7 +180,10 @@ P(pass)(struct fastbuf **fb1, struct fastbuf **fb2) if (!kout || !(P(compare)(kout, ktmp) LESS 0)) { struct fastbuf *t; - SWAP(out1, out2, t); +#ifdef SORT_UP_TO + if (!stop_sorting) +#endif + SWAP(out1, out2, t); if (!out1) out1 = bopen_tmp(sorter_stream_bufsize); run_count++; @@ -252,6 +236,7 @@ P(pass)(struct fastbuf **fb1, struct fastbuf **fb2) *fb1 = P(flush_out)(out1); *fb2 = P(flush_out)(out2); sorter_pass_counter++; + return run_count; } #ifdef SORT_PRESORT @@ -278,7 +263,7 @@ P(presort)(struct fastbuf **fb1, struct fastbuf **fb2) struct fastbuf *tbuf; uns buf_items = sorter_presort_bufsize / sizeof(SORT_KEY); uns run_count = 0; - SORT_KEY last_out, *array; + SORT_KEY last_out = { }, *array; ASSERT(!*fb2); if (buf_items < 2) @@ -302,7 +287,10 @@ P(presort)(struct fastbuf **fb1, struct fastbuf **fb2) if (!run_count || P(compare)(&last_out, &array[0]) > 0) { run_count++; - SWAP(out1, out2, tbuf); +#ifdef SORT_UP_TO + if (sorter_presort_bufsize < (uns) SORT_UP_TO) +#endif + SWAP(out1, out2, tbuf); if (!out1) out1 = bopen_tmp(sorter_stream_bufsize); } @@ -396,7 +384,9 @@ P(presort)(struct fastbuf **fb1, struct fastbuf **fb2) leftover = NULL; while (cont) { - if (!(SORT_PRESORT_ONLY)) +#ifdef SORT_UP_TO + if (sorter_presort_bufsize < SORT_UP_TO) +#endif SWAP(out1, out2, tbuf); if (!out1) out1 = bopen_tmp(sorter_stream_bufsize); @@ -411,7 +401,7 @@ P(presort)(struct fastbuf **fb1, struct fastbuf **fb2) } for(;;) { - current = (byte *) ALIGN((addr_int_t) current, CPU_STRUCT_ALIGN); + current = (byte *) ALIGN_TO((uintptr_t) current, CPU_STRUCT_ALIGN); if (current + sizeof(*this) > bufend) break; this = (SORT_NODE *) current; @@ -521,7 +511,27 @@ struct fastbuf *fb1, struct fastbuf *fb2 P(presort)(&fb1, &fb2); if (fb2) #endif +#ifndef SORT_UP_TO do P(pass)(&fb1, &fb2); while (fb1 && fb2); +#else + { + sh_off_t run_count, max_run_count = 0; + if (fb1) + max_run_count += bfilesize(fb1); + if (fb2) + max_run_count += bfilesize(fb2); +#ifdef SORT_PRESORT + run_count = max_run_count / sorter_presort_bufsize; +#else + run_count = max_run_count; +#endif + if (SORT_UP_TO) + max_run_count /= SORT_UP_TO; + do + run_count = P(pass)(&fb1, &fb2, (run_count+1)/2 <= max_run_count); + while (fb1 && fb2); + } +#endif if (!fb1) fb1 = bopen_tmp(sorter_stream_bufsize); @@ -552,6 +562,4 @@ struct fastbuf *fb1, struct fastbuf *fb2 #undef SORT_OUTPUT_FILE #undef SORT_OUTPUT_FB #undef SORT_PRESORT -#undef SORT_PRESORT_ONLY - -#endif /* !SORT_DECLARE_ONLY */ +#undef SORT_UP_TO