casereader: New function casereader_truncate(). fc11-i386-build44 fc11-x64-build41 lenny-x64-build65 sid-i386-build113
authorBen Pfaff <blp@gnu.org>
Sat, 5 Dec 2009 20:32:59 +0000 (12:32 -0800)
committerBen Pfaff <blp@gnu.org>
Sat, 5 Dec 2009 20:32:59 +0000 (12:32 -0800)
src/data/casereader.c
src/data/casereader.h

index 5ae5a0a8ea4431019660c60e1d56d9d68ed8c3fa..0eb3baf5c1ea1af841915c0b01a29a06403fe444 100644 (file)
@@ -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 *
index 3b903bbfd52d66cdba8ffe0e960fa7f0d1ef2474..107e60693bb6022d9c7ecd55ec6b4b3931d86f30 100644 (file)
@@ -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 *);