summaryrefslogtreecommitdiffstats
path: root/src/util.c
blob: 2b32a94cd031ca5cc81521857ead1147e37f09cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <errno.h>
#include <stdio.h>
#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;
}