pivot-table: Add reference counts.
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 11 Oct 2019 04:15:45 +0000 (04:15 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 29 Dec 2019 05:28:10 +0000 (05:28 +0000)
This will be more useful in an upcoming commit.

src/language/dictionary/sys-file-info.c
src/language/stats/crosstabs.q
src/output/pivot-output.c
src/output/pivot-table.c
src/output/pivot-table.h

index d8a37cdd65b92d008279ac7e8ae0b84f56a9701f..5d47725b574a0d6245cd06db4ef1270fb7028184 100644 (file)
@@ -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);
 }
index b87acf4c72a31bda4717e9f56a1141f97ec0c9e9..6defd2447a9424a7ce5ec0f6f81cda95c5e564c0 100644 (file)
@@ -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)
index 69a6f7fec640f5caa4272e43ea94996fb77b3b19..f9c22b7785131fdbbf9d59b693fd33d83bb6323c 100644 (file)
@@ -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);
 }
index 72a158baaad78a777935077475e529bf01285bb2..eaad89737b382a3d78b8098ac097715287a42b83 100644 (file)
@@ -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.
index aa064953fedb25aa97a4e1016227b421854c064d..657ec75ede8282bdbce7af2f7647fe93d92d81d5 100644 (file)
@@ -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 *,