1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2007 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU 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, see <http://www.gnu.org/licenses/>. */
19 #include <data/casewriter.h>
20 #include <data/casewriter-provider.h>
25 #include <data/casereader.h>
26 #include <data/casereader-provider.h>
27 #include <data/casewindow.h>
28 #include <data/settings.h>
29 #include <libpspp/compiler.h>
30 #include <libpspp/taint.h>
39 const struct casewriter_class *class;
43 static struct casewriter *create_casewriter_window (size_t value_cnt,
44 casenumber max_in_core);
46 /* Writes case C to WRITER. */
48 casewriter_write (struct casewriter *writer, struct ccase *c)
50 writer->class->write (writer, writer->aux, c);
54 Returns true if successful, false if an I/O error was
55 encountered on WRITER or on some object on which WRITER has a
58 casewriter_destroy (struct casewriter *writer)
63 writer->class->destroy (writer, writer->aux);
64 ok = taint_destroy (writer->taint);
70 /* Destroys WRITER and in its place returns a casereader that can
71 be used to read back the data written to WRITER. WRITER must
72 not be used again after calling this function, even as an
73 argument to casewriter_destroy.
75 Not all casewriters implement this function. Behavior is
76 undefined if it is called on one that does not.
78 If an I/O error was encountered on WRITER or on some object on
79 which WRITER has a dependency, then the error will be
80 propagated to the new casereader. */
82 casewriter_make_reader (struct casewriter *writer)
84 struct casereader *reader;
85 reader = writer->class->convert_to_reader (writer, writer->aux);
86 taint_propagate (writer->taint, casereader_get_taint (reader));
87 taint_destroy (writer->taint);
92 /* Returns a copy of WRITER, which is itself destroyed.
93 Useful for taking over ownership of a casewriter, to enforce
94 preventing the original owner from accessing the casewriter
97 casewriter_rename (struct casewriter *writer)
99 struct casewriter *new = xmemdup (writer, sizeof *writer);
104 /* Returns true if an I/O error or another hard error has
105 occurred on WRITER, a clone of WRITER, or on some object on
106 which WRITER's data has a dependency, false otherwise. */
108 casewriter_error (const struct casewriter *writer)
110 return taint_is_tainted (writer->taint);
113 /* Marks WRITER as having encountered an error.
115 Ordinarily, this function should be called by the
116 implementation of a casewriter, not by the casewriter's
117 client. Instead, casewriter clients should usually ensure
118 that a casewriter's error state is correct by using
119 taint_propagate to propagate to the casewriter's taint
120 structure, which may be obtained via casewriter_get_taint. */
122 casewriter_force_error (struct casewriter *writer)
124 taint_set_taint (writer->taint);
127 /* Returns WRITER's associate taint object, for use with
128 taint_propagate and other taint functions. */
130 casewriter_get_taint (const struct casewriter *writer)
132 return writer->taint;
135 /* Creates and returns a new casewriter with the given CLASS and
136 auxiliary data AUX. */
138 casewriter_create (const struct casewriter_class *class, void *aux)
140 struct casewriter *writer = xmalloc (sizeof *writer);
141 writer->taint = taint_create ();
142 writer->case_cnt = 0;
143 writer->class = class;
148 /* Returns a casewriter for cases with VALUE_CNT struct values
149 per case. The cases written to the casewriter will be kept in
150 memory, unless the amount of memory used grows too large, in
151 which case they will be written to disk.
153 A casewriter created with this function may be passed to
154 casewriter_make_reader.
156 This is usually the right kind of casewriter to use. */
158 autopaging_writer_create (size_t value_cnt)
160 return create_casewriter_window (value_cnt, get_workspace_cases (value_cnt));
163 /* Returns a casewriter for cases with VALUE_CNT struct values
164 per case. The cases written to the casewriter will be kept in
167 A casewriter created with this function may be passed to
168 casewriter_make_reader. */
170 mem_writer_create (size_t value_cnt)
172 return create_casewriter_window (value_cnt, CASENUMBER_MAX);
175 /* Returns a casewriter for cases with VALUE_CNT struct values
176 per case. The cases written to the casewriter will be written
179 A casewriter created with this function may be passed to
180 casewriter_make_reader. */
182 tmpfile_writer_create (size_t value_cnt)
184 return create_casewriter_window (value_cnt, 0);
187 static const struct casewriter_class casewriter_window_class;
188 static const struct casereader_random_class casereader_window_class;
190 /* Creates and returns a new casewriter based on a casewindow.
191 Each of the casewriter's cases are composed of VALUE_CNT
192 struct values. The casewriter's cases will be maintained in
193 memory until MAX_IN_CORE_CASES have been written, at which
194 point they will be written to disk. */
195 static struct casewriter *
196 create_casewriter_window (size_t value_cnt, casenumber max_in_core_cases)
198 struct casewindow *window = casewindow_create (value_cnt, max_in_core_cases);
199 struct casewriter *writer = casewriter_create (&casewriter_window_class,
201 taint_propagate (casewindow_get_taint (window),
202 casewriter_get_taint (writer));
206 /* Writes case C to casewindow writer WINDOW. */
208 casewriter_window_write (struct casewriter *writer UNUSED, void *window_,
211 struct casewindow *window = window_;
212 casewindow_push_head (window, c);
215 /* Destroys casewindow writer WINDOW. */
217 casewriter_window_destroy (struct casewriter *writer UNUSED, void *window_)
219 struct casewindow *window = window_;
220 casewindow_destroy (window);
223 /* Converts casewindow writer WINDOW to a casereader and returns
225 static struct casereader *
226 casewriter_window_convert_to_reader (struct casewriter *writer UNUSED,
229 struct casewindow *window = window_;
230 struct casereader *reader;
231 reader = casereader_create_random (casewindow_get_value_cnt (window),
232 casewindow_get_case_cnt (window),
233 &casereader_window_class, window);
234 taint_propagate (casewindow_get_taint (window),
235 casereader_get_taint (reader));
239 /* Reads the case at the given 0-based OFFSET from the front of
240 WINDOW into C. Returns true if successful, false if
241 OFFSET is beyond the end of file or upon I/O error. */
243 casereader_window_read (struct casereader *reader UNUSED, void *window_,
244 casenumber offset, struct ccase *c)
246 struct casewindow *window = window_;
247 if (offset >= casewindow_get_case_cnt (window))
250 return casewindow_get_case (window, offset, c);
253 /* Destroys casewindow reader WINDOW. */
255 casereader_window_destroy (struct casereader *reader UNUSED, void *window_)
257 struct casewindow *window = window_;
258 casewindow_destroy (window);
261 /* Discards CASE_CNT cases from the front of WINDOW. */
263 casereader_window_advance (struct casereader *reader UNUSED, void *window_,
266 struct casewindow *window = window_;
267 casewindow_pop_tail (window, case_cnt);
270 /* Class for casewindow writer. */
271 static const struct casewriter_class casewriter_window_class =
273 casewriter_window_write,
274 casewriter_window_destroy,
275 casewriter_window_convert_to_reader,
278 /* Class for casewindow reader. */
279 static const struct casereader_random_class casereader_window_class =
281 casereader_window_read,
282 casereader_window_destroy,
283 casereader_window_advance,