a lot of fixes, improve visualization speed, add c++ code
diff --git a/clib/Makefile b/clib/Makefile
new file mode 100644
index 0000000..9786d22
--- /dev/null
+++ b/clib/Makefile
@@ -0,0 +1,6 @@
+libwally.so: interpolate.o Makefile
+ g++ interpolate.o -shared -o libwally.so
+
+interpolate.o: interpolate.cpp
+ g++ -c -Wall -std=c++11 -fPIC -O3 interpolate.cpp -o interpolate.o
+
diff --git a/clib/interpolate.cpp b/clib/interpolate.cpp
new file mode 100644
index 0000000..478eb88
--- /dev/null
+++ b/clib/interpolate.cpp
@@ -0,0 +1,120 @@
+#include <algorithm>
+#include <cstdint>
+#include <cstdio>
+
+extern "C"
+void interpolate_ts_on_seconds_border(
+ unsigned int input_size,
+ unsigned int output_size,
+ uint64_t * times,
+ uint64_t * values,
+ unsigned int time_scale_coef,
+ uint64_t * output)
+{
+ auto first_output_cell = (*times / time_scale_coef) * time_scale_coef;
+ auto input_cell_end = *times - time_scale_coef; // hack to unify loop
+ uint64_t input_cell_begin;
+
+// std::printf("first_output_cell = %ld\n", (long)first_output_cell);
+
+ for(auto curr_times=times, curr_data_ptr=values;
+ curr_times < times + input_size ; ++curr_times, ++curr_data_ptr)
+ {
+ // take next cell from input array and calculate data rate in it
+ auto data_left = *curr_data_ptr;
+ input_cell_begin = input_cell_end;
+ input_cell_end = *curr_times;
+
+ auto rate = data_left / double(input_cell_end - input_cell_begin);
+
+// std::printf("input_cell_begin=%ld input_cell_end=%ld\n", (long)input_cell_begin, (long)input_cell_end);
+// std::printf("rate = %lf data_left=%ld\n", rate, (long)data_left);
+
+ uint32_t first_output_cell_idx;
+ if (input_cell_begin <= first_output_cell)
+ first_output_cell_idx = 0;
+ else
+ // +1 because first_output_cell is actually the end of first cell
+ first_output_cell_idx = (input_cell_begin - first_output_cell) / time_scale_coef + 1;
+
+ uint32_t last_output_cell_idx = (input_cell_end - first_output_cell) / time_scale_coef;
+
+ if ((input_cell_end - first_output_cell) % time_scale_coef != 0)
+ ++last_output_cell_idx;
+
+ last_output_cell_idx = std::min(last_output_cell_idx, output_size - 1);
+
+// std::printf("fidx=%d lidx=%d\n", (int)first_output_cell_idx, (int)last_output_cell_idx);
+
+ for(auto output_idx = first_output_cell_idx; output_idx <= last_output_cell_idx ; ++output_idx)
+ {
+ // current output cell time slot
+ auto out_cell_begin = output_idx * time_scale_coef + first_output_cell - time_scale_coef;
+ auto out_cell_end = out_cell_begin + time_scale_coef;
+ auto slot = std::min(out_cell_end, input_cell_end) - std::max(out_cell_begin, input_cell_begin);
+
+ auto slice = uint64_t(rate * slot);
+
+// std::printf("slot=%ld slice=%lf output_idx=%ld\n", (long)slot, (double)slice, (long)output_idx);
+
+ data_left -= slice;
+ output[output_idx] += slice;
+ }
+ output[last_output_cell_idx] += data_left;
+ }
+}
+
+
+extern "C"
+void interpolate_ts_on_seconds_border_v2(
+ unsigned int input_size,
+ unsigned int output_size,
+ uint64_t * times,
+ uint64_t * values,
+ unsigned int time_step,
+ uint64_t * output)
+{
+ auto output_end = (*times / time_step) * time_step;
+ auto output_begin = output_end - time_step;
+ auto output_cell = output;
+
+ auto input_cell = values;
+ auto input_time = times;
+ auto input_val = *input_cell;
+ auto input_begin = *input_time - time_step;
+ auto input_end = *input_time;
+ auto rate = ((double)*input_cell) / (input_end - input_begin);
+
+ // output array mush fully cover input array
+ while(output_cell < output + output_size) {
+ // check if cells intersect
+ auto intersection = ((int64_t)std::min(output_end, input_end)) - std::max(output_begin, input_begin);
+
+ // add intersection slice to output array
+ if(intersection > 0) {
+ auto slice = (uint64_t)(intersection * rate);
+ *output_cell += slice;
+ input_val -= slice;
+ }
+
+ // switch to next input or output cell
+ if (output_end >= input_end){
+ *output_cell += input_val;
+
+ ++input_cell;
+ ++input_time;
+
+ if(input_time == times + input_size)
+ return;
+
+ input_val = *input_cell;
+ input_begin = input_end;
+ input_end = *input_time;
+ rate = ((double)*input_cell) / (input_end - input_begin);
+ } else {
+ ++output_cell;
+ output_begin = output_end;
+ output_end += time_step;
+ }
+ }
+}
\ No newline at end of file