X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fprocedure.c;h=a2ca8b23ee85f8b51285a6c8f61c422911f06638;hb=e83ae31468417739c11aa52c993e80347bbb82e4;hp=dde7fcee7541633eda6a2f7e051b5ba2c5179a4f;hpb=505d1c592469ea99da7723c2770f13f5dc965046;p=pspp diff --git a/src/data/procedure.c b/src/data/procedure.c index dde7fcee75..a2ca8b23ee 100644 --- a/src/data/procedure.c +++ b/src/data/procedure.c @@ -34,20 +34,10 @@ #include #include #include -#include #include #include #include -/* - Virtual File Manager (vfm): - - vfm is used to process data files. It uses the model that - data is read from one stream (the data source), processed, - then written to another (the data sink). The data source is - then deleted and the data sink becomes the data source for the - next procedure. */ - /* Procedure execution data. */ struct write_case_data { @@ -57,21 +47,21 @@ struct write_case_data struct ccase trns_case; /* Case used for transformations. */ struct ccase sink_case; /* Case written to sink, if - compaction is necessary. */ + compacting is necessary. */ size_t cases_written; /* Cases output so far. */ }; -/* Cases are read from vfm_source, +/* Cases are read from proc_source, pass through permanent_trns_chain (which transforms them into the format described by permanent_dict), - are written to vfm_sink, + are written to proc_sink, pass through temporary_trns_chain (which transforms them into the format described by default_dict), and are finally passed to the procedure. */ -static struct case_source *vfm_source; +static struct case_source *proc_source; static struct trns_chain *permanent_trns_chain; static struct dictionary *permanent_dict; -static struct case_sink *vfm_sink; +static struct case_sink *proc_sink; static struct trns_chain *temporary_trns_chain; struct dictionary *default_dict; @@ -83,8 +73,8 @@ static struct trns_chain *cur_trns_chain; otherwise a null pointer. */ static struct dict_compactor *compactor; -/* Time at which vfm was last invoked. */ -static time_t last_vfm_invocation; +/* Time at which proc was last invoked. */ +static time_t last_proc_invocation; /* Lag queue. */ int n_lag; /* Number of cases to lag. */ @@ -94,13 +84,12 @@ static struct ccase *lag_queue; /* Array of n_lag ccase * elements. */ static void add_case_limit_trns (void); static void add_filter_trns (void); -static void add_process_if_trns (void); static bool internal_procedure (bool (*case_func) (const struct ccase *, void *), bool (*end_func) (void *), void *aux); -static void update_last_vfm_invocation (void); +static void update_last_proc_invocation (void); static void create_trns_case (struct ccase *, struct dictionary *); static void open_active_file (void); static bool write_case (struct write_case_data *wc_data); @@ -114,9 +103,9 @@ static bool close_active_file (void); time_t time_of_last_procedure (void) { - if (last_vfm_invocation == 0) - update_last_vfm_invocation (); - return last_vfm_invocation; + if (last_proc_invocation == 0) + update_last_proc_invocation (); + return last_proc_invocation; } /* Regular procedure. */ @@ -206,22 +195,20 @@ internal_procedure (bool (*case_func) (const struct ccase *, void *), struct write_case_data wc_data; bool ok = true; - assert (vfm_source != NULL); + assert (proc_source != NULL); - update_last_vfm_invocation (); + update_last_proc_invocation (); /* Optimize the trivial case where we're not going to do anything with the data, by not reading the data at all. */ if (case_func == NULL && end_func == NULL - && case_source_is_class (vfm_source, &storage_source_class) - && vfm_sink == NULL + && case_source_is_class (proc_source, &storage_source_class) + && proc_sink == NULL && (temporary_trns_chain == NULL || trns_chain_is_empty (temporary_trns_chain)) && trns_chain_is_empty (permanent_trns_chain)) { n_lag = 0; - expr_free (process_if_expr); - process_if_expr = NULL; dict_set_case_limit (default_dict, 0); dict_clear_vectors (default_dict); return true; @@ -235,9 +222,9 @@ internal_procedure (bool (*case_func) (const struct ccase *, void *), case_create (&wc_data.sink_case, dict_get_next_value_idx (default_dict)); wc_data.cases_written = 0; - ok = vfm_source->class->read (vfm_source, - &wc_data.trns_case, - write_case, &wc_data) && ok; + ok = proc_source->class->read (proc_source, + &wc_data.trns_case, + write_case, &wc_data) && ok; if (end_func != NULL) ok = end_func (aux) && ok; @@ -249,11 +236,11 @@ internal_procedure (bool (*case_func) (const struct ccase *, void *), return ok; } -/* Updates last_vfm_invocation. */ +/* Updates last_proc_invocation. */ static void -update_last_vfm_invocation (void) +update_last_proc_invocation (void) { - last_vfm_invocation = time (NULL); + last_proc_invocation = time (NULL); } /* Creates and returns a case, initializing it from the vectors @@ -285,7 +272,6 @@ open_active_file (void) { add_case_limit_trns (); add_filter_trns (); - add_process_if_trns (); /* Finalize transformations. */ trns_chain_finalize (cur_trns_chain); @@ -295,16 +281,16 @@ open_active_file (void) if (permanent_dict == NULL) permanent_dict = default_dict; - /* Figure out compaction. */ - compactor = (dict_needs_compaction (permanent_dict) + /* Figure out whether to compact. */ + compactor = (dict_compacting_would_shrink (permanent_dict) ? dict_make_compactor (permanent_dict) : NULL); /* Prepare sink. */ - if (vfm_sink == NULL) - vfm_sink = create_case_sink (&storage_sink_class, permanent_dict, NULL); - if (vfm_sink->class->open != NULL) - vfm_sink->class->open (vfm_sink); + if (proc_sink == NULL) + proc_sink = create_case_sink (&storage_sink_class, permanent_dict, NULL); + if (proc_sink->class->open != NULL) + proc_sink->class->open (proc_sink); /* Allocate memory for lag queue. */ if (n_lag > 0) @@ -342,16 +328,16 @@ write_case (struct write_case_data *wc_data) /* Write case to replacement active file. */ wc_data->cases_written++; - if (vfm_sink->class->write != NULL) + if (proc_sink->class->write != NULL) { if (compactor != NULL) { dict_compactor_compact (compactor, &wc_data->sink_case, &wc_data->trns_case); - vfm_sink->class->write (vfm_sink, &wc_data->sink_case); + proc_sink->class->write (proc_sink, &wc_data->sink_case); } else - vfm_sink->class->write (vfm_sink, &wc_data->trns_case); + proc_sink->class->write (proc_sink, &wc_data->trns_case); } /* Execute temporary transformations. */ @@ -425,7 +411,7 @@ close_active_file (void) /* Dictionary from before TEMPORARY becomes permanent. */ proc_cancel_temporary_transformations (); - /* Finish compaction. */ + /* Finish compacting. */ if (compactor != NULL) { dict_compactor_destroy (compactor); @@ -434,17 +420,15 @@ close_active_file (void) } /* Free data source. */ - free_case_source (vfm_source); - vfm_source = NULL; + free_case_source (proc_source); + proc_source = NULL; /* Old data sink becomes new data source. */ - if (vfm_sink->class->make_source != NULL) - vfm_source = vfm_sink->class->make_source (vfm_sink); - free_case_sink (vfm_sink); - vfm_sink = NULL; + if (proc_sink->class->make_source != NULL) + proc_source = proc_sink->class->make_source (proc_sink); + free_case_sink (proc_sink); + proc_sink = NULL; - /* Cancel TEMPORARY, PROCESS IF, FILTER, N OF CASES, vectors, - and get rid of all the transformations. */ dict_clear_vectors (default_dict); permanent_dict = NULL; return proc_cancel_all_transformations (); @@ -474,7 +458,6 @@ lagged_case (int n_before) /* Represents auxiliary data for handling SPLIT FILE. */ struct split_aux_data { - size_t case_count; /* Number of cases so far. */ struct ccase prev_case; /* Data in previous case. */ /* Callback functions. */ @@ -514,7 +497,6 @@ procedure_with_splits (void (*begin_func) (const struct ccase *, void *aux), struct split_aux_data split_aux; bool ok; - split_aux.case_count = 0; case_nullify (&split_aux.prev_case); split_aux.begin_func = begin_func; split_aux.proc_func = proc_func; @@ -536,10 +518,10 @@ split_procedure_case_func (const struct ccase *c, void *split_aux_) struct split_aux_data *split_aux = split_aux_; /* Start a new series if needed. */ - if (split_aux->case_count == 0 + if (case_is_null (&split_aux->prev_case) || !equal_splits (c, &split_aux->prev_case)) { - if (split_aux->case_count > 0 && split_aux->end_func != NULL) + if (!case_is_null (&split_aux->prev_case) && split_aux->end_func != NULL) split_aux->end_func (split_aux->func_aux); case_destroy (&split_aux->prev_case); @@ -549,7 +531,6 @@ split_procedure_case_func (const struct ccase *c, void *split_aux_) split_aux->begin_func (&split_aux->prev_case, split_aux->func_aux); } - split_aux->case_count++; return (split_aux->proc_func == NULL || split_aux->proc_func (c, split_aux->func_aux)); } @@ -560,7 +541,7 @@ split_procedure_end_func (void *split_aux_) { struct split_aux_data *split_aux = split_aux_; - if (split_aux->case_count > 0 && split_aux->end_func != NULL) + if (!case_is_null (&split_aux->prev_case) && split_aux->end_func != NULL) split_aux->end_func (split_aux->func_aux); return true; } @@ -673,15 +654,10 @@ discard_variables (void) n_lag = 0; - free_case_source (vfm_source); - vfm_source = NULL; + free_case_source (proc_source); + proc_source = NULL; proc_cancel_all_transformations (); - - expr_free (process_if_expr); - process_if_expr = NULL; - - proc_cancel_temporary_transformations (); } /* Returns the current set of permanent transformations, @@ -823,6 +799,7 @@ void proc_done (void) { discard_variables (); + dict_destroy (default_dict); } /* Sets SINK as the destination for procedure output from the @@ -830,8 +807,8 @@ proc_done (void) void proc_set_sink (struct case_sink *sink) { - assert (vfm_sink == NULL); - vfm_sink = sink; + assert (proc_sink == NULL); + proc_sink = sink; } /* Sets SOURCE as the source for procedure input for the next @@ -839,8 +816,8 @@ proc_set_sink (struct case_sink *sink) void proc_set_source (struct case_source *source) { - assert (vfm_source == NULL); - vfm_source = source; + assert (proc_source == NULL); + proc_source = source; } /* Returns true if a source for the next procedure has been @@ -848,7 +825,7 @@ proc_set_source (struct case_source *source) bool proc_has_source (void) { - return vfm_source != NULL; + return proc_source != NULL; } /* Returns the output from the previous procedure. @@ -862,13 +839,13 @@ proc_capture_output (void) /* Try to make sure that this function is called immediately after procedure() or a similar function. */ - assert (vfm_source != NULL); - assert (case_source_is_class (vfm_source, &storage_source_class)); + assert (proc_source != NULL); + assert (case_source_is_class (proc_source, &storage_source_class)); assert (trns_chain_is_empty (permanent_trns_chain)); assert (!proc_in_temporary_transformations ()); - casefile = storage_source_decapsulate (vfm_source); - vfm_source = NULL; + casefile = storage_source_decapsulate (proc_source); + proc_source = NULL; return casefile; } @@ -943,40 +920,4 @@ filter_trns_proc (void *filter_var_, return (f != 0.0 && !mv_is_num_missing (&filter_var->miss, f) ? TRNS_CONTINUE : TRNS_DROP_CASE); } - -static trns_proc_func process_if_trns_proc; -static trns_free_func process_if_trns_free; - -/* Adds a temporary transformation to filter data according to - the expression specified on PROCESS IF, if any. */ -static void -add_process_if_trns (void) -{ - if (process_if_expr != NULL) - { - proc_start_temporary_transformations (); - add_transformation (process_if_trns_proc, process_if_trns_free, - process_if_expr); - process_if_expr = NULL; - } -} - -/* PROCESS IF transformation. */ -static int -process_if_trns_proc (void *expression_, - struct ccase *c UNUSED, int case_nr UNUSED) - -{ - struct expression *expression = expression_; - return (expr_evaluate_num (expression, c, case_nr) == 1.0 - ? TRNS_CONTINUE : TRNS_DROP_CASE); -} -/* Frees a PROCESS IF transformation. */ -static bool -process_if_trns_free (void *expression_) -{ - struct expression *expression = expression_; - expr_free (expression); - return true; -}