pspp-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pspp-cvs] pspp/src/data datasheet.c [simpler-proc]


From: Ben Pfaff
Subject: [Pspp-cvs] pspp/src/data datasheet.c [simpler-proc]
Date: Sat, 14 Apr 2007 23:01:54 +0000

CVSROOT:        /cvsroot/pspp
Module name:    pspp
Branch:         simpler-proc
Changes by:     Ben Pfaff <blp> 07/04/14 23:01:54

Modified files:
        src/data       : datasheet.c 

Log message:
        Fix various bugs.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/datasheet.c?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.4&r2=1.1.2.5

Patches:
Index: datasheet.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/datasheet.c,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -b -r1.1.2.4 -r1.1.2.5
--- datasheet.c 14 Apr 2007 05:04:23 -0000      1.1.2.4
+++ datasheet.c 14 Apr 2007 23:01:54 -0000      1.1.2.5
@@ -47,8 +47,7 @@
 static void axis_make_available (struct axis *,
                                 unsigned long int start,
                                 unsigned long int width);
-static void axis_extend (struct axis *, unsigned long int width,
-                         unsigned long int *start);
+static unsigned long int axis_extend (struct axis *, unsigned long int width);
 
 static unsigned long int axis_map (const struct axis *, unsigned long log_pos);
 
@@ -69,6 +68,9 @@
 static struct source *clone_source (const struct source *);
 static void source_destroy (struct source *);
 
+static casenumber source_get_backing_row_cnt (const struct source *);
+static size_t source_get_column_cnt (const struct source *);
+
 static bool source_read (const struct source *, 
                          casenumber row, size_t column,
                          union value *, size_t value_cnt);
@@ -120,6 +122,13 @@
     struct source *source;
   };
 
+
+static struct source_info *
+source_info_from_range_map (struct range_map_node *node) 
+{
+  return range_map_data (node, struct source_info, column_range);
+}
+
 struct datasheet *
 datasheet_create (struct casereader *reader) 
 {
@@ -133,21 +142,24 @@
 
   if (reader != NULL) 
     {
-      size_t column_cnt = casereader_get_value_cnt (reader);
-      casenumber row_cnt = casereader_count_cases (reader);
-      unsigned long int column_start, row_start;
+      size_t column_cnt;
+      casenumber row_cnt;
+      unsigned long int column_start;
+      unsigned long int row_start;
       struct source_info *si;
 
-      /* Add source_info for READER. */
       si = xmalloc (sizeof *si);
       si->source = source_create_casereader (reader);
+      column_cnt = source_get_column_cnt (si->source);
+      row_cnt = source_get_backing_row_cnt (si->source);
       source_increase_use (si->source, column_cnt);
-      range_map_insert (&ds->sources, 0, column_cnt, &si->column_range);
 
-      /* Add column and row mappings for READER. */
-      axis_extend (ds->columns, column_cnt, &column_start);
+      column_start = axis_extend (ds->columns, column_cnt);
       axis_insert (ds->columns, 0, column_start, column_cnt);
-      axis_extend (ds->rows, row_cnt, &row_start);
+      range_map_insert (&ds->sources, column_start, column_cnt,
+                        &si->column_range);
+
+      row_start = axis_extend (ds->rows, row_cnt);
       axis_insert (ds->rows, 0, row_start, row_cnt);
   
       return ds;
@@ -175,8 +187,7 @@
   while (!range_map_is_empty (&ds->sources)) 
     {
       struct range_map_node *r = range_map_first (&ds->sources);
-      struct source_info *si
-        = range_map_data (r, struct source_info, column_range);
+      struct source_info *si = source_info_from_range_map (r);
       free_source_info (ds, si);
     }
   free (ds);
@@ -194,11 +205,12 @@
   return axis_get_size (ds->columns);
 }
 
-void
+bool
 datasheet_insert_columns (struct datasheet *ds,
                           const union value init_values[], size_t cnt,
                           size_t before) 
 {
+  size_t added = 0;
   while (cnt > 0) 
     {
       unsigned long first_phy;
@@ -209,7 +221,7 @@
           struct source_info *si;
 
           phy_cnt = MAX (cnt, ds->column_min_alloc);
-          axis_extend (ds->columns, phy_cnt, &first_phy);
+          first_phy = axis_extend (ds->columns, phy_cnt);
           ds->column_min_alloc = MIN (65536, ds->column_min_alloc * 2);
 
           si = xmalloc (sizeof *si);
@@ -231,13 +243,18 @@
           size_t source_cnt;
 
           r = range_map_lookup (&ds->sources, first_phy);
-          s = range_map_data (r, struct source_info, column_range);
+          s = source_info_from_range_map (r);
           source_cnt = MIN (phy_cnt, range_map_node_get_end (r) - first_phy);
           axis_insert (ds->columns, before, first_phy, source_cnt);
 
-          source_write_columns (s->source,
+          if (!source_write_columns (s->source,
                                 first_phy - range_map_node_get_start (r),
-                                init_values, source_cnt);
+                                     init_values, source_cnt)) 
+            {
+              datasheet_delete_columns (ds, before - added,
+                                        source_cnt + added);
+              return false;
+            }
           source_increase_use (s->source, source_cnt);
 
           phy_cnt -= source_cnt;
@@ -245,8 +262,10 @@
           init_values += source_cnt;
           cnt -= source_cnt;
           before += source_cnt;
+          added += source_cnt;
         }
     }
+  return true;
 }
 
 void
@@ -259,8 +278,7 @@
     {
       size_t pcol = axis_map (ds->columns, lcol);
       struct range_map_node *r = range_map_lookup (&ds->sources, pcol);
-      struct source_info *si = range_map_data (r, struct source_info,
-                                               column_range);
+      struct source_info *si = source_info_from_range_map (r);
 
       source_decrease_use (si->source, 1);
       if (source_has_backing (si->source))
@@ -303,21 +321,21 @@
   assert (start_column + column_cnt <= datasheet_get_column_cnt (ds));
 
   prow = axis_map (ds->rows, lrow);
-  for (lcol = start_column; lcol < start_column + column_cnt; lcol++)
+  for (lcol = start_column; lcol < start_column + column_cnt; lcol++, data++)
     {
       size_t pcol;
       struct range_map_node *r;
       struct source_info *s;
+      size_t pcol_ofs;
 
       pcol = axis_map (ds->columns, lcol);
       r = range_map_lookup (&ds->sources, pcol);
-      s = range_map_data (r, struct source_info, column_range);
-      if (op == OP_READ)
-        source_read (s->source, prow, pcol - range_map_node_get_start (r),
-                     data++, 1);
-      else
-        source_write (s->source, prow, pcol - range_map_node_get_start (r),
-                     data++, 1);
+      s = source_info_from_range_map (r);
+      pcol_ofs = pcol - range_map_node_get_start (r);
+      if (!(op == OP_READ
+            ? source_read (s->source, prow, pcol_ofs, data, 1)
+            : source_write (s->source, prow, pcol_ofs, data, 1)))
+        return false;
     }
   return true;
 }
@@ -378,7 +396,7 @@
       if (!axis_allocate (ds->rows, cnt, &first_phy, &phy_cnt)) 
         {
           phy_cnt = cnt;
-          axis_extend (ds->rows, cnt, &first_phy); 
+          first_phy = axis_extend (ds->rows, cnt); 
         }
 
       axis_insert (ds->rows, before, first_phy, phy_cnt);
@@ -599,12 +617,12 @@
   range_set_insert (axis->available, start, width);
 }
 
-static void
-axis_extend (struct axis *axis, unsigned long int width,
-             unsigned long int *start) 
+static unsigned long int
+axis_extend (struct axis *axis, unsigned long int width) 
 {
-  *start = axis->phy_size;
+  unsigned long int start = axis->phy_size;
   axis->phy_size += width;
+  return start;
 }
 
 static unsigned long int
@@ -790,19 +808,13 @@
     }
 }
 
-/* Type of a source. */
-enum backing_type 
-  {
-    SOURCE_CASES,
-    SOURCE_CASEREADER
-  };
-
 /* A source. */
 struct source
   {
     size_t columns_used;
     struct sparse_cases *data;
     struct casereader *backing;
+    casenumber backing_rows;
   };
 
 static struct source *
@@ -812,6 +824,7 @@
   source->columns_used = 0;
   source->data = sparse_cases_create (column_cnt);
   source->backing = NULL;
+  source->backing_rows = 0;
   return source;
 }
 
@@ -821,6 +834,7 @@
   struct source *source
     = source_create_empty (casereader_get_value_cnt (reader));
   source->backing = reader;
+  source->backing_rows = casereader_count_cases (reader);
   return source;
 }
 
@@ -832,6 +846,7 @@
   new->columns_used = old->columns_used;
   new->data = sparse_cases_clone (old->data);
   new->backing = old->backing != NULL ? casereader_clone (old->backing) : NULL;
+  new->backing_rows = old->backing_rows;
   if (new->data == NULL)
     {
       source_destroy (new);
@@ -871,6 +886,19 @@
     }
 }
 
+static casenumber
+source_get_backing_row_cnt (const struct source *source) 
+{
+  assert (source_has_backing (source));
+  return source->backing_rows;
+}
+
+static size_t
+source_get_column_cnt (const struct source *source) 
+{
+  return sparse_cases_get_value_cnt (source->data);
+}
+
 static bool
 source_read (const struct source *source, 
              casenumber row, size_t column,
@@ -909,7 +937,21 @@
   else
     {
       struct ccase c;
+      if (row < source->backing_rows)
       ok = casereader_peek (source->backing, row, &c);
+      else
+        {
+          /* It's not one of the backed rows.  Ideally, this
+             should never happen: we'd always be writing the full
+             contents of new, unbacked rows in a single call to
+             this function, so that the first case above would
+             trigger.  But that's a little difficult at higher
+             levels, so that we in fact usually write the full
+             contents of new, unbacked rows in multiple calls to
+             this function.  Make this work. */
+          case_create (&c, column_cnt);
+          ok = true;
+        }
       if (ok) 
         {
           case_copy_in (&c, column, values, value_cnt);
@@ -1039,8 +1081,7 @@
   for (r = range_map_first (&ods->sources); r != NULL;
        r = range_map_next (&ods->sources, r)) 
     {
-      const struct source_info *osi = range_map_data (r, struct source_info,
-                                                      column_range);
+      const struct source_info *osi = source_info_from_range_map (r);
       struct source_info *si = xmalloc (sizeof *si);
       si->source = clone_source (osi->source);
       range_map_insert (&ds->sources, range_map_node_get_start (r),
@@ -1132,7 +1173,8 @@
           for (i = 0; i < cnt; i++) 
             new[i].f = params->next_value++;
 
-          datasheet_insert_columns (ds, new, cnt, pos);
+          if (!datasheet_insert_columns (ds, new, cnt, pos))
+            mc_error (mc, "datasheet_insert_columns failed");
         
           for (i = 0; i < row_cnt; i++) 
             {
@@ -1211,7 +1253,7 @@
               data[i + pos][j] = case_num_idx (&c[i], j);
 
           if (!datasheet_insert_rows (ds, pos, c, cnt))
-            NOT_REACHED ();
+            mc_error (mc, "datasheet_insert_rows failed");
 
           check_datasheet (mc, ds, data, row_cnt + cnt, column_cnt);
         }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]