summaryrefslogtreecommitdiffstats
path: root/src/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cache.c')
-rw-r--r--src/cache.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/src/cache.c b/src/cache.c
index 0c99322..f8a2026 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -47,8 +47,10 @@ int cache_populate(struct stream * const in)
break;
}
}
+ } else if (in->type == stream_in) {
+ try(1, err, ENOSYS, "populating cache from file is a TODO");
} else {
- /* TODO */
+ try(1, err, EINVAL, "cannot populate a non-reading stream cache");
}
err:
@@ -92,7 +94,7 @@ int cache_block_copy(struct stream const * const src, struct stream * const 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(src->n > dest->settings->to, err, EINVAL, "invalid copy size");
try(!dest->cache, err, EINVAL, "no cache to transfer to");
memcpy(dest->cache, src->cache_a + dest->settings->ss, (dest->settings->to - dest->settings->ss) * dest->settings->stride);
@@ -109,7 +111,7 @@ int cache_list_copy(struct stream * const src, struct stream * const 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(!(src->n > dest->settings->to), err, EINVAL, "invalid copy size");
try(!dest->cache, err, EINVAL, "no cache to transfer to");
while ((tmp = get(src))) {
@@ -125,18 +127,38 @@ err:
int cache_block_split(struct stream * const src, struct stream * const A, struct stream * const B)
{
int ret = 0;
+ struct settings tmp_settings;
try(src->n < 2, err, EINVAL, "cannot split single element stream.");
- /* copy everything, then change whatever's neccesary */
- *A = *B = *src;
-
- A->n = A->n / 2 + A->n % 2;
- B->n = B->n / 2;
+ /* setting up minimal stream basics */
+ A->n = src->n / 2;
+ B->n = src->n / 2 + (src->n & 1ul);
A->index = B->index = 0;
- B->cache_a = B->cache_a + A->n;
- B->cache_l = (struct entry_l *) B->cache_a;
- B->cache = (char *) B->cache_a;
+ A->parentid = B->parentid = random(); /* generate random parent ID that needs to match between children */
+ A->type = B->type = stream_invalid; /* 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;
+
+ tmp_settings = *src->settings;
+ A->settings = B->settings = &tmp_settings;
+
+ /* setting up A */
+ tmp_settings.ss = 0;
+ tmp_settings.to = A->n;
+ try_s((ret = cache_create(A)), err);
+ try_s((ret = cache_block_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_block_copy(src, B)), err);
+
+ A->settings = B->settings = &tmp_settings;
err:
return ret;