summaryrefslogtreecommitdiffstats
path: root/src/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cache.c')
-rw-r--r--src/cache.c63
1 files changed, 52 insertions, 11 deletions
diff --git a/src/cache.c b/src/cache.c
index bb41689..fe97fef 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -9,6 +9,8 @@
#include <rin/diagnostic.h>
#include "defs.h"
+static int cache_rewind(struct stream * const in);
+
int cache_create(struct stream * const in)
{
int ret = 0;
@@ -100,15 +102,23 @@ err:
return ret;
}
-int cache_list_copy(struct stream const * const src, struct stream * const dest)
+int cache_list_copy(struct stream * const src, struct stream * const dest)
{
- int ret = ENOSYS;
+ int ret = 0;
+ struct entry_l *tmp;
- (void) src;
- (void) dest;
+ try(src->settings->access != cached || dest->settings->access != cached, err, EINVAL, "cannot cache-copy between uncached streams");
+ try(!src->cache, err, EINVAL, "no cache to transfer");
+ try(!(src->n < dest->settings->to), err, EINVAL, "invalid copy size");
+ try(!dest->cache, err, EINVAL, "no cache to transfer to");
- rin_warn("stub!");
+ while ((tmp = get(src))) {
+ put(dest, tmp);
+ }
+
+ cache_rewind(src);
+err:
return ret;
}
@@ -163,7 +173,7 @@ struct entry_l *cached_get_list(struct stream * const in)
if (in->index < in->n) {
ret = in->cnode;
- in->cnode = (struct entry_l *) ret->next;
+ in->cnode = ret->next;
++in->index;
}
@@ -172,7 +182,7 @@ struct entry_l *cached_get_list(struct stream * const in)
int cached_put_array(struct stream * const in, const struct entry_l * const data)
{
- int ret = EINVAL;
+ int ret = 0;
if (in->index < in->n) {
in->cache_a[in->index].val = data->val;
@@ -182,14 +192,45 @@ int cached_put_array(struct stream * const in, const struct entry_l * const data
return ret;
}
+/* This is were fun with the fact mergesort is NOT an in-place algorightm begins.
+ * Since we only ever need to "put" on a) generating data and b) merging lists,
+ * we basically have to generate the list anew each and every time. For generating,
+ * it's a no-brainer, but for lists, while reusing existing nodes COULD be done in
+ * a chached variant, file variant cannot do this, as cross-file links are not
+ * something that could be handled without going into pretty insane (and laughably
+ * inefficient) lenghts either way.
+ *
+ * And thus alas, we have no option but to just make a list anew
+ */
int cached_put_list(struct stream * const restrict in, const struct entry_l * const node)
{
- int ret = ENOSYS;
+ int ret = 0;
- (void) in;
- (void) node;
+ if (!in->cnode) { /* if this is the very first one */
+ in->pnode = NULL;
+ in->cnode = in->cache_l;
+ in->cnode->val = node->val;
+ in->cnode->next = NULL;
+ in->index = 0;
+ } else {
+ in->pnode = in->cnode;
+ in->cnode = in->cnode + 1; /* lol says librin, lmao */
+ in->pnode->next = in->cnode;
+ in->cnode->val = node->val;
+ in->cnode->next = NULL;
+ ++in->index;
+ }
- rin_warn("stub!");
+ return ret;
+}
+
+int cache_rewind(struct stream * const in)
+{
+ int ret = 0;
+
+ in->pnode = NULL;
+ in->cnode = in->cnode ? in->cache_l : NULL;
+ in->index = 0;
return ret;
}