X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fsorter.h;h=4c42d7788d90b04771e8ed31840705acdd25ef7a;hb=75eea53f8050dc1482de088b3cbd081b2511c5a4;hp=be2e80a33b12dade3daffafc9683626998d7b5c0;hpb=78d7afe64ca18c0cf679aec89d611641f5cbe872;p=libucw.git diff --git a/lib/sorter.h b/lib/sorter.h index be2e80a3..4c42d778 100644 --- a/lib/sorter.h +++ b/lib/sorter.h @@ -1,7 +1,10 @@ /* * Sherlock Library -- Universal Sorter * - * (c) 2001 Martin Mares + * (c) 2001--2003 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. */ /* @@ -17,10 +20,16 @@ * defined by the sorter) * SORT_PRESORT include an in-core presorting pass * SORT_UNIFY merge items with identical keys + * SORT_REGULAR all items are equally long and they don't contain + * anything else than the key. In this case, the sorter + * automatically supplies fetch_key, copy_data, fetch_item + * and store_item functions. * SORT_DELETE_INPUT a C expression, if true, the input files are * deleted as soon as possible * SORT_INPUT_FILE input is a file with this name * SORT_INPUT_FB input is a fastbuf stream + * (can be safely NULL if you want to treat original + * input in a different way by file read functions) * SORT_INPUT_FBPAIR input is a pair of fastbuf streams * (not supported by the presorter) * SORT_OUTPUT_FILE output is a file with this name @@ -46,9 +55,11 @@ * fetch data belonging to a just fetched key and store * them to memory following the key, but not over limit. * Returns a pointer to first byte after the data - * or NULL if the data don't fit. - * Important: keys carrying no data must be position - * independent. + * or NULL if the data don't fit. For variable-length + * keys, it can use the rest of SORT_KEY and even return + * pointer before end of the key. + * Important: before PREFIX_fetch_item() succeeds, the key + * must be position independent, the sorter can copy it. * void PREFIX_store_item(struct fastbuf *f, SORT_KEY *k) * [used only with SORT_PRESORT] * write key and all its data read with PREFIX_fetch_data @@ -60,6 +71,9 @@ * from the list of items, but not deallocated, so * the remaining item can freely reference data of the * other one. + * + * After including this file, all parameter macros are automatically + * undef'd. */ /* Declarations of externals from sorter.c */ @@ -71,8 +85,7 @@ extern uns sorter_trace; extern uns sorter_presort_bufsize; extern uns sorter_stream_bufsize; -extern uns sorter_pass_counter, sorter_file_counter; -struct fastbuf *sorter_open_tmp(void); +extern uns sorter_pass_counter; #endif /* !SORT_DECLS_READ */ @@ -98,6 +111,34 @@ struct fastbuf *sorter_open_tmp(void); #define LESS <= #endif +#ifdef SORT_REGULAR + +static inline int +P(fetch_key)(struct fastbuf *in, SORT_KEY *x) +{ + return breadb(in, x, sizeof(*x)); +} + +static inline void +P(copy_data)(struct fastbuf *in UNUSED, struct fastbuf *out, SORT_KEY *x) +{ + bwrite(out, x, sizeof(*x)); +} + +static inline byte * +P(fetch_item)(struct fastbuf *in UNUSED, SORT_KEY *x UNUSED, byte *limit UNUSED) +{ + return (byte *)(x+1); +} + +static inline void +P(store_item)(struct fastbuf *out, SORT_KEY *x) +{ + bwrite(out, x, sizeof(*x)); +} + +#endif + static struct fastbuf * P(flush_out)(struct fastbuf *out) { @@ -143,7 +184,7 @@ P(pass)(struct fastbuf **fb1, struct fastbuf **fb2) struct fastbuf *t; SWAP(out1, out2, t); if (!out1) - out1 = sorter_open_tmp(); + out1 = bopen_tmp(sorter_stream_bufsize); run_count++; } if (comp LESS 0) @@ -159,7 +200,7 @@ P(pass)(struct fastbuf **fb1, struct fastbuf **fb2) { P(merge_data)(in1, in2, out1, kin1, kin2); SWAP(kin1, kprev1, ktmp); - next1 = P(fetch_key)(in1, kin1); /* FIXME: Re-use other code? */ + next1 = P(fetch_key)(in1, kin1); run1 = next1 && (P(compare)(kprev1, kin1) LESS 0); SWAP(kin2, kprev2, ktmp); next2 = P(fetch_key)(in2, kin2); @@ -269,7 +310,7 @@ P(presort)(struct fastbuf **fb1, struct fastbuf **fb2) { SWAP(out1, out2, tbuf); if (!out1) - out1 = sorter_open_tmp(); + out1 = bopen_tmp(sorter_stream_bufsize); current = buffer; last = &first; if (leftover) @@ -342,6 +383,7 @@ P(presort)(struct fastbuf **fb1, struct fastbuf **fb2) (out2 ? (int)((btell(out2) + 1023) / 1024) : 0)); *fb1 = P(flush_out)(out1); *fb2 = P(flush_out)(out2); + xfree(buffer); } #endif /* SORT_PRESORT */ @@ -372,14 +414,14 @@ struct fastbuf *fb1, struct fastbuf *fb2 #ifdef SORT_INPUT_FILE struct fastbuf *fb1, *fb2; fb1 = bopen(inname, O_RDONLY, sorter_stream_bufsize); -#ifdef SORT_DELETE_INPUT - fb1->is_temp_file = SORT_DELETE_INPUT; -#endif fb2 = NULL; #elif defined(SORT_INPUT_FB) struct fastbuf *fb2 = NULL; #endif +#ifdef SORT_DELETE_INPUT + bconfig(fb1, BCONFIG_IS_TEMP_FILE, SORT_DELETE_INPUT); +#endif sorter_pass_counter = 1; #ifdef SORT_PRESORT P(presort)(&fb1, &fb2); @@ -387,12 +429,12 @@ struct fastbuf *fb1, struct fastbuf *fb2 #endif do P(pass)(&fb1, &fb2); while (fb1 && fb2); if (!fb1) - fb1 = sorter_open_tmp(); + fb1 = bopen_tmp(sorter_stream_bufsize); #ifdef SORT_OUTPUT_FB return fb1; #else - fb1->is_temp_file = 0; + bconfig(fb1, BCONFIG_IS_TEMP_FILE, 0); if (rename(fb1->name, outname) < 0) die("rename(%s,%s): %m", fb1->name, outname); bclose(fb1); @@ -403,5 +445,15 @@ struct fastbuf *fb1, struct fastbuf *fb2 #undef LESS #undef SWAP #undef SORT_NODE +#undef SORT_KEY +#undef SORT_PREFIX +#undef SORT_UNIFY +#undef SORT_REGULAR +#undef SORT_DELETE_INPUT +#undef SORT_INPUT_FILE +#undef SORT_INPUT_FB +#undef SORT_INPUT_FBPAIR +#undef SORT_OUTPUT_FILE +#undef SORT_OUTPUT_FB #endif /* !SORT_DECLARE_ONLY */