X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fvfm.c;h=06cf67ec1ebc8ca70221875b428b43e16e09e30e;hb=4f31116689eeda21658601c6ecf75a915b80103b;hp=08e3ca30f1f5818a88b8ea1dddadce283260abfa;hpb=8cf495e615e4feca5777f3592de98321d4fcdc0b;p=pspp diff --git a/src/vfm.c b/src/vfm.c index 08e3ca30f1..06cf67ec1e 100644 --- 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 . This program is free software; you can redistribute it and/or @@ -32,9 +32,10 @@ #include "casefile.h" #include "command.h" #include "dictionary.h" -#include "do-ifP.h" +#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,11 +91,12 @@ 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); static int execute_transformations (struct ccase *c, - struct trns_header **trns, + struct transformation *trns, int first_idx, int last_idx, int case_num); static int filter_case (const struct ccase *c, int case_num); @@ -104,6 +106,15 @@ static void close_active_file (void); /* 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) @@ -233,7 +253,7 @@ open_active_file (void) } /* Close any unclosed DO IF or LOOP constructs. */ - discard_ctl_stack (); + ctl_stack_clear (); } /* Transforms trns_case and writes it to the replacement active @@ -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 @@ -299,7 +319,7 @@ write_case (struct write_case_data *wc_data) transformations, nonzero otherwise. */ static int execute_transformations (struct ccase *c, - struct trns_header **trns, + struct transformation *trns, int first_idx, int last_idx, int case_num) { @@ -307,7 +327,8 @@ execute_transformations (struct ccase *c, for (idx = first_idx; idx != last_idx; ) { - int retval = trns[idx]->proc (trns[idx], c, case_num); + struct transformation *t = &trns[idx]; + int retval = t->proc (t->private, c, case_num); switch (retval) { case -1: @@ -406,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); @@ -603,15 +627,24 @@ lagged_case (int n_before) /* Appends TRNS to t_trns[], the list of all transformations to be performed on data as it is read from the active file. */ void -add_transformation (struct trns_header * trns) +add_transformation (trns_proc_func *proc, trns_free_func *free, void *private) { + struct transformation *trns; if (n_trns >= m_trns) - { - m_trns += 16; - t_trns = xnrealloc (t_trns, m_trns, sizeof *t_trns); - } - t_trns[n_trns] = trns; - trns->index = n_trns++; + t_trns = x2nrealloc (t_trns, &m_trns, sizeof *t_trns); + trns = &t_trns[n_trns++]; + trns->proc = proc; + trns->free = free; + trns->private = private; +} + +/* Returns the index number that the next transformation added by + add_transformation() will receive. A trns_proc_func that + returns this index causes control flow to jump to it. */ +size_t +next_transformation (void) +{ + return n_trns; } /* Cancels all active transformations, including any transformations @@ -619,12 +652,12 @@ add_transformation (struct trns_header * trns) void cancel_transformations (void) { - int i; + size_t i; for (i = 0; i < n_trns; i++) { - if (t_trns[i]->free) - t_trns[i]->free (t_trns[i]); - free (t_trns[i]); + struct transformation *t = &t_trns[i]; + if (t->free != NULL) + t->free (t->private); } n_trns = f_trns = 0; free (t_trns); @@ -916,7 +949,7 @@ void discard_variables (void) { dict_clear (default_dict); - default_handle = NULL; + fh_set_default_handle (NULL); n_lag = 0; @@ -928,7 +961,7 @@ discard_variables (void) cancel_transformations (); - ctl_stack = NULL; + ctl_stack_clear (); expr_free (process_if_expr); process_if_expr = NULL;