1 /* PSPP - computes sample statistics.
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #include <data/casefile.h>
21 #include <data/fastfile.h>
23 #include <data/case.h>
25 #include <gsl/gsl_randist.h>
26 #include <gsl/gsl_rng.h>
28 #include <language/command.h>
29 #include <language/lexer/lexer.h>
30 #include <libpspp/assertion.h>
34 static void test_casefile (int pattern, size_t value_cnt, size_t case_cnt);
35 static void get_random_case (struct ccase *, size_t value_cnt,
37 static void write_random_case (struct casefile *cf, size_t case_idx);
38 static void read_and_verify_random_case (struct casefile *cf,
39 struct casereader *reader,
41 static void test_casereader_clone (struct casereader *reader1, size_t case_cnt);
44 static void fail_test (const char *message, ...);
47 cmd_debug_casefile (struct lexer *lexer, struct dataset *ds UNUSED)
49 static const size_t sizes[] =
51 1, 2, 3, 4, 5, 6, 7, 14, 15, 16, 17, 31, 55, 73,
52 100, 137, 257, 521, 1031, 2053
58 size_max = sizeof sizes / sizeof *sizes;
59 if (lex_match_id (lexer, "SMALL"))
66 if (lex_token (lexer) != '.')
67 return lex_end_of_command (lexer);
69 for (pattern = 0; pattern < 7; pattern++)
73 for (size = sizes; size < sizes + size_max; size++)
77 for (case_cnt = 0; case_cnt <= case_max;
78 case_cnt = (case_cnt * 2) + 1)
79 test_casefile (pattern, *size, case_cnt);
82 printf ("Casefile tests succeeded.\n");
87 test_casefile (int pattern, size_t value_cnt, size_t case_cnt)
90 struct casereader *r1, *r2;
95 rng = gsl_rng_alloc (gsl_rng_mt19937);
96 cf = fastfile_create (value_cnt);
98 casefile_to_disk (cf);
99 for (i = 0; i < case_cnt; i++)
100 write_random_case (cf, i);
103 r1 = casefile_get_reader (cf, NULL);
104 r2 = casefile_get_reader (cf, NULL);
109 for (i = 0; i < case_cnt; i++)
111 read_and_verify_random_case (cf, r1, i);
112 read_and_verify_random_case (cf, r2, i);
116 for (i = 0; i < case_cnt; i++)
117 read_and_verify_random_case (cf, r1, i);
118 for (i = 0; i < case_cnt; i++)
119 read_and_verify_random_case (cf, r2, i);
124 for (i = j = 0; i < case_cnt; i++)
126 read_and_verify_random_case (cf, r1, i);
127 if (gsl_rng_get (rng) % pattern == 0)
128 read_and_verify_random_case (cf, r2, j++);
129 if (i == case_cnt / 2)
130 casefile_to_disk (cf);
132 for (; j < case_cnt; j++)
133 read_and_verify_random_case (cf, r2, j);
136 test_casereader_clone (r1, case_cnt);
137 test_casereader_clone (r2, case_cnt);
142 if (casereader_read (r1, &c))
143 fail_test ("Casereader 1 not at end of file.");
144 if (casereader_read (r2, &c))
145 fail_test ("Casereader 2 not at end of file.");
147 casereader_destroy (r1);
149 casereader_destroy (r2);
152 r1 = casefile_get_destructive_reader (cf);
153 for (i = 0; i < case_cnt; i++)
155 struct ccase read_case, expected_case;
157 get_random_case (&expected_case, value_cnt, i);
158 if (!casereader_read_xfer (r1, &read_case))
159 fail_test ("Premature end of casefile.");
160 for (j = 0; j < value_cnt; j++)
162 double a = case_num_idx (&read_case, j);
163 double b = case_num_idx (&expected_case, j);
165 fail_test ("Case %lu fails comparison.", (unsigned long) i);
167 case_destroy (&expected_case);
168 case_destroy (&read_case);
170 casereader_destroy (r1);
172 casefile_destroy (cf);
177 get_random_case (struct ccase *c, size_t value_cnt, size_t case_idx)
180 case_create (c, value_cnt);
181 for (i = 0; i < value_cnt; i++)
182 case_data_rw_idx (c, i)->f = case_idx % 257 + i;
186 write_random_case (struct casefile *cf, size_t case_idx)
189 get_random_case (&c, casefile_get_value_cnt (cf), case_idx);
190 casefile_append_xfer (cf, &c);
194 read_and_verify_random_case (struct casefile *cf,
195 struct casereader *reader, size_t case_idx)
197 struct ccase read_case, expected_case;
201 value_cnt = casefile_get_value_cnt (cf);
202 get_random_case (&expected_case, value_cnt, case_idx);
203 if (!casereader_read (reader, &read_case))
204 fail_test ("Premature end of casefile.");
205 for (i = 0; i < value_cnt; i++)
207 double a = case_num_idx (&read_case, i);
208 double b = case_num_idx (&expected_case, i);
210 fail_test ("Case %lu fails comparison.", (unsigned long) case_idx);
212 case_destroy (&read_case);
213 case_destroy (&expected_case);
217 test_casereader_clone (struct casereader *reader1, size_t case_cnt)
223 struct casefile *src = casereader_get_casefile (reader1);
224 struct casereader *clone = NULL;
226 size_t value_cnt = casefile_get_value_cnt (src);
228 struct casefile *newfile = fastfile_create (value_cnt);
229 struct casereader *newreader;
232 /* Read a 3rd of the cases */
233 for ( i = 0 ; i < case_cnt / 3 ; ++i )
235 casereader_read (reader1, &c1);
239 clone = casereader_clone (reader1);
241 /* Copy all the cases into a new file */
242 while( casereader_read (reader1, &c1))
244 casefile_append_xfer (newfile, &c1);
248 newreader = casefile_get_reader (newfile, NULL);
250 /* Make sure that the new file's are identical to those returned from
252 while( casereader_read (clone, &c1))
254 const union value *v1;
255 const union value *v2;
258 if ( ! casereader_read_xfer (newreader, &c2) )
264 v1 = case_data_all (&c1) ;
265 v2 = case_data_all (&c2) ;
267 if ( 0 != memcmp (v1, v2, value_cnt * MAX_SHORT_STRING))
268 fail_test ("Cloned reader read different value at case %ld", cases);
275 fail_test ("Cloned reader reads different number of cases.");
280 fail_test (const char *message, ...)
284 va_start (args, message);
285 vprintf (message, args);