1 /* PSPP - computes sample statistics.
2 Copyright (C) 2007 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
21 #include <data/casewriter.h>
22 #include <data/casewriter-provider.h>
27 #include <data/casereader.h>
28 #include <data/casereader-provider.h>
29 #include <data/casewindow.h>
30 #include <data/settings.h>
31 #include <libpspp/compiler.h>
32 #include <libpspp/taint.h>
41 const struct casewriter_class *class;
45 static struct casewriter *create_casewriter_window (size_t value_cnt,
46 casenumber max_in_core);
48 /* Writes case C to WRITER. */
50 casewriter_write (struct casewriter *writer, struct ccase *c)
52 writer->class->write (writer, writer->aux, c);
56 Returns true if successful, false if an I/O error was
57 encountered on WRITER or on some object on which WRITER has a
60 casewriter_destroy (struct casewriter *writer)
65 writer->class->destroy (writer, writer->aux);
66 ok = taint_destroy (writer->taint);
72 /* Destroys WRITER and in its place returns a casereader that can
73 be used to read back the data written to WRITER. WRITER must
74 not be used again after calling this function, even as an
75 argument to casewriter_destroy.
77 Not all casewriters implement this function. Behavior is
78 undefined if it is called on one that does not.
80 If an I/O error was encountered on WRITER or on some object on
81 which WRITER has a dependency, then the error will be
82 propagated to the new casereader. */
84 casewriter_make_reader (struct casewriter *writer)
86 struct casereader *reader;
87 reader = writer->class->convert_to_reader (writer, writer->aux);
88 taint_propagate (writer->taint, casereader_get_taint (reader));
89 taint_destroy (writer->taint);
94 /* Returns a copy of WRITER, which is itself destroyed.
95 Useful for taking over ownership of a casewriter, to enforce
96 preventing the original owner from accessing the casewriter
99 casewriter_rename (struct casewriter *writer)
101 struct casewriter *new = xmemdup (writer, sizeof *writer);
106 /* Returns true if an I/O error or another hard error has
107 occurred on WRITER, a clone of WRITER, or on some object on
108 which WRITER's data has a dependency, false otherwise. */
110 casewriter_error (const struct casewriter *writer)
112 return taint_is_tainted (writer->taint);
115 /* Marks WRITER as having encountered an error.
117 Ordinarily, this function should be called by the
118 implementation of a casewriter, not by the casewriter's
119 client. Instead, casewriter clients should usually ensure
120 that a casewriter's error state is correct by using
121 taint_propagate to propagate to the casewriter's taint
122 structure, which may be obtained via casewriter_get_taint. */
124 casewriter_force_error (struct casewriter *writer)
126 taint_set_taint (writer->taint);
129 /* Returns WRITER's associate taint object, for use with
130 taint_propagate and other taint functions. */
132 casewriter_get_taint (const struct casewriter *writer)
134 return writer->taint;
137 /* Creates and returns a new casewriter with the given CLASS and
138 auxiliary data AUX. */
140 casewriter_create (const struct casewriter_class *class, void *aux)
142 struct casewriter *writer = xmalloc (sizeof *writer);
143 writer->taint = taint_create ();
144 writer->case_cnt = 0;
145 writer->class = class;
150 /* Returns a casewriter for cases with VALUE_CNT struct values
151 per case. The cases written to the casewriter will be kept in
152 memory, unless the amount of memory used grows too large, in
153 which case they will be written to disk.
155 A casewriter created with this function may be passed to
156 casewriter_make_reader.
158 This is usually the right kind of casewriter to use. */
160 autopaging_writer_create (size_t value_cnt)
162 return create_casewriter_window (value_cnt, get_workspace_cases (value_cnt));
165 /* Returns a casewriter for cases with VALUE_CNT struct values
166 per case. The cases written to the casewriter will be kept in
169 A casewriter created with this function may be passed to
170 casewriter_make_reader. */
172 mem_writer_create (size_t value_cnt)
174 return create_casewriter_window (value_cnt, CASENUMBER_MAX);
177 /* Returns a casewriter for cases with VALUE_CNT struct values
178 per case. The cases written to the casewriter will be written
181 A casewriter created with this function may be passed to
182 casewriter_make_reader. */
184 tmpfile_writer_create (size_t value_cnt)
186 return create_casewriter_window (value_cnt, 0);
189 static const struct casewriter_class casewriter_window_class;
190 static const struct casereader_random_class casereader_window_class;
192 /* Creates and returns a new casewriter based on a casewindow.
193 Each of the casewriter's cases are composed of VALUE_CNT
194 struct values. The casewriter's cases will be maintained in
195 memory until MAX_IN_CORE_CASES have been written, at which
196 point they will be written to disk. */
197 static struct casewriter *
198 create_casewriter_window (size_t value_cnt, casenumber max_in_core_cases)
200 struct casewindow *window = casewindow_create (value_cnt, max_in_core_cases);
201 struct casewriter *writer = casewriter_create (&casewriter_window_class,
203 taint_propagate (casewindow_get_taint (window),
204 casewriter_get_taint (writer));
208 /* Writes case C to casewindow writer WINDOW. */
210 casewriter_window_write (struct casewriter *writer UNUSED, void *window_,
213 struct casewindow *window = window_;
214 casewindow_push_head (window, c);
217 /* Destroys casewindow writer WINDOW. */
219 casewriter_window_destroy (struct casewriter *writer UNUSED, void *window_)
221 struct casewindow *window = window_;
222 casewindow_destroy (window);
225 /* Converts casewindow writer WINDOW to a casereader and returns
227 static struct casereader *
228 casewriter_window_convert_to_reader (struct casewriter *writer UNUSED,
231 struct casewindow *window = window_;
232 struct casereader *reader;
233 reader = casereader_create_random (casewindow_get_value_cnt (window),
234 casewindow_get_case_cnt (window),
235 &casereader_window_class, window);
236 taint_propagate (casewindow_get_taint (window),
237 casereader_get_taint (reader));
241 /* Reads the case at the given 0-based OFFSET from the front of
242 WINDOW into C. Returns true if successful, false if
243 OFFSET is beyond the end of file or upon I/O error. */
245 casereader_window_read (struct casereader *reader UNUSED, void *window_,
246 casenumber offset, struct ccase *c)
248 struct casewindow *window = window_;
249 if (offset >= casewindow_get_case_cnt (window))
252 return casewindow_get_case (window, offset, c);
255 /* Destroys casewindow reader WINDOW. */
257 casereader_window_destroy (struct casereader *reader UNUSED, void *window_)
259 struct casewindow *window = window_;
260 casewindow_destroy (window);
263 /* Discards CASE_CNT cases from the front of WINDOW. */
265 casereader_window_advance (struct casereader *reader UNUSED, void *window_,
268 struct casewindow *window = window_;
269 casewindow_pop_tail (window, case_cnt);
272 /* Class for casewindow writer. */
273 static const struct casewriter_class casewriter_window_class =
275 casewriter_window_write,
276 casewriter_window_destroy,
277 casewriter_window_convert_to_reader,
280 /* Class for casewindow reader. */
281 static const struct casereader_random_class casereader_window_class =
283 casereader_window_read,
284 casereader_window_destroy,
285 casereader_window_advance,