diff options
author | 2021-02-28 22:31:36 +0200 | |
---|---|---|
committer | 2021-02-28 22:31:36 +0200 | |
commit | d249b69a55f9bf1f3a97627f9cc26bb1cdf673b5 (patch) | |
tree | 3d789019de0b5ae8aa1133ac2473a26a855059eb /src/cache.c | |
parent | 7f522688e215c437b945b85820691e6488d4625e (diff) | |
download | algos-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.c | 60 |
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; } |