blob: 478eb88e4f5ff09dd248cec33a1f5845673fbabe [file] [log] [blame]
kdanylov aka kodercdfcdaf2017-04-29 10:03:39 +03001#include <algorithm>
2#include <cstdint>
3#include <cstdio>
4
5extern "C"
6void interpolate_ts_on_seconds_border(
7 unsigned int input_size,
8 unsigned int output_size,
9 uint64_t * times,
10 uint64_t * values,
11 unsigned int time_scale_coef,
12 uint64_t * output)
13{
14 auto first_output_cell = (*times / time_scale_coef) * time_scale_coef;
15 auto input_cell_end = *times - time_scale_coef; // hack to unify loop
16 uint64_t input_cell_begin;
17
18// std::printf("first_output_cell = %ld\n", (long)first_output_cell);
19
20 for(auto curr_times=times, curr_data_ptr=values;
21 curr_times < times + input_size ; ++curr_times, ++curr_data_ptr)
22 {
23 // take next cell from input array and calculate data rate in it
24 auto data_left = *curr_data_ptr;
25 input_cell_begin = input_cell_end;
26 input_cell_end = *curr_times;
27
28 auto rate = data_left / double(input_cell_end - input_cell_begin);
29
30// std::printf("input_cell_begin=%ld input_cell_end=%ld\n", (long)input_cell_begin, (long)input_cell_end);
31// std::printf("rate = %lf data_left=%ld\n", rate, (long)data_left);
32
33 uint32_t first_output_cell_idx;
34 if (input_cell_begin <= first_output_cell)
35 first_output_cell_idx = 0;
36 else
37 // +1 because first_output_cell is actually the end of first cell
38 first_output_cell_idx = (input_cell_begin - first_output_cell) / time_scale_coef + 1;
39
40 uint32_t last_output_cell_idx = (input_cell_end - first_output_cell) / time_scale_coef;
41
42 if ((input_cell_end - first_output_cell) % time_scale_coef != 0)
43 ++last_output_cell_idx;
44
45 last_output_cell_idx = std::min(last_output_cell_idx, output_size - 1);
46
47// std::printf("fidx=%d lidx=%d\n", (int)first_output_cell_idx, (int)last_output_cell_idx);
48
49 for(auto output_idx = first_output_cell_idx; output_idx <= last_output_cell_idx ; ++output_idx)
50 {
51 // current output cell time slot
52 auto out_cell_begin = output_idx * time_scale_coef + first_output_cell - time_scale_coef;
53 auto out_cell_end = out_cell_begin + time_scale_coef;
54 auto slot = std::min(out_cell_end, input_cell_end) - std::max(out_cell_begin, input_cell_begin);
55
56 auto slice = uint64_t(rate * slot);
57
58// std::printf("slot=%ld slice=%lf output_idx=%ld\n", (long)slot, (double)slice, (long)output_idx);
59
60 data_left -= slice;
61 output[output_idx] += slice;
62 }
63 output[last_output_cell_idx] += data_left;
64 }
65}
66
67
68extern "C"
69void interpolate_ts_on_seconds_border_v2(
70 unsigned int input_size,
71 unsigned int output_size,
72 uint64_t * times,
73 uint64_t * values,
74 unsigned int time_step,
75 uint64_t * output)
76{
77 auto output_end = (*times / time_step) * time_step;
78 auto output_begin = output_end - time_step;
79 auto output_cell = output;
80
81 auto input_cell = values;
82 auto input_time = times;
83 auto input_val = *input_cell;
84 auto input_begin = *input_time - time_step;
85 auto input_end = *input_time;
86 auto rate = ((double)*input_cell) / (input_end - input_begin);
87
88 // output array mush fully cover input array
89 while(output_cell < output + output_size) {
90 // check if cells intersect
91 auto intersection = ((int64_t)std::min(output_end, input_end)) - std::max(output_begin, input_begin);
92
93 // add intersection slice to output array
94 if(intersection > 0) {
95 auto slice = (uint64_t)(intersection * rate);
96 *output_cell += slice;
97 input_val -= slice;
98 }
99
100 // switch to next input or output cell
101 if (output_end >= input_end){
102 *output_cell += input_val;
103
104 ++input_cell;
105 ++input_time;
106
107 if(input_time == times + input_size)
108 return;
109
110 input_val = *input_cell;
111 input_begin = input_end;
112 input_end = *input_time;
113 rate = ((double)*input_cell) / (input_end - input_begin);
114 } else {
115 ++output_cell;
116 output_begin = output_end;
117 output_end += time_step;
118 }
119 }
120}