Add some news.
[pspp] / src / vfm.c
index 7f2cb693301f06fc68894bf47b983a6d7efdcacb..06cf67ec1ebc8ca70221875b428b43e16e09e30e 100644 (file)
--- a/src/vfm.c
+++ b/src/vfm.c
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <blp@gnu.org>.
 
    This program is free software; you can redistribute it and/or
@@ -35,6 +35,7 @@
 #include "ctl-stack.h"
 #include "error.h"
 #include "expressions/public.h"
+#include "file-handle-def.h"
 #include "misc.h"
 #include "settings.h"
 #include "som.h"
@@ -75,12 +76,12 @@ struct case_source *vfm_source;
 /* The replacement active file, to which cases are written. */
 struct case_sink *vfm_sink;
 
-/* Nonzero if the case needs to have values deleted before being
-   stored, zero otherwise. */
-static int compaction_necessary;
+/* The compactor used to compact a compact, if necessary;
+   otherwise a null pointer. */
+static struct dict_compactor *compactor;
 
 /* Time at which vfm was last invoked. */
-time_t last_vfm_invocation;
+static time_t last_vfm_invocation;
 
 /* Lag queue. */
 int n_lag;                     /* Number of cases to lag. */
@@ -90,6 +91,7 @@ static struct ccase *lag_queue; /* Array of n_lag ccase * elements. */
 
 static void internal_procedure (int (*proc_func) (struct ccase *, void *),
                                 void *aux);
+static void update_last_vfm_invocation (void);
 static void create_trns_case (struct ccase *, struct dictionary *);
 static void open_active_file (void);
 static int write_case (struct write_case_data *wc_data);
@@ -104,6 +106,15 @@ static void close_active_file (void);
 \f
 /* Public functions. */
 
+/* Returns the last time the data was read. */
+time_t
+vfm_last_invocation (void) 
+{
+  if (last_vfm_invocation == 0)
+    update_last_vfm_invocation ();
+  return last_vfm_invocation;
+}
+
 /* Reads the data from the input program and writes it to a new
    active file.  For each case we read from the input program, we
    do the following
@@ -136,6 +147,7 @@ procedure (int (*proc_func) (struct ccase *, void *), void *aux)
       && n_trns == 0)
     {
       /* Nothing to do. */
+      update_last_vfm_invocation ();
       return;
     }
 
@@ -162,7 +174,7 @@ internal_procedure (int (*proc_func) (struct ccase *, void *), void *aux)
   case_create (&wc_data.sink_case, dict_get_next_value_idx (default_dict));
   wc_data.cases_written = 0;
 
-  last_vfm_invocation = time (NULL);
+  update_last_vfm_invocation ();
 
   if (vfm_source != NULL) 
     vfm_source->class->read (vfm_source,
@@ -175,6 +187,13 @@ internal_procedure (int (*proc_func) (struct ccase *, void *), void *aux)
   assert (--recursive_call == 0);
 }
 
+/* Updates last_vfm_invocation. */
+static void
+update_last_vfm_invocation (void) 
+{
+  last_vfm_invocation = time (NULL);
+}
+
 /* Creates and returns a case, initializing it from the vectors
    that say which `value's need to be initialized just once, and
    which ones need to be re-initialized before every case. */
@@ -211,8 +230,9 @@ open_active_file (void)
     }
 
   /* Figure out compaction. */
-  compaction_necessary = (dict_get_next_value_idx (temp_dict)
-                          != dict_get_compacted_value_cnt (temp_dict));
+  compactor = (dict_needs_compaction (temp_dict)
+               ? dict_make_compactor (temp_dict)
+               : NULL);
 
   /* Prepare sink. */
   if (vfm_sink == NULL)
@@ -261,10 +281,10 @@ write_case (struct write_case_data *wc_data)
   /* Write case to replacement active file. */
   if (vfm_sink->class->write != NULL) 
     {
-      if (compaction_necessary
+      if (compactor != NULL
         {
-          dict_compact_case (temp_dict, &wc_data->sink_case,
-                             &wc_data->trns_case);
+          dict_compactor_compact (compactor, &wc_data->sink_case,
+                                  &wc_data->trns_case);
           vfm_sink->class->write (vfm_sink, &wc_data->sink_case);
         }
       else
@@ -407,8 +427,11 @@ close_active_file (void)
     }
 
   /* Finish compaction. */
-  if (compaction_necessary)
-    dict_compact_values (default_dict);
+  if (compactor != NULL) 
+    {
+      dict_compactor_destroy (compactor);
+      dict_compact_values (default_dict); 
+    }
     
   /* Free data source. */
   free_case_source (vfm_source);
@@ -926,7 +949,7 @@ void
 discard_variables (void)
 {
   dict_clear (default_dict);
-  default_handle = NULL;
+  fh_set_default_handle (NULL);
 
   n_lag = 0;