#ifndef PIECEWISE_COST_DP_H_ #define PIECEWISE_COST_DP_H_ #include "common.h" #include "codecs.h" #include "time.h" #include "bit_read.h" #include "bit_write.h" #include "caltime.h" #include "lr.h" #define INF 0x7f7fffff namespace Codecset { class piecewiseDp : public IntegerCODEC { public: using IntegerCODEC::encodeArray; using IntegerCODEC::decodeArray; using IntegerCODEC::randomdecodeArray; using IntegerCODEC::encodeArray8; using IntegerCODEC::decodeArray8; using IntegerCODEC::randomdecodeArray8; using IntegerCODEC::init; using IntegerCODEC::summation; std::vector block_start_vec; std::vector block_start_vec_total; std::vector segment_index; std::vector segment_index_total; std::vector segment_length; int total_seg = 0; uint64_t total_byte; uint64_t total_byte_total = 0; // int overhead = sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint64_t)*4;//start_index + start_key + slope // int overhead = sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t); int overhead = 10; uint32_t* array; uint32_t* array_total; int tolerance = 0; int block_num; int block_size; //start_index + bit + theta0 + theta1 + numbers + delta void init(int blocks, int blocksize, int delta) { block_num = blocks; block_size = blocksize; tolerance = delta; // add some punishing item total_byte = 0; total_byte_total = 0; } uint32_t lower_bound(uint32_t v, uint32_t len) { uint32_t m; uint32_t x = 0; uint32_t y = len - 1; while (x <= y) { m = x + (y - x) / 2; if (v < segment_index_total[m]) y = m - 1; else x = m + 1; } return y; } uint32_t newsegment(uint32_t origin_index, uint32_t end_index, std::vector& block_start) { int length = end_index - origin_index + 1; if(length == 1){ uint32_t seg_len = newsegment_1(origin_index, origin_index, block_start); return seg_len; } if(length == 2){ uint32_t seg_len = newsegment_2(origin_index, end_index,block_start); return seg_len; } uint8_t* descriptor = (uint8_t*)malloc((end_index - origin_index + 1) * sizeof(uint64_t)*2); uint8_t* out = descriptor; std::vector indexes; std::vector keys; for (int j = origin_index;j <= end_index;j++) { indexes.emplace_back((double)j - origin_index); keys.emplace_back((double)array[j]); } lr mylr; mylr.caltheta(indexes, keys, length); float final_slope = mylr.theta1; float theta0 = mylr.theta0; int64_t max_error_delta = INT64_MIN; int64_t min_error_delta = INT64_MAX; for (int j = origin_index;j <= end_index;j++) { int64_t tmp = array[j] - (long long)(theta0 + final_slope * (double)(j - origin_index)); if (tmp > max_error_delta) { max_error_delta = tmp; } if (tmp < min_error_delta) { min_error_delta = tmp; } } theta0 += (max_error_delta + min_error_delta) / 2.0; uint32_t final_max_error = 0; std::vector delta_final; std::vector signvec; for (int j = origin_index;j <= end_index;j++) { uint32_t tmp_val; int128_t pred = theta0 + final_slope * (double)(j - origin_index); if (array[j] > pred) { tmp_val = array[j] - pred; signvec.emplace_back(true); // means positive } else { tmp_val = pred - array[j]; signvec.emplace_back(false); // means negative } delta_final.emplace_back(tmp_val); if (tmp_val > final_max_error) { final_max_error = tmp_val; } } uint32_t delta_final_max_bit = 0; if(final_max_error){ delta_final_max_bit= bits_int_T(final_max_error) + 1; } if (delta_final_max_bit>=32){ delta_final_max_bit = 32; } memcpy(out, &origin_index, sizeof(origin_index)); out += sizeof(origin_index); out[0] = (uint8_t)delta_final_max_bit; out++; memcpy(out, &theta0, sizeof(theta0)); out += sizeof(theta0); memcpy(out, &final_slope, sizeof(final_slope)); out += sizeof(final_slope); if (delta_final_max_bit) { out = write_delta_int_T(delta_final, signvec, out, delta_final_max_bit, (end_index - origin_index + 1)); // out = write_delta_T(delta_final, out, delta_final_max_bit, (end_index - origin_index + 1)); } uint64_t segment_size = out - descriptor; descriptor = (uint8_t*)realloc(descriptor, segment_size); block_start.push_back(descriptor); segment_index.push_back(origin_index); segment_length.push_back(segment_size); total_byte += segment_size; return segment_size; } uint32_t newsegment_2(uint32_t origin_index, uint32_t end_index,std::vector& block_start) { // if(origin_index==1636 || origin_index+1 == 1636){ // std::cout<<"hello"<& block_start) { // if(origin_index == 1636){ // std::cout< > segment_start_index(length,std::vector()); std::vector > segment_cost(length,std::vector()); for(int i=0;i segment_cost_sum(length); for(int i=0;i