[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Pspp-cvs] pspp/src dataChangeLog datacasefile.c datacasef...
From: |
Ben Pfaff |
Subject: |
[Pspp-cvs] pspp/src dataChangeLog datacasefile.c datacasef... |
Date: |
Wed, 07 Jun 2006 01:48:47 +0000 |
CVSROOT: /cvsroot/pspp
Module name: pspp
Changes by: Ben Pfaff <blp> 06/06/07 01:48:47
Modified files:
src/data : ChangeLog casefile.c casefile.h
src/language/tests: ChangeLog casefile-test.c
Log message:
Add random access to casefiles, for use in GUI.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/ChangeLog?cvsroot=pspp&r1=1.50&r2=1.51
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casefile.c?cvsroot=pspp&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casefile.h?cvsroot=pspp&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/tests/ChangeLog?cvsroot=pspp&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/tests/casefile-test.c?cvsroot=pspp&r1=1.2&r2=1.3
Patches:
Index: data/ChangeLog
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/ChangeLog,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -b -r1.50 -r1.51
--- data/ChangeLog 30 May 2006 12:01:33 -0000 1.50
+++ data/ChangeLog 7 Jun 2006 01:48:47 -0000 1.51
@@ -1,3 +1,15 @@
+Tue Jun 6 18:46:26 2006 Ben Pfaff <address@hidden>
+
+ Implement random access to casefiles, for use in GUI.
+
+ * casefile.c: (struct casereader) Add `random', `file_ofs',
+ `buffer_ofs' members.
+ (casefile_get_random_reader) New function.
+ (read_open_file) Break part into new function
+ seek_and_fill_buffer().
+ (fill_buffer) Update buffer_ofs, file_ofs.
+ (casereader_seek) New function.
+
Tue May 30 19:52:33 WST 2006 John Darrington <address@hidden>
* settings.c: Added call to i18n{done, init}.
Index: data/casefile.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/casefile.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- data/casefile.c 10 May 2006 04:08:25 -0000 1.9
+++ data/casefile.c 7 Jun 2006 01:48:47 -0000 1.10
@@ -150,9 +150,12 @@
struct casefile *cf; /* Our casefile. */
unsigned long case_idx; /* Case number of current case. */
bool destructive; /* Is this a destructive reader? */
+ bool random; /* Is this a random reader? */
/* Disk storage. */
int fd; /* File descriptor. */
+ off_t file_ofs; /* Current position in fd. */
+ off_t buffer_ofs; /* File offset of buffer start. */
union value *buffer; /* I/O buffer. */
size_t buffer_pos; /* Offset of buffer position. */
struct ccase c; /* Current case. */
@@ -174,10 +177,11 @@
static void register_atexit (void);
static void exit_handler (void);
-static void reader_open_file (struct casereader *reader);
-static void write_case_to_disk (struct casefile *cf, const struct ccase *c);
-static void flush_buffer (struct casefile *cf);
-static bool fill_buffer (struct casereader *reader);
+static void reader_open_file (struct casereader *);
+static void write_case_to_disk (struct casefile *, const struct ccase *);
+static void flush_buffer (struct casefile *);
+static void seek_and_fill_buffer (struct casereader *);
+static bool fill_buffer (struct casereader *);
static void io_error (struct casefile *, const char *, ...)
PRINTF_FORMAT (2, 3);
@@ -423,8 +427,6 @@
cf->buffer_size * sizeof *cf->buffer))
io_error (cf, _("Error writing temporary file: %s."),
strerror (errno));
-
-
cf->buffer_used = 0;
}
}
@@ -519,6 +521,7 @@
reader->cf = cf;
reader->case_idx = 0;
reader->destructive = 0;
+ reader->random = false;
reader->fd = -1;
reader->buffer = NULL;
reader->buffer_pos = 0;
@@ -530,6 +533,17 @@
return reader;
}
+/* Creates and returns a random casereader for CF. A random
+ casereader can be used to randomly read the cases in a
+ casefile. */
+struct casereader *
+casefile_get_random_reader (const struct casefile *cf)
+{
+ struct casereader *reader = casefile_get_reader (cf);
+ reader->random = true;
+ return reader;
+}
+
/* Creates and returns a destructive casereader for CF. Like a
normal casereader, a destructive casereader sequentially reads
the cases in a casefile. Unlike a normal casereader, a
@@ -556,8 +570,6 @@
reader_open_file (struct casereader *reader)
{
struct casefile *cf = reader->cf;
- off_t file_ofs;
-
if (!cf->ok || reader->case_idx >= cf->case_cnt)
return;
@@ -585,24 +597,42 @@
memset (reader->buffer, 0, cf->buffer_size * sizeof *cf->buffer);
}
+ case_create (&reader->c, cf->value_cnt);
+
+ reader->buffer_ofs = -1;
+ reader->file_ofs = -1;
+ seek_and_fill_buffer (reader);
+}
+
+/* Seeks the backing file for READER to the proper position and
+ refreshes the buffer contents. */
+static void
+seek_and_fill_buffer (struct casereader *reader)
+{
+ struct casefile *cf = reader->cf;
+ off_t new_ofs;
+
if (cf->value_cnt != 0)
{
size_t buffer_case_cnt = cf->buffer_size / cf->value_cnt;
- file_ofs = ((off_t) reader->case_idx / buffer_case_cnt
+ new_ofs = ((off_t) reader->case_idx / buffer_case_cnt
* cf->buffer_size * sizeof *cf->buffer);
reader->buffer_pos = (reader->case_idx % buffer_case_cnt
* cf->value_cnt);
}
else
- file_ofs = 0;
- if (lseek (reader->fd, file_ofs, SEEK_SET) != file_ofs)
+ new_ofs = 0;
+ if (new_ofs != reader->file_ofs)
+ {
+ if (lseek (reader->fd, new_ofs, SEEK_SET) != new_ofs)
io_error (cf, _("%s: Seeking temporary file: %s."),
cf->file_name, strerror (errno));
+ else
+ reader->file_ofs = new_ofs;
+ }
- if (cf->case_cnt > 0 && cf->value_cnt > 0)
+ if (cf->case_cnt > 0 && cf->value_cnt > 0 && reader->buffer_ofs != new_ofs)
fill_buffer (reader);
-
- case_create (&reader->c, cf->value_cnt);
}
/* Fills READER's buffer by reading a block from disk. */
@@ -619,6 +649,11 @@
else if (bytes != reader->cf->buffer_size * sizeof *reader->buffer)
io_error (reader->cf, _("%s: Temporary file ended unexpectedly."),
reader->cf->file_name);
+ else
+ {
+ reader->buffer_ofs = reader->file_ofs;
+ reader->file_ofs += bytes;
+ }
}
return reader->cf->ok;
}
@@ -696,6 +731,21 @@
}
}
+/* Sets the next case to be read by READER to CASE_IDX,
+ which must be less than the number of cases in the casefile.
+ Allowed only for random readers. */
+void
+casereader_seek (struct casereader *reader, unsigned long case_idx)
+{
+ assert (reader != NULL);
+ assert (reader->random);
+ assert (case_idx < reader->cf->case_cnt);
+
+ reader->case_idx = case_idx;
+ if (reader->cf->storage == DISK)
+ seek_and_fill_buffer (reader);
+}
+
/* Destroys READER. */
void
casereader_destroy (struct casereader *reader)
Index: data/casefile.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/casefile.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- data/casefile.h 10 May 2006 04:08:25 -0000 1.2
+++ data/casefile.h 7 Jun 2006 01:48:47 -0000 1.3
@@ -44,12 +44,15 @@
void casefile_mode_reader (struct casefile *);
struct casereader *casefile_get_reader (const struct casefile *);
struct casereader *casefile_get_destructive_reader (struct casefile *);
+struct casereader *casefile_get_random_reader (const struct casefile *);
const struct casefile *casereader_get_casefile (const struct casereader *);
bool casereader_read (struct casereader *, struct ccase *);
bool casereader_read_xfer (struct casereader *, struct ccase *);
void casereader_destroy (struct casereader *);
+void casereader_seek (struct casereader *, unsigned long case_idx);
+
unsigned long casereader_cnum(const struct casereader *);
#endif /* casefile.h */
Index: language/tests/ChangeLog
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/tests/ChangeLog,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- language/tests/ChangeLog 4 Mar 2006 01:11:57 -0000 1.1
+++ language/tests/ChangeLog 7 Jun 2006 01:48:47 -0000 1.2
@@ -1,3 +1,8 @@
+Tue Jun 6 18:48:00 2006 Ben Pfaff <address@hidden>
+
+ * casefile-test.c: (test_casefile) Test the new casereader_seek()
+ function.
+
Thu Mar 2 08:40:33 WST 2006 John Darrington <address@hidden>
* Moved files from src directory
Index: language/tests/casefile-test.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/tests/casefile-test.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- language/tests/casefile-test.c 15 Mar 2006 03:29:11 -0000 1.2
+++ language/tests/casefile-test.c 7 Jun 2006 01:48:47 -0000 1.3
@@ -21,11 +21,14 @@
#include <data/casefile.h>
#include <data/case.h>
+#include <gsl/gsl_randist.h>
#include <gsl/gsl_rng.h>
#include <stdarg.h>
#include <language/command.h>
#include <language/lexer/lexer.h>
+#include "xalloc.h"
+
static void test_casefile (int pattern, size_t value_cnt, size_t case_cnt);
static void get_random_case (struct ccase *, size_t value_cnt,
size_t case_idx);
@@ -133,6 +136,24 @@
casereader_destroy (r1);
if (pattern != 2)
casereader_destroy (r2);
+ if (pattern > 3)
+ {
+ int *order;
+ r1 = casefile_get_random_reader (cf);
+ order = xmalloc (sizeof *order * case_cnt);
+ for (i = 0; i < case_cnt; i++)
+ order[i] = i;
+ if (case_cnt > 0)
+ gsl_ran_shuffle (rng, order, case_cnt, sizeof *order);
+ for (i = 0; i < case_cnt; i++)
+ {
+ int case_idx = order[i];
+ casereader_seek (r1, case_idx);
+ read_and_verify_random_case (cf, r1, case_idx);
+ }
+ casereader_destroy (r1);
+ free (order);
+ }
if (pattern > 2)
{
r1 = casefile_get_destructive_reader (cf);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Pspp-cvs] pspp/src dataChangeLog datacasefile.c datacasef...,
Ben Pfaff <=