Make casewriters keep track of the number of `union value's in each
authorBen Pfaff <blp@gnu.org>
Mon, 13 Aug 2007 00:41:34 +0000 (00:41 +0000)
committerBen Pfaff <blp@gnu.org>
Mon, 13 Aug 2007 00:41:34 +0000 (00:41 +0000)
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.

src/data/ChangeLog
src/data/casewriter-provider.h
src/data/casewriter-translator.c
src/data/casewriter.c
src/data/casewriter.h
src/data/por-file-writer.c
src/data/scratch-writer.c
src/data/sys-file-writer.c
src/language/data-io/ChangeLog
src/language/data-io/get.c
src/math/sort.c

index 0dbf5777662674fabcb2885af28d8ac589edac21..4d4ff743521a8f957879fab4697a424f04d3d608 100644 (file)
@@ -1,3 +1,19 @@
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       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  <blp@gnu.org>
 
        Fix bug reported by Jason Stover.
index 29a6ee06c41bb8d2a49a6346cebcc9e7b97665df..8298af465da9d88640fe813f6a12309c6effd036 100644 (file)
@@ -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 */
index f2a0b68e6a5683d6c903ed40de0510ca4f88742c..526bba34900b8b0d239a52e279923cdb4a52076a 100644 (file)
@@ -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;
index 1a8ae730175eb68587fd1b11ef6cd4cc175e06e3..eac02b16865e5b9348a3575af03e819982070114 100644 (file)
@@ -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));
index a526c56aed463b11f4f24fe0de92b47ba1aca1b5..87bf6f6abd9f2c398399b903c4654b5c702140af 100644 (file)
@@ -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);
 \f
 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),
index cf4474569531ee723f2fbbb3ecb7a2b1e815b507..27f7c5c4f57ef15879a6cd2d8e1b5de273593db8 100644 (file)
@@ -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);
index a2ce305e727b392e944a9609d816eb9483dffe84..e085ca1c28e59b7984251037067019add18984e4 100644 (file)
@@ -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;
index 6b4344a79d779a1bed28c0ea58c42f9f8dd6854d..d58fd835beaa3a8ade0d750a6909d4aed80c1d3e 100644 (file)
@@ -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);
index c1b9aaf1a1a37e7bc4b9b4a2197f7b07da60e5ff..966904f67d6e047d5a907f098844813606dab6c3 100644 (file)
@@ -1,3 +1,7 @@
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * get.c (case_map_get_value_cnt): New function.
+
 2007-07-25  Ben Pfaff  <blp@gnu.org>
 
        Fix bug #17100.
index dbda3662372b9a8a3f3d016a119a7fbab84c0988..383513e632f0aadb5640d17e4cb81411fd312711 100644 (file)
@@ -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 *);
 \f
@@ -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;
+}
index aa2afe80951b7a31608f6e4d1bf4d03c8807de0a..95c40fb39cdc029b2f1ce592194affed2b9002d0 100644 (file)
@@ -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