From 21d1bfd6633ae0ba18b3a394a96970ac9a8c1a46 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 20 Dec 2003 00:44:35 +0000 Subject: [PATCH] Fri Dec 19 16:38:35 2003 Ben Pfaff * matrix-data.c (compare_factors) Use lexicographical_compare() algorithm. (compare_doubles) New function. * algorithm.c: (lexicographical_compare) New algorithm. --- src/ChangeLog | 8 ++++++++ src/algorithm.c | 30 +++++++++++++++++++++++++++++ src/algorithm.h | 17 +++++++++++++--- src/matrix-data.c | 49 +++++++++++++++++++++++++++++------------------ 4 files changed, 82 insertions(+), 22 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index f00fddfd..16b12205 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +Fri Dec 19 16:38:35 2003 Ben Pfaff + + * matrix-data.c (compare_factors) Use lexicographical_compare() + algorithm. + (compare_doubles) New function. + + * algorithm.c: (lexicographical_compare) New algorithm. + Fri Dec 19 16:23:45 2003 Ben Pfaff * matrix-data.c (compare_variables_by_mxd_vartype): Rewrite. diff --git a/src/algorithm.c b/src/algorithm.c index ac7f28df..c6bdae27 100644 --- a/src/algorithm.c +++ b/src/algorithm.c @@ -362,6 +362,36 @@ binary_search (const void *array, size_t count, size_t size, } return NULL; } + +/* Lexicographically compares ARRAY1, which contains COUNT1 + elements of SIZE bytes each, to ARRAY2, which contains COUNT2 + elements of SIZE bytes, according to COMPARE. Returns a + strcmp()-type result. AUX is passed to COMPARE as auxiliary + data. */ +int +lexicographical_compare (const void *array1, size_t count1, + const void *array2, size_t count2, + size_t size, + algo_compare_func *compare, void *aux) +{ + const unsigned char *first1 = array1; + const unsigned char *first2 = array2; + size_t min_count = count1 < count2 ? count1 : count2; + + while (min_count > 0) + { + int cmp = compare (first1, first2, aux); + if (cmp != 0) + return cmp; + + first1 += size; + first2 += size; + min_count--; + } + + return count1 < count2 ? -1 : count1 > count2; +} + /* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. diff --git a/src/algorithm.h b/src/algorithm.h index 2c897bda..d32b5c07 100644 --- a/src/algorithm.h +++ b/src/algorithm.h @@ -65,11 +65,22 @@ size_t remove_copy_if (const void *array, size_t count, size_t size, void *result, algo_predicate_func *predicate, void *aux); -/* Searches ARRAY, which contains COUNT of SIZE bytes each, for - VALUE, using a binary search. ARRAY must ordered according to - COMPARE. AUX is passed to COMPARE as auxiliary data. */ +/* Searches ARRAY, which contains COUNT elements of SIZE bytes + each, for VALUE, using a binary search. ARRAY must ordered + according to COMPARE. AUX is passed to COMPARE as auxiliary + data. */ void *binary_search (const void *array, size_t count, size_t size, void *value, algo_compare_func *compare, void *aux); +/* Lexicographically compares ARRAY1, which contains COUNT1 + elements of SIZE bytes each, to ARRAY2, which contains COUNT2 + elements of SIZE bytes, according to COMPARE. Returns a + strcmp()-type result. AUX is passed to COMPARE as auxiliary + data. */ +int lexicographical_compare (const void *array1, size_t count1, + const void *array2, size_t count2, + size_t size, + algo_compare_func *compare, void *aux); + #endif /* sort-algo.h */ diff --git a/src/matrix-data.c b/src/matrix-data.c index b2adcd4a..986186ab 100644 --- a/src/matrix-data.c +++ b/src/matrix-data.c @@ -39,6 +39,7 @@ char *alloca (); #include #include #include +#include "algorithm.h" #include "alloc.h" #include "command.h" #include "data-in.h" @@ -1641,29 +1642,39 @@ wr_read_splits (void) return 1; } -/* Return strcmp()-type comparison of the n_factors factors at _A and - _B. Sort missing values toward the end. */ +/* Compares doubles A and B, treating SYSMIS as greatest. */ static int -compare_factors (const void *pa, const void *pb) +compare_doubles (const void *a_, const void *b_, void *aux unused) { - const double *a = (*(struct factor_data **) pa)->factors; - const double *b = (*(struct factor_data **) pb)->factors; - int i; + const double *a = a_; + const double *b = b_; - for (i = 0; i < n_factors; i++, a++, b++) - { - if (*a == *b) - continue; - - if (*a == SYSMIS) - return 1; - else if (*b == SYSMIS) - return -1; - else - return *a - *b < 0 ? -1 : 1; - } + if (*a == *b) + return 0; + else if (*a == SYSMIS) + return 1; + else if (*b == SYSMIS) + return -1; + else if (*a > *b) + return 1; + else + return -1; +} - return 0; +/* Return strcmp()-type comparison of the n_factors factors at _A and + _B. Sort missing values toward the end. */ +static int +compare_factors (const void *a_, const void *b_) +{ + struct factor_data *const *pa = a_; + struct factor_data *const *pb = b_; + const double *a = (*pa)->factors; + const double *b = (*pb)->factors; + + return lexicographical_compare (a, n_factors, + b, n_factors, + sizeof *a, + compare_doubles, NULL); } /* Write out the data for the current split file to the active -- 2.30.2