/*
* Sherlock Library -- Universal Sorter
*
- * (c) 2001 Martin Mares <mj@ucw.cz>
+ * (c) 2001--2003 Martin Mares <mj@ucw.cz>
+ *
+ * This software may be freely distributed and used according to the terms
+ * of the GNU Lesser General Public License.
*/
/*
* 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
* 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
* 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 */
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 */
#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)
{
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)
{
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);
{
SWAP(out1, out2, tbuf);
if (!out1)
- out1 = sorter_open_tmp();
+ out1 = bopen_tmp(sorter_stream_bufsize);
current = buffer;
last = &first;
if (leftover)
(out2 ? (int)((btell(out2) + 1023) / 1024) : 0));
*fb1 = P(flush_out)(out1);
*fb2 = P(flush_out)(out2);
+ xfree(buffer);
}
#endif /* SORT_PRESORT */
#endif
#ifdef SORT_DELETE_INPUT
- fb1->is_temp_file = SORT_DELETE_INPUT;
+ bconfig(fb1, BCONFIG_IS_TEMP_FILE, SORT_DELETE_INPUT);
#endif
sorter_pass_counter = 1;
#ifdef SORT_PRESORT
#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);
#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 */