1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2007, 2009 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>
40 const struct casewriter_class *class;
44 static struct casewriter *create_casewriter_window (size_t value_cnt,
45 casenumber max_in_core);
47 /* Writes case C to WRITER. */
49 casewriter_write (struct casewriter *writer, struct ccase *c)
51 assert (case_get_value_cnt (c) >= writer->value_cnt);
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 /* Returns the number of `union value's in each case written to
75 casewriter_get_value_cnt (const struct casewriter *writer)
77 return writer->value_cnt;
80 /* Destroys WRITER and in its place returns a casereader that can
81 be used to read back the data written to WRITER. WRITER must
82 not be used again after calling this function, even as an
83 argument to casewriter_destroy.
85 Not all casewriters implement this function. Behavior is
86 undefined if it is called on one that does not.
88 If an I/O error was encountered on WRITER or on some object on
89 which WRITER has a dependency, then the error will be
90 propagated to the new casereader. */
92 casewriter_make_reader (struct casewriter *writer)
94 struct casereader *reader = writer->class->convert_to_reader (writer, writer->aux);
95 taint_propagate (writer->taint, casereader_get_taint (reader));
96 taint_destroy (writer->taint);
101 /* Returns a copy of WRITER, which is itself destroyed.
102 Useful for taking over ownership of a casewriter, to enforce
103 preventing the original owner from accessing the casewriter
106 casewriter_rename (struct casewriter *writer)
108 struct casewriter *new = xmemdup (writer, sizeof *writer);
113 /* Returns true if an I/O error or another hard error has
114 occurred on WRITER, a clone of WRITER, or on some object on
115 which WRITER's data has a dependency, false otherwise. */
117 casewriter_error (const struct casewriter *writer)
119 return taint_is_tainted (writer->taint);
122 /* Marks WRITER as having encountered an error.
124 Ordinarily, this function should be called by the
125 implementation of a casewriter, not by the casewriter's
126 client. Instead, casewriter clients should usually ensure
127 that a casewriter's error state is correct by using
128 taint_propagate to propagate to the casewriter's taint
129 structure, which may be obtained via casewriter_get_taint. */
131 casewriter_force_error (struct casewriter *writer)
133 taint_set_taint (writer->taint);
136 /* Returns WRITER's associate taint object, for use with
137 taint_propagate and other taint functions. */
139 casewriter_get_taint (const struct casewriter *writer)
141 return writer->taint;
144 /* Creates and returns a new casewriter with the given CLASS and
145 auxiliary data AUX. The casewriter accepts cases with
146 VALUE_CNT `union value's. */
148 casewriter_create (size_t value_cnt,
149 const struct casewriter_class *class, void *aux)
151 struct casewriter *writer = xmalloc (sizeof *writer);
152 writer->taint = taint_create ();
153 writer->value_cnt = value_cnt;
154 writer->case_cnt = 0;
155 writer->class = class;
160 /* Returns a casewriter for cases with VALUE_CNT struct values
161 per case. The cases written to the casewriter will be kept in
162 memory, unless the amount of memory used grows too large, in
163 which case they will be written to disk.
165 A casewriter created with this function may be passed to
166 casewriter_make_reader.
168 This is usually the right kind of casewriter to use. */
170 autopaging_writer_create (size_t value_cnt)
172 return create_casewriter_window (value_cnt, settings_get_workspace_cases (value_cnt));
175 /* Returns a casewriter for cases with VALUE_CNT struct values
176 per case. The cases written to the casewriter will be kept in
179 A casewriter created with this function may be passed to
180 casewriter_make_reader. */
182 mem_writer_create (size_t value_cnt)
184 return create_casewriter_window (value_cnt, CASENUMBER_MAX);
187 /* Returns a casewriter for cases with VALUE_CNT struct values
188 per case. The cases written to the casewriter will be written
191 A casewriter created with this function may be passed to
192 casewriter_make_reader. */
194 tmpfile_writer_create (size_t value_cnt)
196 return create_casewriter_window (value_cnt, 0);
199 static const struct casewriter_class casewriter_window_class;
200 static const struct casereader_random_class casereader_window_class;
202 /* Creates and returns a new casewriter based on a casewindow.
203 Each of the casewriter's cases are composed of VALUE_CNT
204 struct values. The casewriter's cases will be maintained in
205 memory until MAX_IN_CORE_CASES have been written, at which
206 point they will be written to disk. */
207 static struct casewriter *
208 create_casewriter_window (size_t value_cnt, casenumber max_in_core_cases)
210 struct casewindow *window = casewindow_create (value_cnt, max_in_core_cases);
211 struct casewriter *writer = casewriter_create (value_cnt,
212 &casewriter_window_class,
214 taint_propagate (casewindow_get_taint (window),
215 casewriter_get_taint (writer));
219 /* Writes case C to casewindow writer WINDOW. */
221 casewriter_window_write (struct casewriter *writer UNUSED, void *window_,
224 struct casewindow *window = window_;
225 casewindow_push_head (window, c);
228 /* Destroys casewindow writer WINDOW. */
230 casewriter_window_destroy (struct casewriter *writer UNUSED, void *window_)
232 struct casewindow *window = window_;
233 casewindow_destroy (window);
236 /* Converts casewindow writer WINDOW to a casereader and returns
238 static struct casereader *
239 casewriter_window_convert_to_reader (struct casewriter *writer UNUSED,
242 struct casewindow *window = window_;
243 struct casereader *reader =
244 casereader_create_random (casewindow_get_value_cnt (window),
245 casewindow_get_case_cnt (window),
246 &casereader_window_class, window);
248 taint_propagate (casewindow_get_taint (window),
249 casereader_get_taint (reader));
253 /* Reads and returns the case at the given 0-based OFFSET from
254 the front of WINDOW into C. Returns a null pointer if OFFSET
255 is beyond the end of file or upon I/O error. The caller must
256 call case_unref() on the returned case when it is no longer
258 static struct ccase *
259 casereader_window_read (struct casereader *reader UNUSED, void *window_,
262 struct casewindow *window = window_;
263 if (offset >= casewindow_get_case_cnt (window))
265 return casewindow_get_case (window, offset);
268 /* Destroys casewindow reader WINDOW. */
270 casereader_window_destroy (struct casereader *reader UNUSED, void *window_)
272 struct casewindow *window = window_;
273 casewindow_destroy (window);
276 /* Discards CASE_CNT cases from the front of WINDOW. */
278 casereader_window_advance (struct casereader *reader UNUSED, void *window_,
281 struct casewindow *window = window_;
282 casewindow_pop_tail (window, case_cnt);
285 /* Class for casewindow writer. */
286 static const struct casewriter_class casewriter_window_class =
288 casewriter_window_write,
289 casewriter_window_destroy,
290 casewriter_window_convert_to_reader,
293 /* Class for casewindow reader. */
294 static const struct casereader_random_class casereader_window_class =
296 casereader_window_read,
297 casereader_window_destroy,
298 casereader_window_advance,