summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Gediminas Jakutis <gediminas@varciai.lt> 2021-03-15 02:39:41 +0200
committerGravatar Gediminas Jakutis <gediminas@varciai.lt> 2021-03-15 02:39:41 +0200
commita84c0f57b5efde85c195cbc706715bf4a4116018 (patch)
treed9c5715d637dd870ca5ffe6f3bb031297c8d2f45
parent111d08d814720966d12fd57b58331c149df7e6cf (diff)
downloadalgos-ld1-1.0.tar.gz
algos-ld1-1.0.tar.bz2
algos-ld1-1.0.zip
cleanup and optimizations.algos-ld1-1.0
· No longer rewinding a stream being split, just to skip half through it again, which was not only stupid, but inneficient. · No longer using "index" anywhere when working with lists, lest we get accused of not actually doing lists. Signed-off-by: Gediminas Jakutis <gediminas@varciai.lt>
-rw-r--r--src/cache.c14
-rw-r--r--src/main.c1
-rw-r--r--src/stream.c51
-rw-r--r--src/util.c17
-rw-r--r--src/util.h1
5 files changed, 49 insertions, 35 deletions
diff --git a/src/cache.c b/src/cache.c
index 2b24dd0..3a169b8 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -122,10 +122,9 @@ struct entry_l *cached_get_list(struct stream * const in, struct entry_l * const
{
struct entry_l *ret = NULL;
- if (in->index < in->n) {
+ if (in->cnode) {
ret = in->cnode;
- in->cnode = ret->next ? ret->next : in->cnode;
- ++in->index;
+ in->cnode = ret->next;
*store = *ret;
ret = store;
}
@@ -163,17 +162,14 @@ int cached_put_list(struct stream * const restrict in, const struct entry_l * co
if (!in->cnode) { /* if this is the very first one */
in->cnode = in->cache_l;
- in->cnode->val = node->val;
- in->cnode->next = NULL;
- in->index = 1;
} else {
in->cnode->next = in->cnode + 1; /* lol says librin, lmao */
in->cnode = in->cnode->next;
- in->cnode->val = node->val;
- in->cnode->next = NULL;
- ++in->index;
}
+ in->cnode->val = node->val;
+ in->cnode->next = NULL;
+
err:
return ret;
}
diff --git a/src/main.c b/src/main.c
index f4990ac..905da11 100644
--- a/src/main.c
+++ b/src/main.c
@@ -72,6 +72,7 @@ int main(int argc, char **argv)
switch (settings.opmode) {
case mode_fetch:
+ stream_skip(&file_in);
stream_shallow_copy(&file_in, &file_tmp);
if (settings.format == array) {
try_s((ret = cache_block_copy(&file_in, &file_tmp)), out);
diff --git a/src/stream.c b/src/stream.c
index 13df929..48f7e4c 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -125,15 +125,19 @@ struct entry_l *file_get_list(struct stream * const in, struct entry_l * const s
struct entry_l *ret = NULL;
ssize_t bytes_read;
- if (in->index < in->n) {
- in->cnode = in->cnode ? in->cnode : &in->cnode_f;
+ if (in->cnode) {
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;
+
+ if (ent.file_offset) {
+ in->cnode->file_offset = ent.file_offset;
+ } else { /* reached end of list; unhook */
+ in->cnode = NULL;
+ }
+
ret = store;
}
@@ -161,29 +165,27 @@ 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");
+ struct entry_l tmp = {0}; /* we use a temp var for next offest to be zero */
+ off_t offset = 0;
if (!in->cnode) { /* if this is the very first one */
in->cnode = &in->cnode_f;
} else {
- in->cnode->file_offset += sizeof(*node);
+ offset = in->cnode->file_offset;
+ offset += sizeof(*node); /* advance by one */
/* 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);
+ try(0 > (bytes_written = pwrite(in->fd, &offset, sizeof(offset), offset - sizeof(in->cnode->file_offset))), 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));
- }
+ do {
+ try(0 > (bytes_written = pwrite(in->fd, &tmp, sizeof(tmp), offset)), err, errno, "Writing to stream failed with %i", ret);
+ } while (bytes_written != sizeof(tmp));
- ++in->index;
+ in->cnode->file_offset = offset; /* store the new "current" offset */
err:
return ret;
}
@@ -206,23 +208,16 @@ int file_transfer(struct stream * const src, struct stream * const dest)
int stream_copy_range(struct stream * const restrict src, struct stream * const restrict dest)
{
int ret = 0;
- size_t ss;
+ struct entry_l *tmp;
struct entry_l tmp_store;
+ size_t i = 0;
try(src->n < dest->settings->to, err, EINVAL, "invalid copy size");
- ss = dest->settings->ss;
-
- /* skip over to start position */
- while (ss--) {
- src->get(src, &tmp_store);
+ while (i++ < (dest->n) && (tmp = src->get(src, &tmp_store))) {
+ dest->put(dest, tmp);
}
- do {
- dest->put(dest, src->get(src, &tmp_store));
- } while (dest->index < (dest->n));
-
- stream_rewind(src);
stream_rewind(dest);
err:
@@ -320,6 +315,10 @@ static int stream_open_in(struct stream * const in)
in->fd = open(in->name, O_RDONLY | O_NOATIME);
try(in->fd < 0, err, errno, "failed opening input file: %s", strerror(ret));
+ if (in->settings->access == direct) {
+ in->cnode = &in->cnode_f;
+ }
+
err:
return ret;
}
diff --git a/src/util.c b/src/util.c
index c14a848..2b32a94 100644
--- a/src/util.c
+++ b/src/util.c
@@ -22,6 +22,21 @@ int stream_rewind(struct stream * const restrict in)
return ret;
}
+int stream_skip(struct stream * const restrict in)
+{
+ int ret = 0;
+ size_t ss;
+ struct entry_l discard;
+
+ ss = in->settings->ss;
+
+ while (ss--) {
+ in->get(in, &discard);
+ }
+
+ return ret;
+}
+
int split(struct stream * const src, struct stream * const A, struct stream * const B)
{
int ret = 0;
@@ -57,6 +72,7 @@ int split(struct stream * const src, struct stream * const A, struct stream * co
try_s((ret = src->copy(src, A)), err);
try_s((ret = cache_create(B)), err);
try_s((ret = src->copy(src, B)), err);
+ stream_rewind(src);
} else {
A->name = B->name = src->name;
A->type = B->type = stream_lite;
@@ -64,6 +80,7 @@ int split(struct stream * const src, struct stream * const A, struct stream * co
try_s((ret = src->copy(src, A)), err);
try_s((ret = stream_open(B)), err);
try_s((ret = src->copy(src, B)), err);
+ stream_rewind(src);
}
A->settings = B->settings = src->settings;
diff --git a/src/util.h b/src/util.h
index 090a4a0..8435ccf 100644
--- a/src/util.h
+++ b/src/util.h
@@ -8,6 +8,7 @@
#include "defs.h"
int stream_rewind(struct stream * const restrict in);
+int stream_skip(struct stream * const restrict in);
int split(struct stream * const src, struct stream * const A, struct stream * const B);
int print_data(struct stream * const in);