X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmath%2Fsort.c;h=fbd40d9b966897ec4df1afd7e53e7916e8dec022;hb=378ff5f35086629f4656c5e46934d1ec51ec00ca;hp=8ce955384b674eb4599f98a2b072e83eaa76c64b;hpb=b0bf9b1b0f727fafac4296a048e3f45db5936f81;p=pspp-builds.git diff --git a/src/math/sort.c b/src/math/sort.c index 8ce95538..fbd40d9b 100644 --- a/src/math/sort.c +++ b/src/math/sort.c @@ -30,17 +30,20 @@ #include #include #include +#include +#include #include #include #include -#include #include #include +#include #include #include #include #include -#include + +#include "minmax.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -57,33 +60,26 @@ static struct casefile *do_internal_sort (struct casereader *, static struct casefile *do_external_sort (struct casereader *, const struct sort_criteria *); -/* Get ready to sort the active file. */ -static void -prepare_to_sort_active_file (void) -{ - proc_cancel_temporary_transformations (); - expr_free (process_if_expr); - process_if_expr = NULL; -} /* Sorts the active file in-place according to CRITERIA. - Returns nonzero if successful. */ -int -sort_active_file_in_place (const struct sort_criteria *criteria) + Returns true if successful. */ +bool +sort_active_file_in_place (struct dataset *ds, + const struct sort_criteria *criteria) { struct casefile *in, *out; - prepare_to_sort_active_file (); - if (!procedure (NULL, NULL)) - return 0; + proc_cancel_temporary_transformations (ds); + if (!procedure (ds, NULL, NULL)) + return false; - in = proc_capture_output (); + in = proc_capture_output (ds); out = sort_execute (casefile_get_destructive_reader (in), criteria); if (out == NULL) - return 0; + return false; - proc_set_source (storage_source_create (out)); - return 1; + proc_set_source (ds, storage_source_create (out)); + return true; } /* Data passed to sort_to_casefile_callback(). */ @@ -98,7 +94,7 @@ static bool sort_to_casefile_callback (const struct casefile *cf, void *cb_data_) { struct sort_to_casefile_cb_data *cb_data = cb_data_; - cb_data->output = sort_execute (casefile_get_reader (cf), cb_data->criteria); + cb_data->output = sort_execute (casefile_get_reader (cf, NULL), cb_data->criteria); return cb_data->output != NULL; } @@ -106,16 +102,20 @@ sort_to_casefile_callback (const struct casefile *cf, void *cb_data_) returns the sorted casefile. Returns a null pointer on failure. */ struct casefile * -sort_active_file_to_casefile (const struct sort_criteria *criteria) +sort_active_file_to_casefile (struct dataset *ds, + const struct sort_criteria *criteria) { struct sort_to_casefile_cb_data cb_data; - prepare_to_sort_active_file (); + proc_cancel_temporary_transformations (ds); cb_data.criteria = criteria; cb_data.output = NULL; - multipass_procedure (sort_to_casefile_callback, &cb_data); - + if (!multipass_procedure (ds, sort_to_casefile_callback, &cb_data)) + { + casefile_destroy (cb_data.output); + return NULL; + } return cb_data.output; } @@ -140,7 +140,7 @@ struct indexed_case unsigned long idx; /* Index to allow for stable sorting. */ }; -static int compare_indexed_cases (const void *, const void *, void *); +static int compare_indexed_cases (const void *, const void *, const void *); /* If the data is in memory, do an internal sort and return a new casefile for the data. Otherwise, return a null pointer. */ @@ -160,7 +160,7 @@ do_internal_sort (struct casereader *reader, return NULL; case_cnt = casefile_get_case_cnt (src); - dst = casefile_create (casefile_get_value_cnt (src)); + dst = fastfile_create (casefile_get_value_cnt (src)); if (case_cnt != 0) { struct indexed_case *cases = nmalloc (sizeof *cases, case_cnt); @@ -172,7 +172,7 @@ do_internal_sort (struct casereader *reader, { bool ok = casereader_read_xfer (reader, &cases[i].c); if (!ok) - abort (); + NOT_REACHED (); cases[i].idx = i; } @@ -182,7 +182,7 @@ do_internal_sort (struct casereader *reader, for (i = 0; i < case_cnt; i++) casefile_append_xfer (dst, &cases[i].c); if (casefile_error (dst)) - abort (); + NOT_REACHED (); free (cases); } @@ -201,9 +201,9 @@ do_internal_sort (struct casereader *reader, at A and B, with a "last resort" comparison for stability, and returns a strcmp()-type result. */ static int -compare_indexed_cases (const void *a_, const void *b_, void *criteria_) +compare_indexed_cases (const void *a_, const void *b_, const void *criteria_) { - struct sort_criteria *criteria = criteria_; + const struct sort_criteria *criteria = criteria_; const struct indexed_case *a = a_; const struct indexed_case *b = b_; int result = compare_record (&a->c, &b->c, criteria); @@ -310,16 +310,17 @@ struct initial_run_state }; static bool destroy_initial_run_state (struct initial_run_state *); -static void process_case (struct initial_run_state *, const struct ccase *, - size_t); +static void process_case (struct initial_run_state *, + const struct ccase *, size_t); static int allocate_cases (struct initial_run_state *); static void output_record (struct initial_run_state *); static void start_run (struct initial_run_state *); static void end_run (struct initial_run_state *); static int compare_record_run (const struct record_run *, const struct record_run *, - struct initial_run_state *); -static int compare_record_run_minheap (const void *, const void *, void *); + const struct initial_run_state *); +static int compare_record_run_minheap (const void *, const void *, + const void *); /* Reads cases from READER and composes initial runs in XSRT. */ static int @@ -362,7 +363,8 @@ write_runs (struct external_sort *xsrt, struct casereader *reader) /* Add a single case to an initial run. */ static void -process_case (struct initial_run_state *irs, const struct ccase *c, size_t idx) +process_case (struct initial_run_state *irs, const struct ccase *c, + size_t idx) { struct record_run *rr; @@ -461,13 +463,14 @@ compare_record (const struct ccase *a, const struct ccase *b, if (c->width == 0) { - double af = case_num (a, c->fv); - double bf = case_num (b, c->fv); + double af = case_num_idx (a, c->fv); + double bf = case_num_idx (b, c->fv); result = af < bf ? -1 : af > bf; } else - result = memcmp (case_str (a, c->fv), case_str (b, c->fv), c->width); + result = memcmp (case_str_idx (a, c->fv), + case_str_idx (b, c->fv), c->width); if (result != 0) return c->dir == SRT_ASCEND ? result : -result; @@ -481,7 +484,7 @@ compare_record (const struct ccase *a, const struct ccase *b, static int compare_record_run (const struct record_run *a, const struct record_run *b, - struct initial_run_state *irs) + const struct initial_run_state *irs) { int result = a->run < b->run ? -1 : a->run > b->run; if (result == 0) @@ -495,7 +498,7 @@ compare_record_run (const struct record_run *a, on the current record according to SCP, but in descending order. */ static int -compare_record_run_minheap (const void *a, const void *b, void *irs) +compare_record_run_minheap (const void *a, const void *b, const void *irs) { return -compare_record_run (a, b, irs); } @@ -506,7 +509,7 @@ start_run (struct initial_run_state *irs) { irs->run++; irs->case_cnt = 0; - irs->casefile = casefile_create (irs->xsrt->value_cnt); + irs->casefile = fastfile_create (irs->xsrt->value_cnt); casefile_to_disk (irs->casefile); case_nullify (&irs->last_output); } @@ -586,7 +589,7 @@ merge (struct external_sort *xsrt) { while (xsrt->run_cnt > 1) { - int order = min (MAX_MERGE_ORDER, xsrt->run_cnt); + int order = MIN (MAX_MERGE_ORDER, xsrt->run_cnt); int idx = choose_merge (xsrt->runs, xsrt->run_cnt, order); xsrt->runs[idx] = merge_once (xsrt, xsrt->runs + idx, order); remove_range (xsrt->runs, xsrt->run_cnt, sizeof *xsrt->runs, @@ -671,7 +674,7 @@ merge_once (struct external_sort *xsrt, } /* Create output file. */ - output = casefile_create (xsrt->value_cnt); + output = fastfile_create (xsrt->value_cnt); casefile_to_disk (output); /* Merge. */