From: Ben Pfaff Date: Mon, 13 Aug 2007 00:41:34 +0000 (+0000) Subject: Make casewriters keep track of the number of `union value's in each X-Git-Tag: v0.6.0~316 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=130ced32165dc409b1be560d3d7a581a7ba3c5ee;p=pspp-builds.git Make casewriters keep track of the number of `union value's in each case. This is useful for two reasons: casewriter_write can then check that the case being written is large enough, and later recipients of the casewriter can determine the size of the case. * get.c (case_map_get_value_cnt): New function. * casewriter-translator.c (casewriter_create_translator): Add value_cnt parameter. * casewriter.c (struct casewriter): Add value_cnt member. (casewriter_write): Check that the case passed in is big enough. (casewriter_get_value_cnt): New function. (casewriter_create): Add value_cnt parameter. --- diff --git a/src/data/ChangeLog b/src/data/ChangeLog index 0dbf5777..4d4ff743 100644 --- a/src/data/ChangeLog +++ b/src/data/ChangeLog @@ -1,3 +1,19 @@ +2007-08-12 Ben Pfaff + + Make casewriters keep track of the number of `union value's in + each case. This is useful for two reasons: casewriter_write can + then check that the case being written is large enough, and later + recipients of the casewriter can determine the size of the case. + + * casewriter-translator.c (casewriter_create_translator): Add + value_cnt parameter. + + * casewriter.c (struct casewriter): Add value_cnt member. + (casewriter_write): Check that the case passed in is big enough. + (casewriter_get_value_cnt): New function. + (casewriter_create): Add value_cnt parameter. + + 2007-08-09 Ben Pfaff Fix bug reported by Jason Stover. diff --git a/src/data/casewriter-provider.h b/src/data/casewriter-provider.h index 29a6ee06..8298af46 100644 --- a/src/data/casewriter-provider.h +++ b/src/data/casewriter-provider.h @@ -56,6 +56,7 @@ struct casewriter_class struct casereader *(*convert_to_reader) (struct casewriter *, void *aux); }; -struct casewriter *casewriter_create (const struct casewriter_class *, void *); +struct casewriter *casewriter_create (size_t value_cnt, + const struct casewriter_class *, void *); #endif /* data/casewriter-provider.h */ diff --git a/src/data/casewriter-translator.c b/src/data/casewriter-translator.c index f2a0b68e..526bba34 100644 --- a/src/data/casewriter-translator.c +++ b/src/data/casewriter-translator.c @@ -39,6 +39,7 @@ static struct casewriter_class casewriter_translator_class; struct casewriter * casewriter_create_translator (struct casewriter *subwriter, + size_t translated_value_cnt, void (*translate) (const struct ccase *input, struct ccase *output, void *aux), @@ -51,7 +52,8 @@ casewriter_create_translator (struct casewriter *subwriter, ct->translate = translate; ct->destroy = destroy; ct->aux = aux; - writer = casewriter_create (&casewriter_translator_class, ct); + writer = casewriter_create (translated_value_cnt, + &casewriter_translator_class, ct); taint_propagate (casewriter_get_taint (ct->subwriter), casewriter_get_taint (writer)); return writer; diff --git a/src/data/casewriter.c b/src/data/casewriter.c index 1a8ae730..eac02b16 100644 --- a/src/data/casewriter.c +++ b/src/data/casewriter.c @@ -35,6 +35,7 @@ struct casewriter { struct taint *taint; + size_t value_cnt; casenumber case_cnt; const struct casewriter_class *class; void *aux; @@ -47,6 +48,7 @@ static struct casewriter *create_casewriter_window (size_t value_cnt, void casewriter_write (struct casewriter *writer, struct ccase *c) { + assert (case_get_value_cnt (c) >= writer->value_cnt); writer->class->write (writer, writer->aux, c); } @@ -67,6 +69,14 @@ casewriter_destroy (struct casewriter *writer) return ok; } +/* Returns the number of `union value's in each case written to + WRITER. */ +size_t +casewriter_get_value_cnt (const struct casewriter *writer) +{ + return writer->value_cnt; +} + /* Destroys WRITER and in its place returns a casereader that can be used to read back the data written to WRITER. WRITER must not be used again after calling this function, even as an @@ -133,12 +143,15 @@ casewriter_get_taint (const struct casewriter *writer) } /* Creates and returns a new casewriter with the given CLASS and - auxiliary data AUX. */ + auxiliary data AUX. The casewriter accepts cases with + VALUE_CNT `union value's. */ struct casewriter * -casewriter_create (const struct casewriter_class *class, void *aux) +casewriter_create (size_t value_cnt, + const struct casewriter_class *class, void *aux) { struct casewriter *writer = xmalloc (sizeof *writer); writer->taint = taint_create (); + writer->value_cnt = value_cnt; writer->case_cnt = 0; writer->class = class; writer->aux = aux; @@ -196,7 +209,8 @@ static struct casewriter * create_casewriter_window (size_t value_cnt, casenumber max_in_core_cases) { struct casewindow *window = casewindow_create (value_cnt, max_in_core_cases); - struct casewriter *writer = casewriter_create (&casewriter_window_class, + struct casewriter *writer = casewriter_create (value_cnt, + &casewriter_window_class, window); taint_propagate (casewindow_get_taint (window), casewriter_get_taint (writer)); diff --git a/src/data/casewriter.h b/src/data/casewriter.h index a526c56a..87bf6f6a 100644 --- a/src/data/casewriter.h +++ b/src/data/casewriter.h @@ -27,6 +27,8 @@ struct casewriter; void casewriter_write (struct casewriter *, struct ccase *); bool casewriter_destroy (struct casewriter *); +size_t casewriter_get_value_cnt (const struct casewriter *); + struct casereader *casewriter_make_reader (struct casewriter *); struct casewriter *casewriter_rename (struct casewriter *); @@ -40,7 +42,7 @@ struct casewriter *tmpfile_writer_create (size_t value_cnt); struct casewriter *autopaging_writer_create (size_t value_cnt); struct casewriter * -casewriter_create_translator (struct casewriter *, +casewriter_create_translator (struct casewriter *, size_t translated_value_cnt, void (*translate) (const struct ccase *input, struct ccase *output, void *aux), diff --git a/src/data/por-file-writer.c b/src/data/por-file-writer.c index cf447456..27f7c5c4 100644 --- a/src/data/por-file-writer.c +++ b/src/data/por-file-writer.c @@ -166,7 +166,8 @@ pfm_open_writer (struct file_handle *fh, struct dictionary *dict, buf_write (w, "F", 1); if (ferror (w->file)) goto error; - return casewriter_create (&por_file_casewriter_class, w); + return casewriter_create (dict_get_next_value_idx (dict), + &por_file_casewriter_class, w); error: close_writer (w); diff --git a/src/data/scratch-writer.c b/src/data/scratch-writer.c index a2ce305e..e085ca1c 100644 --- a/src/data/scratch-writer.c +++ b/src/data/scratch-writer.c @@ -56,6 +56,7 @@ scratch_writer_open (struct file_handle *fh, struct dictionary *scratch_dict; struct dict_compactor *compactor; struct casewriter *casewriter; + size_t dict_value_cnt; if (!fh_open (fh, FH_REF_SCRATCH, "scratch file", "we")) return NULL; @@ -74,6 +75,7 @@ scratch_writer_open (struct file_handle *fh, } else compactor = NULL; + dict_value_cnt = dict_get_next_value_idx (scratch_dict); /* Create new contents. */ sh = xmalloc (sizeof *sh); @@ -85,11 +87,11 @@ scratch_writer_open (struct file_handle *fh, writer->handle = sh; writer->fh = fh; writer->compactor = compactor; - writer->subwriter = autopaging_writer_create (dict_get_next_value_idx ( - scratch_dict)); + writer->subwriter = autopaging_writer_create (dict_value_cnt); fh_set_scratch_handle (fh, sh); - casewriter = casewriter_create (&scratch_writer_casewriter_class, writer); + casewriter = casewriter_create (dict_value_cnt, + &scratch_writer_casewriter_class, writer); taint_propagate (casewriter_get_taint (writer->subwriter), casewriter_get_taint (casewriter)); return casewriter; diff --git a/src/data/sys-file-writer.c b/src/data/sys-file-writer.c index 6b4344a7..d58fd835 100644 --- a/src/data/sys-file-writer.c +++ b/src/data/sys-file-writer.c @@ -238,7 +238,8 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d, if (write_error (w)) goto error; - return casewriter_create (&sys_file_casewriter_class, w); + return casewriter_create (dict_get_next_value_idx (d), + &sys_file_casewriter_class, w); error: close_writer (w); diff --git a/src/language/data-io/ChangeLog b/src/language/data-io/ChangeLog index c1b9aaf1..966904f6 100644 --- a/src/language/data-io/ChangeLog +++ b/src/language/data-io/ChangeLog @@ -1,3 +1,7 @@ +2007-08-12 Ben Pfaff + + * get.c (case_map_get_value_cnt): New function. + 2007-07-25 Ben Pfaff Fix bug #17100. diff --git a/src/language/data-io/get.c b/src/language/data-io/get.c index dbda3662..383513e6 100644 --- a/src/language/data-io/get.c +++ b/src/language/data-io/get.c @@ -54,6 +54,7 @@ static struct case_map *finish_case_map (struct dictionary *); static void map_case (const struct case_map *, const struct ccase *, struct ccase *); static void destroy_case_map (struct case_map *); +static size_t case_map_get_value_cnt (const struct case_map *); static bool parse_dict_trim (struct lexer *, struct dictionary *); @@ -358,6 +359,7 @@ parse_write_command (struct lexer *lexer, struct dataset *ds, map = finish_case_map (dict); if (map != NULL) writer = casewriter_create_translator (writer, + case_map_get_value_cnt (map), get_translate_case, get_destroy_case_map, map); @@ -1442,3 +1444,11 @@ destroy_case_map (struct case_map *map) free (map); } } + +/* Returns the number of `union value's in cases created by + MAP. */ +static size_t +case_map_get_value_cnt (const struct case_map *map) +{ + return map->value_cnt; +} diff --git a/src/math/sort.c b/src/math/sort.c index aa2afe80..95c40fb3 100644 --- a/src/math/sort.c +++ b/src/math/sort.c @@ -63,6 +63,7 @@ static void output_record (struct sort_writer *); struct casewriter * sort_create_writer (struct case_ordering *ordering) { + size_t value_cnt = case_ordering_get_value_cnt (ordering); struct sort_writer *sort; sort = xmalloc (sizeof *sort); @@ -75,7 +76,7 @@ sort_create_writer (struct case_ordering *ordering) case_ordering_destroy (ordering); - return casewriter_create (&sort_casewriter_class, sort); + return casewriter_create (value_cnt, &sort_casewriter_class, sort); } static void