1#ifndef BMBMATRIX__H__INCLUDED__
2#define BMBMATRIX__H__INCLUDED__
328 template<
typename Val,
typename BVect,
unsigned MAX_SIZE>
350template<
typename Val,
typename BV,
unsigned MAX_SIZE>
421 {
bmatr_.swap_columns(idx1, idx2); }
434 {
return std::is_signed<value_type>::value; }
454 return bmatr_.get_row(null_idx);
469 {
bmatr_.set_allocator_pool(pool_ptr); }
475 {
return bmatr_.get_allocator_pool(); }
523 {
return bmatr_.get_row(i); }
528 return bmatr_.get_row(null_idx);
566 {
bmatr_.null_idx_ = null_idx; }
686 {
bmatr_.optimize_block(nb, opt_mode); }
713#pragma warning( push )
714#pragma warning( disable : 4146 )
853 bv->insert(idx,
false);
864 bv->clear_bit_no_check(idx);
874 bv->swap(idx1, idx2);
883 if (rsize <= rsize_prev)
896 for (
size_type i = 0; i < rsize_prev; ++i)
898 alloc_.free_ptr(bv_rows_prev,
unsigned(rsize_prev));
954 if (
bool(bv) !=
bool(bv_arg))
967 if (
pool_ != pool_ptr)
971 bv->set_allocator_pool(pool_ptr);
985 for (--i; i > 0; --i)
1011template<
typename BV>
1023template<
typename BV>
1033 bbm.alloc_ = alloc_tmp;
1041 bbm.pool_ = pool_tmp;
1048 bbm.bv_rows_ = rtmp;
1053template<
typename BV>
1071template<
typename BV>
1089template<
typename BV>
1102template<
typename BV>
1120template<
typename BV>
1129 BM_THROW(
false, BM_ERR_BADALLOC);
1148 rbv->set_allocator_pool(
pool_);
1154template<
typename BV>
1167template<
typename BV>
1173 return bv->get_blocks_manager().get_block_ptr(i, j);
1179template<
typename BV>
1181 unsigned slice_from,
unsigned slice_until,
1184 for (
unsigned p = slice_from; p < slice_until; ++p)
1186 bv->clear_bit_no_check(idx);
1192template<
typename BV>
1195 unsigned char octet)
1197 if (7u + octet_idx * 8u >
rsize_)
1202 for (;
row < row_end; ++
row)
1209 bv->set_bit_no_check(pos);
1214 bv->clear_bit_no_check(pos);
1226 bv->clear_bit_no_check(pos);
1231template<
typename BV>
1234 unsigned char octet)
1241 for (;
row < row_end; ++
row)
1249 bv->set_bit_no_check(pos);
1253 bv->insert(pos,
true);
1259 bv->insert(pos,
false);
1271 bv->insert(pos,
false);
1282 b1 = (blka[0] == FBADDR);
1283 b2 = (blka[1] == FBADDR);
1284 b1 |= (blka[2] == FBADDR);
1285 b2 |= (blka[3] == FBADDR);
1286 b1 |= (blka[4] == FBADDR);
1287 b2 |= (blka[5] == FBADDR);
1288 b1 |= (blka[6] == FBADDR);
1289 b2 |= (blka[7] == FBADDR);
1293template<
typename BV>
1304 unsigned row_idx = unsigned(octet_idx * 8);
1305 if (row_idx + 7 >=
rsize_ ||
1307 return (
unsigned char)v;
1329 if (
const bm::word_t* blk; (blk = blka[0])!=0)
1332 v |= (unsigned)
bool(is_set);
1334 if (
const bm::word_t* blk;(blk = blka[1])!=0)
1337 v |= unsigned(
bool(is_set)) << 1u;
1339 if (
const bm::word_t* blk;(blk = blka[2])!=0)
1342 v |= unsigned(
bool(is_set)) << 2u;
1344 if (
const bm::word_t* blk;(blk = blka[3])!=0)
1347 v |= unsigned(
bool(is_set)) << 3u;
1349 if (
const bm::word_t* blk;(blk = blka[4])!=0)
1352 v |= unsigned(
bool(is_set)) << 4u;
1354 if (
const bm::word_t* blk;(blk = blka[5])!=0)
1357 v |= unsigned(
bool(is_set)) << 5u;
1359 if (
const bm::word_t* blk;(blk = blka[6])!=0)
1362 v |= unsigned(
bool(is_set)) << 6u;
1364 if (
const bm::word_t* blk;(blk = blka[7])!=0)
1367 v |= unsigned(
bool(is_set)) << 7u;
1369 return (
unsigned char)v;
1373 if ((blk = blka[0])!=0)
1379 v |= (unsigned)
bool(is_set);
1381 if ((blk = blka[1])!=0)
1387 v |= unsigned(
bool(is_set)) << 1u;
1389 if ((blk = blka[2])!=0)
1395 v |= unsigned(
bool(is_set)) << 2u;
1397 if ((blk = blka[3])!=0)
1403 v |= unsigned(
bool(is_set)) << 3u;
1406 if ((blk = blka[4])!=0)
1412 v |= unsigned(
bool(is_set)) << 4u;
1414 if ((blk = blka[5])!=0)
1420 v |= unsigned(
bool(is_set)) << 5u;
1422 if ((blk = blka[6])!=0)
1428 v |= unsigned(
bool(is_set)) << 6u;
1430 if ((blk = blka[7])!=0)
1436 v |= unsigned(
bool(is_set)) << 7u;
1439 return (
unsigned char)v;
1444template<
typename BV>
1449 char value = char(
get_octet(pos, octet_idx));
1450 return (value > octet) - (value < octet);
1464 = uintptr_t(p0) | uintptr_t(p1) | uintptr_t(p2) | uintptr_t(p3);
1482template<
typename BV>
1509 if (!
test_4gaps(blka[0], blka[1], blka[2], blka[3]))
1511 if (
test_4bits(blka[0], blka[1], blka[2], blka[3]))
1513 v = unsigned(
bool((blka[0][nword] & mask0))) |
1514 unsigned(
bool((blka[1][nword] & mask0)) << 1u) |
1515 unsigned(
bool((blka[2][nword] & mask0)) << 2u) |
1516 unsigned(
bool((blka[3][nword] & mask0)) << 3u);
1524 if ((blk = blka[i])!=0)
1530 v |= unsigned(
bool(is_set)) << i;
1532 if ((blk = blka[++i])!=0)
1538 v |= unsigned(
bool(is_set)) << i;
1546template<
typename BV>
1558 for (
unsigned k = 0; k <
rsize_; ++k)
1564 bv->optimize(temp_block, opt_mode, st ? &stbv : 0);
1573template<
typename BV>
1576 for (
unsigned k = 0; k <
rsize_; ++k)
1583template<
typename BV>
1591 bv->calc_stat(&stbv);
1595 st.max_serialize_mem += 8;
1600template<
typename BV>
1602 typename BV::optmode opt_mode)
1604 for (
unsigned k = 0; k <
rsize_; ++k)
1611 bv->get_blocks_manager();
1612 bman.optimize_bit_block(i, j, opt_mode);
1624template<
class Val,
class BV,
unsigned MAX_SIZE>
1631template<
class Val,
class BV,
unsigned MAX_SIZE>
1642 size_type null_idx = (MAX_SIZE *
sizeof(Val) * 8);
1643 bmatr_.construct_row(null_idx)->init();
1644 bmatr_.set_null_idx(null_idx);
1651template<
class Val,
class BV,
unsigned MAX_SIZE>
1662template<
class Val,
class BV,
unsigned MAX_SIZE>
1671 bmatr_.null_idx_ = arg_null_idx;
1680 if (i && (i == arg_null_idx))
1685 bv->set_range(0,
size_-1);
1696 bmatr_.construct_row(i, *bv_src);
1704template<
class Val,
class BV,
unsigned MAX_SIZE>
1710 if (rows < arg_rows)
1713 bmatr_.allocate_rows(rows);
1720 bv_null_arg = bmatr.
get_row(null_idx);
1725 bv_null->merge(*bv_null_arg);
1727 if (rows > arg_rows)
1729 for (
unsigned j = 0; j < rows; ++j)
1732 if (arg_bv && arg_bv != bv_null_arg)
1743template<
class Val,
class BV,
unsigned MAX_SIZE>
1758template<
class Val,
class BV,
unsigned MAX_SIZE>
1766 bmatr_.clear_row(i, free_mem);
1769 bv_null->clear(
true);
1775template<
class Val,
class BV,
unsigned MAX_SIZE>
1783 auto planes =
bmatr_.rows();
1785 for (
unsigned i = 0; i < planes; ++i)
1789 bv->clear_range_no_check(left, right);
1791 if (set_null && bv_null)
1792 bv_null->clear_range_no_check(left, right);
1797template<
class Val,
class BV,
unsigned MAX_SIZE>
1811template<
class Val,
class BV,
unsigned MAX_SIZE>
1829template<
class Val,
class BV,
unsigned MAX_SIZE>
1834 return (bv_null) ? (!bv_null->test(idx)) :
false;
1839template<
class Val,
class BV,
unsigned MAX_SIZE>
1844 bv_null->insert(idx, not_null);
1849template<
class Val,
class BV,
unsigned MAX_SIZE>
1869template<
class Val,
class BV,
unsigned MAX_SIZE>
1875 const unsigned planes =
sizeof(
value_type) * 8;
1877 unsigned slice_size = (element_idx+1) * planes;
1878 if (slice_size > this->bmatr_.
rows())
1879 slice_size = (unsigned) this->bmatr_.
rows();
1880 for (
unsigned i = element_idx * planes; i < slice_size; ++i, ++bidx)
1881 mask |=
get_slice(i) ? (mask1 << bidx) : 0ull;
1887template<
class Val,
class BV,
unsigned MAX_SIZE>
1893 bmatr_.optimize(temp_block, opt_mode, &stbv);
1898 unsigned slices = (unsigned)this->bmatr_.
rows();
1899 for (
unsigned j = 0; j <
slices; ++j)
1902 if (bv && (bv != bv_null))
1917template<
class Val,
class BV,
unsigned MAX_SIZE>
1927 st->max_serialize_mem += 1 + 1 + 1 + 1 + 8 + (8 *
slices);
1928 st->max_serialize_mem += 1 + 8;
1933template<
class Val,
class BV,
unsigned MAX_SIZE>
1937 bmatr_.clear_column(idx, plane_idx);
1942template<
class Val,
class BV,
unsigned MAX_SIZE>
1946 bmatr_.insert_column(idx, plane_idx);
1951template<
class Val,
class BV,
unsigned MAX_SIZE>
1955 bmatr_.erase_column(idx, erase_null);
1960template<
class Val,
class BV,
unsigned MAX_SIZE>
1965 if (
size_type arg_size = sv.size(); this->size_ != arg_size)
1968 unsigned slices = (unsigned) this->bmatr_.
rows();
1969 unsigned arg_slices = (unsigned) sv.bmatr_.rows();
1970 unsigned max_slices(
slices);
1971 if (max_slices < arg_slices)
1972 max_slices = arg_slices;
1975 const bvector_type* bv_null_arg = sv.get_null_bvector();
1977 for (
unsigned j = 0; j < max_slices; ++j)
1983 arg_bv = (j < arg_slices) ? sv.bmatr_.get_row(j) : 0;
1986 if (arg_bv == bv_null_arg)
2005 bool eq = bv->equal(*arg_bv);
2013 if (bv_null == bv_null_arg)
2015 if (!bv_null || !bv_null_arg)
2020 bool eq = bv_null->equal(*bv_null_arg);
2029template<
class Val,
class BV,
unsigned MAX_SIZE>
2032 unsigned slices = (unsigned) this->bmatr_.
rows();
2033 for (
unsigned j = 0; j <
slices; ++j)
2048template<
class Val,
class BV,
unsigned MAX_SIZE>
2062 spli = this->bmatr_.
rows();
2064 bv_null->
copy_range(*bv_null_arg, left, right);
2068 spli = this->bmatr_.
rows();
2074 if (arg_bv == bv_null_arg)
2077 bv->copy_range(*arg_bv, left, right);
2085template<
class Val,
class BV,
unsigned MAX_SIZE>
2106template<
class Val,
class BV,
unsigned MAX_SIZE>
2123#pragma warning( pop )
Compressed bit-vector bvector<> container, set algebraic methods, traversal iterators.
#define BM_DECLARE_TEMP_BLOCK(x)
Constants, lookup tables and typedefs.
#define FULL_BLOCK_FAKE_ADDR
Utilities for bit transposition (internal) (experimental!).
void freeze_matr()
Turn on RO mode.
bvector_type_const_ptr get_slice(unsigned i) const BMNOEXCEPT
get read-only access to bit-plane
void swap(base_sparse_vector< Val, BV, MAX_SIZE > &bsv) BMNOEXCEPT
void resize(size_type new_size, bool set_null)
bm::null_support get_null_support() const BMNOEXCEPT
check if container supports NULL (unassigned) values
unsigned effective_slices() const BMNOEXCEPT
Number of effective bit-planes in the value type.
unsigned_value_type slice_mask_
const bvector_type * bvector_type_const_ptr
void merge_matr(bmatrix_type &bmatr)
Merge plane bvectors from an outside base matrix Note: outside base matrix gets destroyed.
static unsigned slices() BMNOEXCEPT
get total number of bit-planes in the vector
static value_type u2s(unsigned_value_type v) BMNOEXCEPT
Convert unsigned value type to signed representation.
bvector_type * bvector_type_ptr
const value_type & const_reference
const bvector_type * get_null_bvector() const BMNOEXCEPT
Get bit-vector of assigned values or NULL (if not constructed that way).
bvector_type_ptr slice(unsigned i) BMNOEXCEPT
get access to bit-plane as is (can return NULL)
void copy_from(const base_sparse_vector< Val, BV, MAX_SIZE > &bsv)
static unsigned_value_type s2u(value_type v) BMNOEXCEPT
Convert signed value type to unsigned representation.
bvector_type::allocation_policy allocation_policy_type
void set_allocator_pool(allocator_pool_type *pool_ptr) BMNOEXCEPT
Set allocation pool.
void clear_range(size_type left, size_type right, bool set_null)
bvector_type_ptr get_create_slice(unsigned i)
get access to bit-plain, function checks and creates a plane
size_type size() const BMNOEXCEPT
base_sparse_vector(const base_sparse_vector< Val, BV, MAX_SIZE > &bsv)
bool empty() const BMNOEXCEPT
void free_slice(unsigned i)
free memory in bit-plane
void optimize_block(block_idx_type nb, typename BV::optmode opt_mode)
plane index for the "NOT NULL" flags plane
unsigned effective_slices_
void erase_column(size_type idx, bool erase_null)
allocator_type::allocator_pool_type allocator_pool_type
base_sparse_vector(bm::null_support null_able, bool is_dynamic, allocation_policy_type ap=allocation_policy_type(), size_type bv_max_size=bm::id_max, const allocator_type &alloc=allocator_type())
void swap_elements(size_type idx1, size_type idx2)
swap two vector elements
allocator_pool_type * get_allocator_pool() const BMNOEXCEPT
Get allocation pool.
void copy_range_slices(const base_sparse_vector< Val, BV, MAX_SIZE > &bsv, typename base_sparse_vector< Val, BV, MAX_SIZE >::size_type left, typename base_sparse_vector< Val, BV, MAX_SIZE >::size_type right, bm::null_support slice_null)
base_sparse_vector(base_sparse_vector< Val, BV, MAX_SIZE > &&bsv) BMNOEXCEPT
bm::id64_t get_slice_mask(unsigned element_idx) const BMNOEXCEPT
static unsigned stored_slices() BMNOEXCEPT
Number of stored bit-planes (value planes + extra.
static constexpr unsigned value_bits() BMNOEXCEPT
Number of total bit-planes in the value type.
bool is_null(size_type idx) const BMNOEXCEPT
test if specified element is NULL
void bit_and_rows(const bvector_type &bv)
Set AND (intersect) operation on all existing bit-slices.
void keep_range_no_check(size_type left, size_type right, bm::null_support slice_null)
std::make_unsigned< value_type >::type unsigned_value_type
const bmatrix_type & get_bmatrix() const BMNOEXCEPT
bvector_type * get_null_bvect() BMNOEXCEPT
void mark_null_idx(unsigned null_idx) BMNOEXCEPT
Set NULL plain index.
bvector_type_const_ptr slice(unsigned i) const BMNOEXCEPT
bvector_type::enumerator bvector_enumerator_type
void sync_ro() BMNOEXCEPT
Sybc read-only state.
void bit_sub_rows(const bvector_type &bv, bool use_null)
Set SUB (MINUS) operation on all existing bit-slices.
void clear_all(bool free_mem=true) BMNOEXCEPT
resize to zero, free memory
bmatrix_type & get_bmatrix() BMNOEXCEPT
access to internal bit-matrix
bm::basic_bmatrix< BV > bmatrix_type
BV::allocator_type allocator_type
static constexpr bool is_signed() BMNOEXCEPT
returns true if value type is signed integral type
void optimize(bm::word_t *temp_block=0, typename bvector_type::optmode opt_mode=bvector_type::opt_compress, typename bvector_type::statistics *stat=0)
run memory optimization for all bit-vector rows
void insert_null(size_type idx, bool not_null)
void clear_value_planes_from(unsigned plane_idx, size_type idx)
void calc_stat(typename bvector_type::statistics *st) const BMNOEXCEPT
Calculates memory statistics.
bool is_nullable() const BMNOEXCEPT
check if container supports NULL(unassigned) values
bool equal(const base_sparse_vector< Val, BV, MAX_SIZE > &sv, bm::null_support null_able=bm::use_null) const BMNOEXCEPT
check if another sparse vector has the same content and size
void insert_clear_value_planes_from(unsigned plane_idx, size_type idx)
bvector_type::block_idx_type block_idx_type
Basic dense bit-matrix class.
void insert_octet(size_type pos, size_type octet_idx, unsigned char octet)
void insert_column(size_type idx, size_type row_from)
bvector_type::block_idx_type block_idx_type
void swap(basic_bmatrix< BV > &bbm) BMNOEXCEPT
~basic_bmatrix() BMNOEXCEPT
bvector_type * bvector_type_ptr
bvector_type_ptr * bv_rows_
void swap_columns(size_type idx1, size_type idx2)
bool is_dynamic_
if rsize is dynamic (variable length)
void set_allocator_pool(allocator_pool_type *pool_ptr) BMNOEXCEPT
void set_null_idx(size_type null_idx) BMNOEXCEPT
set index of the NULL vector
bvector_type_ptr construct_row(size_type row)
unsigned get_half_octet(size_type pos, size_type row_idx) const BMNOEXCEPT
BV::allocator_type allocator_type
bvector_type::allocation_policy allocation_policy_type
size_type null_idx_
Index of the NULL row.
allocator_type::allocator_pool_type allocator_pool_type
size_type get_null_idx() const BMNOEXCEPT
return index of the NULL vector
void destruct_row(size_type row)
const bvector_type * bvector_type_const_ptr
bvector_type * construct_bvector(const bvector_type *bv) const
const bm::word_t * get_block(size_type p, unsigned i, unsigned j) const BMNOEXCEPT
Get low level internal access to.
void bit_and_rows(const bvector_type &bv)
Set AND (intersect) operation on all existing rows.
basic_bmatrix< BV > & operator=(const basic_bmatrix< BV > &bbm)
void calc_stat(typename bvector_type::statistics &st, size_type rsize) const BMNOEXCEPT
int compare_octet(size_type pos, size_type octet_idx, char octet) const BMNOEXCEPT
size_type rows_not_null() const BMNOEXCEPT
allocator_pool_type * pool_
allocator_pool_type * get_allocator_pool() const BMNOEXCEPT
void copy_from(const basic_bmatrix< BV > &bbm)
bool is_same_structure(const basic_bmatrix< BV > &bbm) const BMNOEXCEPT
Debugging function to check if two matrixes have the same rows created.
static void throw_bad_alloc()
void optimize(bm::word_t *temp_block=0, typename bvector_type::optmode opt_mode=bvector_type::opt_compress, typename bvector_type::statistics *stat=0)
run memory optimization for all bit-vector rows
void clear_slices_range(unsigned slice_from, unsigned slize_until, size_type idx)
Clear bit-planes bit.
void clear_column(size_type idx, size_type row_from)
void clear_row(size_type row, bool free_mem)
bool is_dynamic() const BMNOEXCEPT
Return if matrix is dynamic resizable.
const bvector_type * row(size_type i) const BMNOEXCEPT
void allocate_rows(size_type rsize)
allocate matrix rows of bit-vectors (new rows are NULLs)
void optimize_block(block_idx_type nb, typename BV::optmode opt_mode)
allocation_policy_type ap_
size_type rows() const BMNOEXCEPT
void destruct_bvector(bvector_type *bv) const
size_type calc_effective_rows_not_null() const BMNOEXCEPT
void set_octet(size_type pos, size_type octet_idx, unsigned char octet)
void erase_column(size_type idx, bool erase_null)
basic_bmatrix(size_type rsize, bool is_dynamic=true, allocation_policy_type ap=allocation_policy_type(), size_type bv_max_size=bm::id_max, const allocator_type &alloc=allocator_type())
void bit_sub_rows(const bvector_type &bv, bool use_null)
Set SUB (MINUS) operation on all existing rows.
size_type octet_size() const BMNOEXCEPT
void free_rows() BMNOEXCEPT
Free all rows.
friend class base_sparse_vector
unsigned char get_octet(size_type pos, size_type octet_idx) const BMNOEXCEPT
bvector_type::size_type size_type
bvector_type_const_ptr get_row(size_type i) const BMNOEXCEPT
Constant iterator designed to enumerate "ON" bits.
optmode
Optimization mode Every next level means additional checks (better compression vs time).
@ opt_compress
compress blocks when possible (GAP/prefix sum)
blocks_manager< Alloc > blocks_manager_type
bvector_size_type size_type
void init()
Explicit post-construction initialization. Must be caled to make sure safe use of *_no_check() method...
void copy_range(const bvector< Alloc > &bvect, size_type left, size_type right)
Copy all bits in the specified closed interval [left,right].
blocks_manager_type::block_idx_type block_idx_type
null_support
NULL-able value support.
@ use_null
support "non-assigned" or "NULL" logic
@ no_null
do not support NULL values
unsigned gap_test_unr(const T *BMRESTRICT buf, const unsigned pos) BMNOEXCEPT
Tests if bit = pos is true. Analog of bm::gap_test with SIMD unrolling.
bool test_4bits(const bm::word_t *p0, const bm::word_t *p1, const bm::word_t *p2, const bm::word_t *p3) BMNOEXCEPT
Test 4 pointers are not NULL and not marked as FULLBLOCK.
const unsigned set_block_mask
BMFORCEINLINE void get_block_coord(BI_TYPE nb, unsigned &i, unsigned &j) BMNOEXCEPT
Recalc linear bvector block index into 2D matrix coordinates.
bool check_any_fullb(const bm::word_t *blka[8], const bm::word_t *FBADDR)
const unsigned set_word_shift
BMFORCEINLINE void xor_swap(W &x, W &y) BMNOEXCEPT
XOR swap two variables.
unsigned long long int id64_t
const unsigned set_block_shift
const unsigned set_word_mask
bool test_4gaps(const bm::word_t *p0, const bm::word_t *p1, const bm::word_t *p2, const bm::word_t *p3) BMNOEXCEPT
Test 4 pointers are all marked as GAPs.
void reset() BMNOEXCEPT
Reset statisctics.
void add(const bv_statistics &st) BMNOEXCEPT
Sum data from another sttructure.
Statistical information about bitset's memory allocation details.
static TBVector * construct_bvector()