summaryrefslogtreecommitdiffstats
path: root/src/cache.c
diff options
context:
space:
mode:
authorGravatar Gediminas Jakutis <gediminas@varciai.lt> 2021-02-28 22:31:36 +0200
committerGravatar Gediminas Jakutis <gediminas@varciai.lt> 2021-02-28 22:31:36 +0200
commitd249b69a55f9bf1f3a97627f9cc26bb1cdf673b5 (patch)
tree3d789019de0b5ae8aa1133ac2473a26a855059eb /src/cache.c
parent7f522688e215c437b945b85820691e6488d4625e (diff)
downloadalgos-ld1-d249b69a55f9bf1f3a97627f9cc26bb1cdf673b5.tar.gz
algos-ld1-d249b69a55f9bf1f3a97627f9cc26bb1cdf673b5.tar.bz2
algos-ld1-d249b69a55f9bf1f3a97627f9cc26bb1cdf673b5.zip
now with cached list handling!
Implemented the last two cached list handling functions required to get this party started. Signed-off-by: Gediminas Jakutis <gediminas@varciai.lt>
Diffstat (limited to 'src/cache.c')
-rw-r--r--src/cache.c60
1 files changed, 49 insertions, 11 deletions
diff --git a/src/cache.c b/src/cache.c
index f158e44..86e3161 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -22,7 +22,6 @@ int cache_create(struct stream * const in)
try(in->settings->access != cached, err, EINVAL, "cannot create cache: stream is uncached");
try(!(cache = calloc(in->n, in->settings->stride)), err, ENOMEM, "out of memory");
- /* yeah... */
in->cache = cache;
in->cnode = NULL;
err:
@@ -104,18 +103,26 @@ err:
int cache_list_copy(struct stream * const src, struct stream * const dest)
{
int ret = 0;
- struct entry_l *tmp;
+ size_t ss;
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(src->n < dest->settings->to, err, EINVAL, "invalid copy size");
try(!dest->cache, err, EINVAL, "no cache to transfer to");
- while ((tmp = get(src))) {
- put(dest, tmp);
+ ss = dest->settings->ss;
+
+ /* skip over to start position */
+ while (ss--) {
+ get(src);
}
+ do {
+ put(dest, get(src));
+ } while (dest->index < (dest->n - 1));
+
cache_rewind(src);
+ cache_rewind(dest);
err:
return ret;
@@ -163,14 +170,42 @@ err:
int cache_list_split(struct stream * const src, struct stream * const A, struct stream * const B)
{
- int ret = ENOSYS;
+ int ret = 0;
+ struct settings tmp_settings;
+
+
+ try(src->n < 2, err, EINVAL, "cannot split single element stream.");
+
+ /* setting up minimal stream basics */
+ A->n = src->n / 2;
+ B->n = src->n / 2 + (src->n & 1ul);
+ A->index = B->index = 0;
+ A->type = B->type = stream_cache; /* disallow any stream operations other than split/merge on children */
+ A->fd = B->fd = -1; /* if we're splitting, these are for holding cache only */
+ /* we only care about these three functions for these temporary streams */
+ A->get_next_element_cache = B->get_next_element_cache = src->get_next_element_cache;
+ A->place_next_element_cache = B->place_next_element_cache = src->place_next_element_cache;
+ A->split = B->split = src->split;
+ A->rewind = B->rewind = src->rewind;
- (void) src;
- (void) A;
- (void) B;
+ tmp_settings = *src->settings;
+ A->settings = B->settings = &tmp_settings;
- rin_warn("stub!");
+ /* setting up A */
+ tmp_settings.ss = 0;
+ tmp_settings.to = A->n;
+ try_s((ret = cache_create(A)), err);
+ try_s((ret = cache_list_copy(src, A)), err);
+ /* setting up B */
+ tmp_settings.ss = A->n;
+ tmp_settings.to = src->n;
+ try_s((ret = cache_create(B)), err);
+ try_s((ret = cache_list_copy(src, B)), err);
+
+ A->settings = B->settings = src->settings;
+
+err:
return ret;
}
@@ -192,7 +227,7 @@ struct entry_l *cached_get_list(struct stream * const in)
if (in->index < in->n) {
ret = in->cnode;
- in->cnode = ret->next;
+ in->cnode = ret->next ? ret->next : in->cnode;
++in->index;
}
@@ -225,6 +260,8 @@ int cached_put_list(struct stream * const restrict in, const struct entry_l * co
{
int ret = 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->cache_l;
in->cnode->val = node->val;
@@ -238,6 +275,7 @@ int cached_put_list(struct stream * const restrict in, const struct entry_l * co
++in->index;
}
+err:
return ret;
}