summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/defs.h4
-rw-r--r--src/main.c4
-rw-r--r--src/stream.c53
-rw-r--r--src/stream.h2
-rw-r--r--src/util.c9
5 files changed, 70 insertions, 2 deletions
diff --git a/src/defs.h b/src/defs.h
index 522eed4..878823f 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -86,6 +86,7 @@ union nextoff {
struct entry_l *next;
void *nextaddr;
ptrdiff_t offset;
+ off_t file_offset;
int64_t spacer; /* make sure it is 8-byte-alligned on 32 bit pointer systems */
};
@@ -137,7 +138,8 @@ struct stream {
enum streamtype type;
char *name;
size_t index;
- struct entry_l *cnode; /* "current" node */
+ struct entry_l *cnode; /* cached access */
+ struct entry_l cnode_f; /* file access */
union cachewrap;
struct settings *settings;
struct entry_l *(*get)(struct stream * const, struct entry_l * const);
diff --git a/src/main.c b/src/main.c
index d82b0d6..1bac2de 100644
--- a/src/main.c
+++ b/src/main.c
@@ -240,6 +240,10 @@ static int load_io_functions(struct settings const * const s, struct stream * co
in->get = file_get_array;
in->put = file_put_array;
in->copy = stream_copy_range;
+ } else { /* if (s->format == list */
+ in->get = file_get_list;
+ in->put = file_put_list;
+ in->copy = stream_copy_range;
}
}
diff --git a/src/stream.c b/src/stream.c
index da8d9c8..6a84940 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -119,6 +119,28 @@ err:
return ret;
}
+struct entry_l *file_get_list(struct stream * const in, struct entry_l * const store)
+{
+ struct entry_l ent;
+ struct entry_l *ret = NULL;
+ ssize_t bytes_read;
+
+ if (in->index < in->n) {
+ in->cnode = in->cnode ? in->cnode : &in->cnode_f;
+ do {
+ try(0 > (bytes_read = pread(in->fd, &ent, sizeof(ent), in->cnode->file_offset)), err, NULL, "Writing to stream failed with %i", errno);
+ } while (bytes_read != sizeof(ent));
+
+ in->cnode->file_offset = ent.file_offset;
+ ++in->index;
+ store->val = ent.val;
+ ret = store;
+ }
+
+err:
+ return ret;
+}
+
int file_put_array(struct stream * const in, const struct entry_l * const data)
{
int ret = 0;
@@ -135,6 +157,37 @@ err:
return ret;
}
+int file_put_list(struct stream * const in, const struct entry_l * const node)
+{
+ int ret = 0;
+ ssize_t bytes_written;
+ struct entry_l tmp = {0};
+
+ try(in->index >= in->n, err, EINVAL, "can't add element: out of cache bounds");
+
+ if (!in->cnode) { /* if this is the very first one */
+ in->cnode = &in->cnode_f;
+ } else {
+ in->cnode->file_offset += sizeof(*node);
+ /* writing the offset of the node being added to the current node's offset field */
+ do {
+ try(0 > (bytes_written = pwrite(in->fd, &in->cnode->file_offset, sizeof(in->cnode->file_offset), in->cnode->file_offset - sizeof(*node) + sizeof(node->val))), err, errno, "Writing to stream failed with %i", ret);
+ } while (bytes_written != sizeof(in->cnode->file_offset));
+ }
+
+ tmp.val = node->val;
+
+ if (in->index < in->n) {
+ do {
+ try(0 > (bytes_written = pwrite(in->fd, &tmp, sizeof(tmp), in->cnode->file_offset)), err, errno, "Writing to stream failed with %i", ret);
+ } while (bytes_written != sizeof(tmp));
+ }
+
+ ++in->index;
+err:
+ return ret;
+}
+
int file_transfer(struct stream * const src, struct stream * const dest)
{
int ret = 0;
diff --git a/src/stream.h b/src/stream.h
index 3617930..8d1f789 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -12,9 +12,11 @@ int stream_close(struct stream * const in);
/* uncached GET */
struct entry_l *file_get_array(struct stream * const in, struct entry_l * const store);
+struct entry_l *file_get_list(struct stream * const in, struct entry_l * const store);
/* uncached PUT */
int file_put_array(struct stream * const in, const struct entry_l * const data);
+int file_put_list(struct stream * const restrict in, const struct entry_l * const node);
/* uncached blockmanip */
int file_transfer(struct stream * const src, struct stream * const dest);
diff --git a/src/util.c b/src/util.c
index 47bf7a7..b2a3115 100644
--- a/src/util.c
+++ b/src/util.c
@@ -8,7 +8,14 @@ int stream_rewind(struct stream * const restrict in)
{
int ret = 0;
- in->cnode = in->cnode ? in->cache_l : NULL;
+ if (in->cnode) {
+ if (in->cache) {
+ in->cnode = in->cache_l;
+ } else {
+ in->cnode_f.file_offset = 0;
+ }
+ }
+
in->index = 0;
return ret;