diff options
-rw-r--r-- | src/defs.h | 4 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/stream.c | 53 | ||||
-rw-r--r-- | src/stream.h | 2 | ||||
-rw-r--r-- | src/util.c | 9 |
5 files changed, 70 insertions, 2 deletions
@@ -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); @@ -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); @@ -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; |