#include #include #include "defs.h" #include "util.h" #include "cache.h" #include "stream.h" int stream_rewind(struct stream * const restrict in) { int ret = 0; if (in->cnode) { if (in->cache) { in->cnode = in->cache_l; } else { in->cnode_f.file_offset = 0; } } in->index = 0; 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; struct settings tmp_settings[2]; 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; /* we only care about these three functions for these temporary streams */ A->get = B->get = src->get; A->put = B->put = src->put; A->copy = B->copy = src->copy; tmp_settings[0] = *src->settings; tmp_settings[1] = *src->settings; A->settings = tmp_settings; B->settings = tmp_settings + 1; /* setting up A */ tmp_settings[0].ss = 0; tmp_settings[0].to = A->n; /* setting up B */ tmp_settings[1].ss = A->n; tmp_settings[1].to = src->n; if (src->settings->access == cached) { A->fd = B->fd = -1; /* if we're splitting, these are for holding cache only */ A->type = B->type = stream_cache; try_s((ret = cache_create(A)), err); 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; try_s((ret = stream_open(A)), err); 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; err: return ret; } int print_data(struct stream * const in) { int ret = 0; struct entry_l store; size_t i; puts( " position | value |\n" " | |"); for (i = 0; in->get(in, &store); ++i) { printf(" %10lu | " "%20"fieldprint" |\n", in->settings->ss + i, store.val); } return ret; }