X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fdatasheet.c;h=83a2a677e3b55a671a10f71d5347fb2b4b312b07;hb=07006e3b80d88f60f3a2af10a805d8bca847a0ef;hp=a11a1e596c4446106e7f9adab05a385dc307479b;hpb=1a35c8af6643fc1c7fa6e4b775282ff1bef8ed98;p=pspp diff --git a/src/data/datasheet.c b/src/data/datasheet.c index a11a1e596c..83a2a677e3 100644 --- a/src/data/datasheet.c +++ b/src/data/datasheet.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -389,21 +389,22 @@ datasheet_move_columns (struct datasheet *ds, axis_move (ds->columns, old_start, new_start, cnt); } -/* Retrieves the contents of the given ROW in datasheet DS into - newly created case C. Returns true if successful, false on - I/O error. */ -bool -datasheet_get_row (const struct datasheet *ds, casenumber row, struct ccase *c) +/* Retrieves and returns the contents of the given ROW in + datasheet DS. The caller owns the returned case and must + unref it when it is no longer needed. Returns a null pointer + on I/O error. */ +struct ccase * +datasheet_get_row (const struct datasheet *ds, casenumber row) { size_t column_cnt = datasheet_get_column_cnt (ds); - case_create (c, column_cnt); + struct ccase *c = case_create (column_cnt); if (rw_case ((struct datasheet *) ds, OP_READ, row, 0, column_cnt, case_data_all_rw (c))) - return true; + return c; else { - case_destroy (c); - return false; + case_unref (c); + return NULL; } } @@ -417,7 +418,7 @@ datasheet_put_row (struct datasheet *ds, casenumber row, struct ccase *c) size_t column_cnt = datasheet_get_column_cnt (ds); bool ok = rw_case (ds, OP_WRITE, row, 0, column_cnt, (union value *) case_data_all (c)); - case_destroy (c); + case_unref (c); return ok; } @@ -445,13 +446,15 @@ datasheet_put_value (struct datasheet *ds, casenumber row, size_t column, (union value *) value); } -/* Inserts the CNT cases at C, which are destroyed, into - datasheet DS just before row BEFORE. Returns true if - successful, false on I/O error. On failure, datasheet DS is - not modified. */ +/* Inserts the CNT cases at C into datasheet DS just before row + BEFORE. Returns true if successful, false on I/O error. On + failure, datasheet DS is not modified. + + Regardless of success, this function unrefs all of the cases + in C. */ bool datasheet_insert_rows (struct datasheet *ds, - casenumber before, struct ccase c[], + casenumber before, struct ccase *c[], casenumber cnt) { casenumber added = 0; @@ -476,10 +479,10 @@ datasheet_insert_rows (struct datasheet *ds, /* Initialize the new rows. */ for (i = 0; i < phy_cnt; i++) - if (!datasheet_put_row (ds, before + i, &c[i])) + if (!datasheet_put_row (ds, before + i, c[i])) { while (++i < cnt) - case_destroy (&c[i]); + case_unref (c[i]); datasheet_delete_rows (ds, before - added, phy_cnt + added); return false; } @@ -540,20 +543,20 @@ datasheet_make_reader (struct datasheet *ds) } /* "read" function for the datasheet random casereader. */ -static bool +static struct ccase * datasheet_reader_read (struct casereader *reader UNUSED, void *ds_, - casenumber case_idx, struct ccase *c) + casenumber case_idx) { struct datasheet *ds = ds_; - if (case_idx >= datasheet_get_row_cnt (ds)) - return false; - else if (datasheet_get_row (ds, case_idx, c)) - return true; - else + if (case_idx < datasheet_get_row_cnt (ds)) { - taint_set_taint (ds->taint); - return false; + struct ccase *c = datasheet_get_row (ds, case_idx); + if (c == NULL) + taint_set_taint (ds->taint); + return c; } + else + return NULL; } /* "destroy" function for the datasheet random casereader. */ @@ -693,7 +696,7 @@ axis_clone (const struct axis *old) for (node = tower_first (&old->log_to_phy); node != NULL; node = tower_next (&old->log_to_phy, node)) { - unsigned long int size = tower_node_get_height (node); + unsigned long int size = tower_node_get_size (node); struct axis_group *group = tower_data (node, struct axis_group, logical); tower_insert (&new->log_to_phy, size, make_axis_group (group->phy_start), NULL); @@ -717,7 +720,7 @@ axis_hash (const struct axis *axis, struct md4_ctx *ctx) { struct axis_group *group = tower_data (tn, struct axis_group, logical); unsigned long int phy_start = group->phy_start; - unsigned long int size = tower_node_get_height (tn); + unsigned long int size = tower_node_get_size (tn); md4_process_bytes (&phy_start, sizeof phy_start, ctx); md4_process_bytes (&size, sizeof size, ctx); @@ -921,7 +924,7 @@ split_axis (struct axis *axis, unsigned long int where) if (where > group_start) { unsigned long int size_1 = where - group_start; - unsigned long int size_2 = tower_node_get_height (group_node) - size_1; + unsigned long int size_2 = tower_node_get_size (group_node) - size_1; struct tower_node *next = tower_next (&axis->log_to_phy, group_node); struct tower_node *new = make_axis_group (group->phy_start + size_1); tower_resize (&axis->log_to_phy, group_node, size_1); @@ -961,11 +964,11 @@ merge_axis_nodes (struct axis *axis, struct tower_node *node, if (next != NULL) { struct axis_group *next_group = axis_group_from_tower_node (next); - unsigned long this_height = tower_node_get_height (node); + unsigned long this_height = tower_node_get_size (node); if (group->phy_start + this_height == next_group->phy_start) { - unsigned long next_height = tower_node_get_height (next); + unsigned long next_height = tower_node_get_size (next); tower_resize (t, node, this_height + next_height); if (other_node != NULL && *other_node == next) *other_node = tower_next (t, *other_node); @@ -979,11 +982,11 @@ merge_axis_nodes (struct axis *axis, struct tower_node *node, if (prev != NULL) { struct axis_group *prev_group = axis_group_from_tower_node (prev); - unsigned long prev_height = tower_node_get_height (prev); + unsigned long prev_height = tower_node_get_size (prev); if (prev_group->phy_start + prev_height == group->phy_start) { - unsigned long this_height = tower_node_get_height (node); + unsigned long this_height = tower_node_get_size (node); group->phy_start = prev_group->phy_start; tower_resize (t, node, this_height + prev_height); if (other_node != NULL && *other_node == prev) @@ -1007,7 +1010,7 @@ check_axis_merged (const struct axis *axis UNUSED) if (prev != NULL) { struct axis_group *prev_group = axis_group_from_tower_node (prev); - unsigned long prev_height = tower_node_get_height (prev); + unsigned long prev_height = tower_node_get_size (prev); struct axis_group *node_group = axis_group_from_tower_node (node); assert (prev_group->phy_start + prev_height != node_group->phy_start); } @@ -1136,15 +1139,12 @@ source_read (const struct source *source, return sparse_cases_read (source->data, row, column, values, value_cnt); else { - struct ccase c; - bool ok; - - assert (source->backing != NULL); - ok = casereader_peek (source->backing, row, &c); + struct ccase *c = casereader_peek (source->backing, row); + bool ok = c != NULL; if (ok) { - case_copy_out (&c, column, values, value_cnt); - case_destroy (&c); + case_copy_out (c, column, values, value_cnt); + case_unref (c); } return ok; } @@ -1169,9 +1169,10 @@ source_write (struct source *source, ok = sparse_cases_write (source->data, row, column, values, value_cnt); else { - struct ccase c; + struct ccase *c; + if (row < source->backing_rows) - ok = casereader_peek (source->backing, row, &c); + c = case_unshare (casereader_peek (source->backing, row)); else { /* It's not one of the backed rows. Ideally, this @@ -1182,15 +1183,16 @@ source_write (struct source *source, 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; + c = case_create (column_cnt); } + ok = c != NULL; + if (ok) { - case_copy_in (&c, column, values, value_cnt); + case_copy_in (c, column, values, value_cnt); ok = sparse_cases_write (source->data, row, 0, - case_data_all (&c), column_cnt); - case_destroy (&c); + case_data_all (c), column_cnt); + case_unref (c); } } return ok;