[Top][All Lists]
[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);
}
- [Pspp-cvs] pspp/src/data datasheet.c [simpler-proc],
Ben Pfaff <=