#ifndef PIECEWISE_FIX_MERGE_H_ #define PIECEWISE_FIX_MERGE_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 piecewise_fix_merge : public IntegerCODEC { public: using IntegerCODEC::encodeArray; using IntegerCODEC::decodeArray; using IntegerCODEC::randomdecodeArray; using IntegerCODEC::encodeArray8; using IntegerCODEC::decodeArray8; using IntegerCODEC::randomdecodeArray8; using IntegerCODEC::init; std::vector block_start_vec; std::vector segment_index; std::vector segment_length; uint64_t total_byte = 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 = 18; uint32_t* array; 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 } 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[m]) y = m - 1; else x = m + 1; } return y; } void newsegment(uint32_t origin_index, uint32_t end_index) { uint8_t* descriptor = (uint8_t*)malloc((end_index - origin_index + 1) * sizeof(uint64_t)*2); uint8_t* out = descriptor; int length = end_index - origin_index + 1; std::vector indexes; std::vector keys; for (int j = origin_index;j <= end_index;j++) { indexes.emplace_back(j - origin_index); keys.emplace_back(array[j]); } lr mylr; mylr.caltheta(indexes, keys, length); double final_slope = mylr.theta1; double theta0 = mylr.theta0; uint32_t final_max_error = 0; int* delta_final = new int[end_index - origin_index + 1]; for (int j = origin_index;j <= end_index;j++) { // long long pred = theta0 + (float)(j - origin_index) * final_slope; long long pred = (long long)(theta0 + final_slope * (double)(j - origin_index)); uint32_t tmp_error = abs(pred - (long long)array[j]); delta_final[j - origin_index] = (long long)array[j] - pred; if (tmp_error > final_max_error) { final_max_error = tmp_error; } } uint32_t 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==32){ out = write_delta_default(array+origin_index, out,delta_final_max_bit, end_index - origin_index + 1); } else{ out = write_delta_T(delta_final, out, delta_final_max_bit, (end_index - origin_index + 1)); } // if(1636>=origin_index && 1636<=end_index){ // std::cout<<"("< block_interval * nvalue){ nvalue++; } for(int i=0;i0){ iter++; cost_decline = total_byte; merge(); compressrate = (total_byte) * 100.0 / (4 * block_size * 1.0); std::cout << "try "< new_block_start_vec; std::vector new_segment_index; std::vector new_segment_length; while(segment_num < total_segments){ // std::cout<<"segment_num: "<merge_cost){ // merge the two segments // new_block_start_vec.emplace_back(std::unique_ptr(block_start_vec[total_segments+newsegment_num])); // std::cout<<"merge "<(block_start_vec[segment_num]))); new_segment_index.emplace_back(segment_index[segment_num]); new_segment_length.emplace_back(segment_length[segment_num]); totalbyte_after_merge += segment_length[segment_num]; start_index=segment_index[segment_num+1]; segment_num++; newsegment_num++; } } block_start_vec.swap(new_block_start_vec); segment_index.swap(new_segment_index); segment_length.swap(new_segment_length); total_byte = totalbyte_after_merge; // std::cout<