From 74d822fd30c51b33035cbf017aa8fa75fa2b97c4 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 5 Dec 2009 12:32:59 -0800 Subject: [PATCH] casereader: New function casereader_truncate(). --- src/data/casereader.c | 47 +++++++++++++++++++++++++++++++------------ src/data/casereader.h | 1 + 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/data/casereader.c b/src/data/casereader.c index 5ae5a0a8..0eb3baf5 100644 --- a/src/data/casereader.c +++ b/src/data/casereader.c @@ -257,6 +257,25 @@ casereader_get_case_cnt (struct casereader *reader) return reader->case_cnt; } +static casenumber +casereader_count_cases__ (struct casereader *reader, casenumber max_cases) +{ + struct casereader *clone; + casenumber n_cases; + + clone = casereader_clone (reader); + for (n_cases = 0; n_cases < max_cases; n_cases++) + { + struct ccase *c = casereader_read (clone); + if (c == NULL) + break; + case_unref (c); + } + casereader_destroy (clone); + + return n_cases; +} + /* Returns the number of cases that will be read by successive calls to casereader_read for READER, assuming that no errors occur. Upon an error condition, the case count drops to 0, so @@ -270,22 +289,24 @@ casenumber casereader_count_cases (struct casereader *reader) { if (reader->case_cnt == CASENUMBER_MAX) - { - casenumber n_cases = 0; - struct ccase *c; - - struct casereader *clone = casereader_clone (reader); - - for (; (c = casereader_read (clone)) != NULL; case_unref (c)) - n_cases++; - - casereader_destroy (clone); - reader->case_cnt = n_cases; - } - + reader->case_cnt = casereader_count_cases__ (reader, CASENUMBER_MAX); return reader->case_cnt; } +/* Truncates READER to at most N cases. */ +void +casereader_truncate (struct casereader *reader, casenumber n) +{ + /* This could be optimized, if it ever becomes too expensive, by adding a + "max_cases" member to struct casereader. We could also add a "truncate" + function to the casereader implementation, to allow the casereader to + throw away data that cannot ever be read. */ + if (reader->case_cnt == CASENUMBER_MAX) + reader->case_cnt = casereader_count_cases__ (reader, n); + if (reader->case_cnt > n) + reader->case_cnt = n; +} + /* Returns the prototype for the cases in READER. The caller must not unref the returned prototype. */ const struct caseproto * diff --git a/src/data/casereader.h b/src/data/casereader.h index 3b903bbf..107e6069 100644 --- a/src/data/casereader.h +++ b/src/data/casereader.h @@ -77,6 +77,7 @@ const struct taint *casereader_get_taint (const struct casereader *); casenumber casereader_get_case_cnt (struct casereader *); casenumber casereader_count_cases (struct casereader *); +void casereader_truncate (struct casereader *, casenumber); const struct caseproto *casereader_get_proto (const struct casereader *); void casereader_transfer (struct casereader *, struct casewriter *); -- 2.30.2