projects
/
pspp
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
(render_strip) Fix bug that sometimes caused joined text in joined
[pspp]
/
src
/
sort.c
diff --git
a/src/sort.c
b/src/sort.c
index e5feef94c208d545a1679d664a63c372353a42f3..d68ee45b2a71aebee306bac68a4e7818ed482c6c 100644
(file)
--- a/
src/sort.c
+++ b/
src/sort.c
@@
-18,6
+18,7
@@
02111-1307, USA. */
#include <config.h>
02111-1307, USA. */
#include <config.h>
+#include "sort.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@
-30,7
+31,6
@@
#include "heap.h"
#include "lexer.h"
#include "misc.h"
#include "heap.h"
#include "lexer.h"
#include "misc.h"
-#include "sort.h"
#include "str.h"
#include "var.h"
#include "vfm.h"
#include "str.h"
#include "var.h"
#include "vfm.h"
@@
-48,8
+48,6
@@
#include <sys/stat.h>
#endif
#include <sys/stat.h>
#endif
-#undef DEBUGGING
-/*#define DEBUGGING 1*/
#include "debug-print.h"
/* Variables to sort. */
#include "debug-print.h"
/* Variables to sort. */
@@
-59,11
+57,6
@@
int nv_sort;
/* Used when internal-sorting to a separate file. */
static struct case_list **separate_case_tab;
/* Used when internal-sorting to a separate file. */
static struct case_list **separate_case_tab;
-/* Exported by qsort.c. */
-void blp_quicksort (void *pbase, size_t total_elems, size_t size,
- int (*cmp) (const void *, const void *),
- void *temp_buf);
-
/* Other prototypes. */
static int compare_case_lists (const void *, const void *);
static int do_internal_sort (int separate);
/* Other prototypes. */
static int compare_case_lists (const void *, const void *);
static int do_internal_sort (int separate);
@@
-118,7
+111,7
@@
parse_sort_variables (void)
int prev_nv_sort = nv_sort;
int order = SRT_ASCEND;
int prev_nv_sort = nv_sort;
int order = SRT_ASCEND;
- if (!parse_variables (
&
default_dict, &v_sort, &nv_sort,
+ if (!parse_variables (default_dict, &v_sort, &nv_sort,
PV_NO_DUPLICATE | PV_APPEND | PV_NO_SCRATCH))
return 0;
if (lex_match ('('))
PV_NO_DUPLICATE | PV_APPEND | PV_NO_SCRATCH))
return 0;
if (lex_match ('('))
@@
-222,13
+215,16
@@
do_internal_sort (int separate)
return 0;
}
return 0;
}
-/* Compares the NV_SORT variables in V_SORT[] between the `case_list's
- at _A and _B, and returns a strcmp()-type result. */
+/* Compares the NV_SORT variables in V_SORT[] between the
+ `case_list's at A and B, and returns a strcmp()-type
+ result. */
static int
static int
-compare_case_lists (const void *
pa, const void *pb
)
+compare_case_lists (const void *
a_, const void *b_
)
{
{
- struct case_list *a = *(struct case_list **) pa;
- struct case_list *b = *(struct case_list **) pb;
+ struct case_list *const *pa = a_;
+ struct case_list *const *pb = b_;
+ struct case_list *a = *pa;
+ struct case_list *b = *pb;
struct variable *v;
int result = 0;
int i;
struct variable *v;
int result = 0;
int i;
@@
-239,27
+235,21
@@
compare_case_lists (const void *pa, const void *pb)
if (v->type == NUMERIC)
{
if (v->type == NUMERIC)
{
- if (approx_ne (a->c.data[v->fv].f, b->c.data[v->fv].f))
- {
- result = (a->c.data[v->fv].f > b->c.data[v->fv].f) ? 1 : -1;
- break;
- }
+ double af = a->c.data[v->fv].f;
+ double bf = b->c.data[v->fv].f;
+
+ result = af < bf ? -1 : af > bf;
}
else
}
else
- {
- result = memcmp (a->c.data[v->fv].s, b->c.data[v->fv].s, v->width);
- if (result != 0)
- break;
- }
- }
+ result = memcmp (a->c.data[v->fv].s, b->c.data[v->fv].s, v->width);
- if (v->p.srt.order == SRT_ASCEND)
- return result;
- else
- {
- assert (v->p.srt.order == SRT_DESCEND);
- return -result;
+ if (result != 0)
+ break;
}
}
+
+ if (v->p.srt.order == SRT_DESCEND)
+ result = -result;
+ return result;
}
\f
/* External sort. */
}
\f
/* External sort. */
@@
-495,7
+485,8
@@
allocate_cases (void)
{
/* This is the size of one case. */
const int case_size = (sizeof (struct repl_sel_tree)
{
/* This is the size of one case. */
const int case_size = (sizeof (struct repl_sel_tree)
- + sizeof (union value) * (default_dict.nval - 1)
+ + (sizeof (union value)
+ * (dict_get_value_cnt (default_dict) - 1))
+ sizeof (struct repl_sel_tree *));
x = NULL;
+ sizeof (struct repl_sel_tree *));
x = NULL;
@@
-511,7
+502,8
@@
allocate_cases (void)
for (i = 0; i < x_max; i++)
{
x[i] = malloc (sizeof (struct repl_sel_tree)
for (i = 0; i < x_max; i++)
{
x[i] = malloc (sizeof (struct repl_sel_tree)
- + sizeof (union value) * (default_dict.nval - 1));
+ + (sizeof (union value)
+ * (dict_get_value_cnt (default_dict) - 1)));
if (x[i] == NULL)
break;
}
if (x[i] == NULL)
break;
}
@@
-737,7
+729,8
@@
write_initial_runs (int separate)
J->rn = 0;
J->fe = x[(x_max + j) / 2];
J->fi = x[j / 2];
J->rn = 0;
J->fe = x[(x_max + j) / 2];
J->fi = x[j / 2];
- memset (J->record, 0, default_dict.nval * sizeof (union value));
+ memset (J->record, 0,
+ dict_get_value_cnt (default_dict) * sizeof (union value));
}
}
}
}
@@
-924,10
+917,11
@@
merge (void)
order = MAX_MERGE_ORDER;
if (x_max / order < MIN_BUFFER_SIZE_RECS)
order = x_max / MIN_BUFFER_SIZE_RECS;
order = MAX_MERGE_ORDER;
if (x_max / order < MIN_BUFFER_SIZE_RECS)
order = x_max / MIN_BUFFER_SIZE_RECS;
- else if (x_max / order * sizeof (union value) * d
efault_dict.nval
+ else if (x_max / order * sizeof (union value) * d
ict_get_value_cnt (default_dict)
< MIN_BUFFER_SIZE_BYTES)
order = x_max / (MIN_BUFFER_SIZE_BYTES
< MIN_BUFFER_SIZE_BYTES)
order = x_max / (MIN_BUFFER_SIZE_BYTES
- / (sizeof (union value) * (default_dict.nval - 1)));
+ / (sizeof (union value)
+ * (dict_get_value_cnt (default_dict) - 1)));
/* Make sure the order of merge is bounded. */
if (order < 2)
/* Make sure the order of merge is bounded. */
if (order < 2)
@@
-1068,8
+1062,8
@@
merge_once (int run_index[], int run_length[], int n_runs)
buffered[i] = min (records_per_buffer, run_length[i]);
for (j = 0; j < buffered[i]; j++)
if ((int) fread (x[j + ofs]->record, sizeof (union value),
buffered[i] = min (records_per_buffer, run_length[i]);
for (j = 0; j < buffered[i]; j++)
if ((int) fread (x[j + ofs]->record, sizeof (union value),
- d
efault_dict.nval
, handle[i])
- != d
efault_dict.nval
)
+ d
ict_get_value_cnt (default_dict)
, handle[i])
+ != d
ict_get_value_cnt (default_dict)
)
{
sprintf (tmp_extname, "%08x", run_index[i]);
if (ferror (handle[i]))
{
sprintf (tmp_extname, "%08x", run_index[i]);
if (ferror (handle[i]))
@@
-1097,8
+1091,9
@@
merge_once (int run_index[], int run_length[], int n_runs)
min = i;
if ((int) fwrite (x[buffer_ptr[min]]->record, sizeof (union value),
min = i;
if ((int) fwrite (x[buffer_ptr[min]]->record, sizeof (union value),
- default_dict.nval, handle[N_INPUT_BUFFERS])
- != default_dict.nval)
+ dict_get_value_cnt (default_dict),
+ handle[N_INPUT_BUFFERS])
+ != dict_get_value_cnt (default_dict))
{
sprintf (tmp_extname, "%08x", run_index[i]);
msg (SE, _("%s: Error writing temporary file in "
{
sprintf (tmp_extname, "%08x", run_index[i]);
msg (SE, _("%s: Error writing temporary file in "
@@
-1126,8
+1121,9
@@
merge_once (int run_index[], int run_length[], int n_runs)
buffered[min] = min (records_per_buffer, run_length[min]);
for (j = 0; j < buffered[min]; j++)
if ((int) fread (x[j + ofs]->record, sizeof (union value),
buffered[min] = min (records_per_buffer, run_length[min]);
for (j = 0; j < buffered[min]; j++)
if ((int) fread (x[j + ofs]->record, sizeof (union value),
- default_dict.nval, handle[min])
- != default_dict.nval)
+ dict_get_value_cnt (default_dict),
+ handle[min])
+ != dict_get_value_cnt (default_dict))
{
sprintf (tmp_extname, "%08x", run_index[min]);
if (ferror (handle[min]))
{
sprintf (tmp_extname, "%08x", run_index[min]);
if (ferror (handle[min]))
@@
-1220,7
+1216,7
@@
lossage:
/* Reads all the records from the source stream and passes them
to write_case(). */
/* Reads all the records from the source stream and passes them
to write_case(). */
-void
+
static
void
sort_stream_read (void)
{
read_sort_output (write_case);
sort_stream_read (void)
{
read_sort_output (write_case);
@@
-1364,7
+1360,7
@@
sort_stream_write (void)
}
/* Switches mode from sink to source. */
}
/* Switches mode from sink to source. */
-void
+
static
void
sort_stream_mode (void)
{
/* If this is not done, then we get the following source/sink pairs:
sort_stream_mode (void)
{
/* If this is not done, then we get the following source/sink pairs: