#include <iostream>
#include <vector>
#include <chrono>
#include <algorithm>
#include <random>
#include <stdexcept>
#include "bm.h"
#include "bmsparsevec.h"
#include "bmsparsevec_algo.h"
#include "bmtimer.h"
#include "bmundef.h"
using namespace std;
typedef bm::sparse_vector<bm::id_t, bm::bvector<> > sparse_vector_u32;
const unsigned value_max = 1250000; const unsigned test_size = 250000000;
std::random_device rand_dev;
std::mt19937 gen(rand_dev());
std::uniform_int_distribution<> rand_dis(1, value_max);
bm::chrono_taker::duration_map_type timing_map;
static
void generate_test_set(std::vector<unsigned>& vect,
bm::bvector<>& bv_null,
sparse_vector_u32& sv)
{
sparse_vector_u32::back_insert_iterator bi(sv.get_back_inserter());
vect.resize(test_size);
bv_null.reset();
for (unsigned i = 0; i < test_size; ++i)
{
unsigned v = unsigned(rand_dis(gen));
vect[i] = v;
bv_null[i] = true;
*bi = v;
if (i % 64 == 0)
{
bi.add_null(5); i += 5; }
} }
static
void vector_search(const std::vector<unsigned>& vect,
const bm::bvector<>& bv_null,
unsigned value,
bm::bvector<>& bv_res)
{
bv_res.init(); for (size_t i = 0; i < vect.size(); ++i)
{
if (vect[i] == value)
bv_res.set_bit_no_check((bm::id_t)i);
} bv_res &= bv_null; }
inline
void print_bvector(const bm::bvector<>& bv)
{
cout << "( count = " << bv.count() << ")" << ": [";
bm::bvector<>::enumerator en = bv.first();
for (; en.valid(); ++en)
cout << *en << ", ";
cout << "]" << endl;
}
int main(void)
{
try
{
{
sparse_vector_u32 sv(bm::use_null);
sv.set(2, 25);
sv.set(3, 35);
sv.set(7, 75);
sv.set(1000, 2000);
sv.set(256, 2001);
sv.set(77, 25);
bm::bvector<> bv_found;
bm::sparse_vector_scanner<sparse_vector_u32> scanner; scanner.find_eq(sv, 25, bv_found);
print_bvector(bv_found);
scanner.invert(sv, bv_found); print_bvector(bv_found); }
std::vector<unsigned> vect;
bm::bvector<> bv_null;
sparse_vector_u32 sv(bm::use_null);
{
bm::chrono_taker tt1("0. test set generate ", 1, &timing_map);
generate_test_set(vect, bv_null, sv);
}
unsigned search_repeats = 500;
std::vector<unsigned> search_vect;
{
bm::bvector<> bv_tmp;
search_vect.reserve(search_repeats);
for (unsigned i = 0; i < search_repeats;)
{
bm::id_t idx = bm::id_t(rand_dis(gen));
if (!bv_tmp.test(idx)) {
search_vect.push_back(idx);
bv_tmp[idx] = 1;
++i;
}
}
}
bm::bvector<> bv_res1;
bm::bvector<> bv_res2;
bm::bvector<> bv_res3;
{
bm::chrono_taker tt1("1. std::vector<> scan ", search_repeats, &timing_map);
for (unsigned i = 0; i < search_repeats; ++i)
{
unsigned vs = search_vect[i];
vector_search(vect, bv_null, vs, bv_res1);
} }
{
bm::chrono_taker tt1("2. sparse_vector<> scan ", search_repeats, &timing_map);
bm::sparse_vector_scanner<sparse_vector_u32> scanner;
scanner.find_eq(sv, search_vect.begin(), search_vect.end(), bv_res2);
}
if (bv_res1.compare(bv_res2) != 0)
{
std::cerr << "2. Search result mismatch!" << std::endl;
}
{
bv_res3.init();
bm::chrono_taker tt1("3. sparse_vector<>::const_iterator search ", search_repeats, &timing_map);
bm::bvector<> bv_search(bm::BM_GAP);
bm::combine_or(bv_search, search_vect.begin(), search_vect.end());
sparse_vector_u32::const_iterator it = sv.begin();
sparse_vector_u32::const_iterator it_end = sv.end();
for (; it != it_end; ++it)
{
unsigned v = *it;
if (bv_search.test(v))
{
bv_res3.set_bit_no_check(it.pos());
}
} }
if (bv_res1.compare(bv_res3) != 0)
{
std::cerr << "3. Search result mismatch!" << std::endl;
}
bm::chrono_taker::print_duration_map(timing_map, bm::chrono_taker::ct_ops_per_sec);
}
catch(std::exception& ex)
{
std::cerr << ex.what() << std::endl;
return 1;
}
return 0;
}