#include <iostream>
#include <vector>
#include <cassert>
#include "bm.h"
#include "bmsparsevec.h"
#include "bmsparsevec_compr.h"
#include "bmsparsevec_serial.h"
using namespace std;
typedef bm::bvector<> bvector_type;
typedef bm::sparse_vector<unsigned short, bvector_type> sparse_vector_u16;
typedef bm::sparse_vector<unsigned, bvector_type> sparse_vector_u32;
typedef bm::rsc_sparse_vector<unsigned, sparse_vector_u32 > rsc_sparse_vector_u32;
typedef bm::sparse_vector_serializer<rsc_sparse_vector_u32> csv_serializer_type;
typedef bm::sparse_vector_serializer<sparse_vector_u16> sv16_serializer_type;
typedef bm::sparse_vector_deserializer<rsc_sparse_vector_u32> csv_deserializer_type;
typedef bm::sparse_vector_deserializer<sparse_vector_u16> sv16_deserializer_type;
struct sample_data_frame
{
rsc_sparse_vector_u32 csv1;
rsc_sparse_vector_u32 csv2;
rsc_sparse_vector_u32 csv3;
sparse_vector_u16 sv0;
sample_data_frame()
: sv0(bm::use_null)
{}
};
inline
size_t raw_data_size(const sample_data_frame& df)
{
size_t sz = 0;
if (df.csv1.size())
sz += df.csv1.size() * sizeof(df.csv1.get(0));
if (df.csv2.size())
sz += df.csv2.size() * sizeof(df.csv2.get(0));
if (df.csv3.size())
sz += df.csv3.size() * sizeof(df.csv3.get(0));
if (df.sv0.size())
sz += df.sv0.size() * sizeof(df.sv0.get(0));
return sz;
}
static
void fill_test_data(sample_data_frame& df)
{
for (unsigned i = 0; i < 65536; i+=7)
{
df.csv1.set(i, 4);
df.csv2.set(i, 8);
df.csv3.set(i, 17);
df.sv0.set(i, i % 256);
}
df.csv1.sync();
df.csv2.sync();
df.csv3.sync();
}
static
void test_data(sample_data_frame& df)
{
for (unsigned i = 0; i < 65536; i+=7)
{
auto v1 = df.csv1.get(i);
assert(v1 == 4); (void)v1;
auto v2 = df.csv2.get(i);
assert(v2 == 8); (void)v2;
auto v3 = df.csv3.get(i);
assert(v3 == 17); (void)v3;
auto v0 = df.sv0.get(i);
assert(v0 == i % 256); (void)v0;
}
}
template<typename SVLay>
unsigned char* copy_buffer(unsigned char* buf_ptr, const SVLay& sv_lay)
{
auto s = sv_lay.size();
::memcpy(buf_ptr, sv_lay.buf(), s);
return buf_ptr + s;
}
static
void serialize_df0(const sample_data_frame& df,
std::vector<unsigned char>& buf,
csv_serializer_type& csv_ser,
sv16_serializer_type& sv16_ser)
{
csv_ser.set_xor_ref(false);
bm::sparse_vector_serial_layout<rsc_sparse_vector_u32> sv_lay1, sv_lay2, sv_lay3;
bm::sparse_vector_serial_layout<sparse_vector_u16> sv_lay0;
csv_ser.serialize(df.csv1, sv_lay1);
csv_ser.serialize(df.csv2, sv_lay2);
csv_ser.serialize(df.csv3, sv_lay3);
sv16_ser.serialize(df.sv0, sv_lay0);
size_t sz = (sizeof(size_t) * 3) +
sv_lay1.size() + sv_lay2.size() + sv_lay3.size() + sv_lay0.size();
buf.resize(sz);
unsigned char* buf_ptr = buf.data();
{
auto s = sv_lay1.size();
::memcpy(buf_ptr, &s, sizeof(s));
buf_ptr += sizeof(s);
}
{
auto s = sv_lay2.size();
::memcpy(buf_ptr, &s, sizeof(s));
buf_ptr += sizeof(s);
}
{
auto s = sv_lay3.size();
::memcpy(buf_ptr, &s, sizeof(s));
buf_ptr += sizeof(s);
}
{
auto s = sv_lay0.size();
::memcpy(buf_ptr, &s, sizeof(s));
buf_ptr += sizeof(s);
}
buf_ptr = copy_buffer(buf_ptr, sv_lay1);
buf_ptr = copy_buffer(buf_ptr, sv_lay2);
buf_ptr = copy_buffer(buf_ptr, sv_lay3);
buf_ptr = copy_buffer(buf_ptr, sv_lay0);
}
static
void deserialize_df0(sample_data_frame& df,
const std::vector<unsigned char>& buf,
csv_deserializer_type& csv_dser,
sv16_deserializer_type& sv16_dser)
{
assert(buf.size() > sizeof(size_t)*3);
size_t sz1, sz2, sz3, sz0;
const unsigned char* data_ptr = buf.data();
::memcpy(&sz1, data_ptr, sizeof(size_t));
data_ptr += sizeof(size_t);
::memcpy(&sz2, data_ptr, sizeof(size_t));
data_ptr += sizeof(size_t);
::memcpy(&sz3, data_ptr, sizeof(size_t));
data_ptr += sizeof(size_t);
::memcpy(&sz0, data_ptr, sizeof(size_t));
data_ptr += sizeof(size_t);
csv_dser.deserialize(df.csv1, data_ptr);
data_ptr += sz1;
csv_dser.deserialize(df.csv2, data_ptr);
data_ptr += sz2;
csv_dser.deserialize(df.csv3, data_ptr);
data_ptr += sz3;
sv16_dser.deserialize(df.sv0, data_ptr);
data_ptr += sz0;
}
static
void serialize_df2(const sample_data_frame& df,
std::vector<unsigned char>& buf,
csv_serializer_type& csv_ser,
sv16_serializer_type& sv16_ser)
{
try
{
csv_serializer_type::bv_ref_vector_type bv_ref;
bv_ref.add_sparse_vector(df.sv0); bv_ref.add_sparse_vector(df.csv3);
bv_ref.add_sparse_vector(df.csv2);
bv_ref.add_sparse_vector(df.csv1);
csv_ser.set_xor_ref(&bv_ref); sv16_ser.set_xor_ref(&bv_ref);
bm::xor_sim_params x_params;
csv_serializer_type::xor_sim_model_type sim_model;
csv_ser.compute_sim_model(sim_model, bv_ref, x_params);
csv_ser.set_sim_model(&sim_model);
sv16_ser.set_sim_model(&sim_model);
bm::sparse_vector_serial_layout<rsc_sparse_vector_u32> sv_lay1, sv_lay2, sv_lay3;
bm::sparse_vector_serial_layout<sparse_vector_u16> sv_lay0;
csv_ser.serialize(df.csv1, sv_lay1);
csv_ser.serialize(df.csv2, sv_lay2);
csv_ser.serialize(df.csv3, sv_lay3);
sv16_ser.serialize(df.sv0, sv_lay0);
size_t sz = (sizeof(size_t) * 4) +
sv_lay1.size() + sv_lay2.size() + sv_lay3.size() + sv_lay0.size();
buf.resize(sz);
unsigned char* buf_ptr = buf.data();
{
auto s = sv_lay1.size();
::memcpy(buf_ptr, &s, sizeof(s));
buf_ptr += sizeof(s);
}
{
auto s = sv_lay2.size();
::memcpy(buf_ptr, &s, sizeof(s));
buf_ptr += sizeof(s);
}
{
auto s = sv_lay3.size();
::memcpy(buf_ptr, &s, sizeof(s));
buf_ptr += sizeof(s);
}
{
auto s = sv_lay0.size();
::memcpy(buf_ptr, &s, sizeof(s));
buf_ptr += sizeof(s);
}
buf_ptr = copy_buffer(buf_ptr, sv_lay1);
buf_ptr = copy_buffer(buf_ptr, sv_lay2);
buf_ptr = copy_buffer(buf_ptr, sv_lay3);
buf_ptr = copy_buffer(buf_ptr, sv_lay0);
csv_ser.set_xor_ref(nullptr);
sv16_ser.set_xor_ref(nullptr);
}
catch (...)
{
csv_ser.set_xor_ref(nullptr);
sv16_ser.set_xor_ref(nullptr);
throw;
}
}
static
void deserialize_df2(sample_data_frame& df,
const std::vector<unsigned char>& buf,
csv_deserializer_type& csv_dser,
sv16_deserializer_type& sv16_dser)
{
assert(buf.size() > sizeof(size_t)*3);
try
{
size_t sz1, sz2, sz3, sz0;
const unsigned char* data_ptr = buf.data();
::memcpy(&sz1, data_ptr, sizeof(size_t));
data_ptr += sizeof(size_t);
::memcpy(&sz2, data_ptr, sizeof(size_t));
data_ptr += sizeof(size_t);
::memcpy(&sz3, data_ptr, sizeof(size_t));
data_ptr += sizeof(size_t);
::memcpy(&sz0, data_ptr, sizeof(size_t));
data_ptr += sizeof(size_t);
bm::sparse_vector_deserializer<rsc_sparse_vector_u32>::bv_ref_vector_type bv_ref;
csv_dser.deserialize_structure(df.csv1, data_ptr);
data_ptr += sz1;
csv_dser.deserialize_structure(df.csv2, data_ptr);
data_ptr += sz2;
csv_dser.deserialize_structure(df.csv3, data_ptr);
data_ptr += sz3;
sv16_dser.deserialize_structure(df.sv0, data_ptr);
data_ptr += sz0;
bv_ref.add_vectors(df.sv0.get_bmatrix()); bv_ref.add_vectors(df.csv3.get_bmatrix());
bv_ref.add_vectors(df.csv2.get_bmatrix());
bv_ref.add_vectors(df.csv1.get_bmatrix());
csv_dser.set_xor_ref(&bv_ref);
sv16_dser.set_xor_ref(&bv_ref);
data_ptr = buf.data() + (4 * sizeof(size_t));
csv_dser.deserialize(df.csv1, data_ptr, false);
data_ptr += sz1;
csv_dser.deserialize(df.csv2, data_ptr, false);
data_ptr += sz2;
csv_dser.deserialize(df.csv3, data_ptr, false);
data_ptr += sz3;
sv16_dser.deserialize(df.sv0, data_ptr, false);
data_ptr += sz0;
csv_dser.set_xor_ref(nullptr);
sv16_dser.set_xor_ref(nullptr);
}
catch (...)
{
csv_dser.set_xor_ref(nullptr);
sv16_dser.set_xor_ref(nullptr);
throw;
}
}
int main(void)
{
try
{
std::vector<unsigned char> buf0, buf2;
{
sample_data_frame df1; fill_test_data(df1); test_data(df1);
size_t raw_size = raw_data_size(df1);
cout << "raw size: " << raw_size << endl;
csv_serializer_type csv_ser;
sv16_serializer_type sv16_ser;
serialize_df0(df1, buf0, csv_ser, sv16_ser);
cout << "Plain serializarion: " << buf0.size() << endl;
serialize_df2(df1, buf2, csv_ser, sv16_ser);
cout << "XOR data frame serialization: " << buf2.size() << endl;
}
csv_deserializer_type csv_dser;
sv16_deserializer_type sv16_dser;
{
sample_data_frame df0;
deserialize_df0(df0, buf0, csv_dser, sv16_dser);
test_data(df0); }
{
sample_data_frame df2;
deserialize_df2(df2, buf2, csv_dser, sv16_dser);
test_data(df2);
}
}
catch(std::exception& ex)
{
std::cerr << ex.what() << std::endl;
return 1;
}
return 0;
}