(parse_rank_function) Fix msg() bug found by -Wformat.
[pspp] / src / casefile.c
index 689e2b1302cb3ed8b540e94f8ebe3a6b6809a1b1..706a6b93916dc727e5e5711bdf579a730e69a852 100644 (file)
@@ -14,8 +14,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA. */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
 
 #include <config.h>
 #include "casefile.h"
 #include "settings.h"
 #include "var.h"
 
-#ifdef HAVE_VALGRIND_VALGRIND_H
-#include <valgrind/valgrind.h>
-#endif
-
 #define IO_BUF_SIZE (8192 / sizeof (union value))
 
-/* A casefile is a sequentially accessible array of immutable
-   cases.  It may be stored in memory or on disk as workspace
-   allows.  Cases may be appended to the end of the file.  Cases
-   may be read sequentially starting from the beginning of the
-   file.  Once any cases have been read, no more cases may be
-   appended.  The entire file is discarded at once. */
+/* A casefile represents a sequentially accessible stream of
+   immutable cases.
+
+   If workspace allows, a casefile is maintained in memory.  If
+   workspace overflows, then the casefile is pushed to disk.  In
+   either case the interface presented to callers is kept the
+   same.
+
+   The life cycle of a casefile consists of up to three phases:
+
+       1. Writing.  The casefile initially contains no cases.  In
+          this phase, any number of cases may be appended to the
+          end of a casefile.  (Cases are never inserted in the
+          middle or before the beginning of a casefile.)
+
+          Use casefile_append() or casefile_append_xfer() to
+          append a case to a casefile.
+
+       2. Reading.  The casefile may be read sequentially,
+          starting from the beginning, by "casereaders".  Any
+          number of casereaders may be created, at any time,
+          during the reading phase.  Each casereader has an
+          independent position in the casefile.
+
+          Casereaders may only move forward.  They cannot move
+          backward to arbitrary records or seek randomly.
+          Cloning casereaders is possible, but it is not yet
+          implemented.
+
+          Use casefile_get_reader() to create a casereader for
+          use in phase 2.  This also transitions from phase 1 to
+          phase 2.  Calling casefile_mode_reader() makes the same
+          transition, without creating a casereader.
+
+          Use casereader_read(), casereader_read_xfer(), or
+          casereader_read_xfer_assert() to read a case from a
+          casereader.  Use casereader_destroy() to discard a
+          casereader when it is no longer needed.
+
+       3. Destruction.  This phase is optional.  The casefile is
+          also read with casereaders in this phase, but the
+          ability to create new casereaders is curtailed.
+
+          In this phase, casereaders could still be cloned (once
+          we eventually implement cloning).
+
+          To transition from phase 1 or 2 to phase 3 and create a
+          casereader, call casefile_get_destructive_reader().
+          The same functions apply to the casereader obtained
+          this way as apply to casereaders obtained in phase 2.
+          
+          After casefile_get_destructive_reader() is called, no
+          more casereaders may be created with
+          casefile_get_reader() or
+          casefile_get_destructive_reader().  (If cloning of
+          casereaders were implemented, it would still be
+          possible.)
+
+          The purpose of the limitations applied to casereaders
+          in phase 3 is to allow in-memory casefiles to fully
+          transfer ownership of cases to the casereaders,
+          avoiding the need for extra copies of case data.  For
+          relatively static data sets with many variables, I
+          suspect (without evidence) that this may be a big
+          performance boost.
+
+   When a casefile is no longer needed, it may be destroyed with
+   casefile_destroy().  This function will also destroy any
+   remaining casereaders. */
 
 /* In-memory cases are arranged in an array of arrays.  The top
    level is variable size and the size of each bottom level array