From 2733e649b31b5491fb252970a06dc9abb3838e4c Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 11 Oct 2019 04:15:45 +0000 Subject: [PATCH] pivot-table: Add reference counts. This will be more useful in an upcoming commit. --- src/language/dictionary/sys-file-info.c | 2 +- src/language/stats/crosstabs.q | 2 +- src/output/pivot-output.c | 2 +- src/output/pivot-table.c | 28 +++++++++++++++++++++++-- src/output/pivot-table.h | 10 ++++++++- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/language/dictionary/sys-file-info.c b/src/language/dictionary/sys-file-info.c index d8a37cdd65..5d47725b57 100644 --- a/src/language/dictionary/sys-file-info.c +++ b/src/language/dictionary/sys-file-info.c @@ -706,7 +706,7 @@ display_attributes (const struct attrset *dict_attrset, var_get_attributes (vars[i]), flags); if (pivot_table_is_empty (table)) - pivot_table_destroy (table); + pivot_table_unref (table); else pivot_table_submit (table); } diff --git a/src/language/stats/crosstabs.q b/src/language/stats/crosstabs.q index b87acf4c72..6defd2447a 100644 --- a/src/language/stats/crosstabs.q +++ b/src/language/stats/crosstabs.q @@ -1097,7 +1097,7 @@ output_crosstabulation (struct crosstabs_proc *proc, struct crosstabulation *xt) if (!pivot_table_is_empty (risk)) pivot_table_submit (risk); else - pivot_table_destroy (risk); + pivot_table_unref (risk); } if (direct) diff --git a/src/output/pivot-output.c b/src/output/pivot-output.c index 69a6f7fec6..f9c22b7785 100644 --- a/src/output/pivot-output.c +++ b/src/output/pivot-output.c @@ -512,5 +512,5 @@ pivot_table_submit (struct pivot_table *pt) settings_set_decimal_char (old_decimal); - pivot_table_destroy (pt); + pivot_table_unref (pt); } diff --git a/src/output/pivot-table.c b/src/output/pivot-table.c index 72a158baaa..eaad89737b 100644 --- a/src/output/pivot-table.c +++ b/src/output/pivot-table.c @@ -638,6 +638,7 @@ struct pivot_table * pivot_table_create__ (struct pivot_value *title) { struct pivot_table *table = xzalloc (sizeof *table); + table->ref_cnt = 1; table->weight_format = (struct fmt_spec) { FMT_F, 40, 0 }; table->title = title; @@ -723,12 +724,27 @@ pivot_table_create_for_text (struct pivot_value *title, return table; } -/* Destroys TABLE and frees everything it points to. */ +/* Increases TABLE's reference count, indicating that it has an additional + owner. A pivot table that is shared among multiple owners must not be + modified. */ +struct pivot_table * +pivot_table_ref (const struct pivot_table *table_) +{ + struct pivot_table *table = CONST_CAST (struct pivot_table *, table_); + table->ref_cnt++; + return table; +} + +/* Decreases TABLE's reference count, indicating that it has one fewer owner. + If TABLE no longer has any owners, it is freed. */ void -pivot_table_destroy (struct pivot_table *table) +pivot_table_unref (struct pivot_table *table) { if (!table) return; + assert (table->ref_cnt > 0); + if (--table->ref_cnt) + return; free (table->current_layer); free (table->table_look); @@ -781,6 +797,14 @@ pivot_table_destroy (struct pivot_table *table) free (table); } +/* Returns true if TABLE has more than one owner. A pivot table that is shared + among multiple owners must not be modified. */ +bool +pivot_table_is_shared (const struct pivot_table *table) +{ + return table->ref_cnt > 1; +} + /* Sets the format used for PIVOT_RC_COUNT cells to the one used for variable WV, which should be the weight variable for the dictionary whose data or statistics are being put into TABLE. diff --git a/src/output/pivot-table.h b/src/output/pivot-table.h index aa064953fe..657ec75ede 100644 --- a/src/output/pivot-table.h +++ b/src/output/pivot-table.h @@ -372,6 +372,11 @@ bool pivot_result_class_change (const char *, const struct fmt_spec *); /* A pivot table. See the top of this file for more information. */ struct pivot_table { + /* Reference count. A pivot_table may be shared between multiple owners, + indicated by a reference count greater than 1. When this is the case, + the pivot_table must not be modified. */ + int ref_cnt; + /* Display settings. */ bool rotate_inner_column_labels; bool rotate_outer_row_labels; @@ -448,7 +453,10 @@ struct pivot_table *pivot_table_create (const char *title); struct pivot_table *pivot_table_create__ (struct pivot_value *title); struct pivot_table *pivot_table_create_for_text (struct pivot_value *title, struct pivot_value *content); -void pivot_table_destroy (struct pivot_table *); + +struct pivot_table *pivot_table_ref (const struct pivot_table *); +void pivot_table_unref (struct pivot_table *); +bool pivot_table_is_shared (const struct pivot_table *); /* Format of PIVOT_RC_COUNT cells. */ void pivot_table_set_weight_var (struct pivot_table *, -- 2.30.2