BitMagic-C++
bmbmatrix.h
Go to the documentation of this file.
1#ifndef BMBMATRIX__H__INCLUDED__
2#define BMBMATRIX__H__INCLUDED__
3/*
4Copyright(c) 2002-2017 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
5
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17
18For more information please visit: http://bitmagic.io
19*/
20
21/*! \file bmbmatrix.h
22 \brief basic bit-matrix class and utilities
23*/
24
25#include <stddef.h>
26#include <type_traits>
27
28#include "bmconst.h"
29
30#ifndef BM_NO_STL
31#include <stdexcept>
32#endif
33
34#include "bm.h"
35#include "bmtrans.h"
36#include "bmdef.h"
37
38
39
40namespace bm
41{
42
43/**
44 Basic dense bit-matrix class.
45
46 Container of row-major bit-vectors, forming a bit-matrix.
47 This class uses dense form of row storage.
48 It is applicable as a build block for other sparse containers and
49 succinct data structures, implementing high level abstractions.
50
51 @ingroup bmagic
52 @internal
53*/
54template<typename BV>
56{
57public:
58 typedef BV bvector_type;
61 typedef typename BV::allocator_type allocator_type;
63 typedef typename allocator_type::allocator_pool_type allocator_pool_type;
66 typedef unsigned char octet_type;
67
68public:
69 // ------------------------------------------------------------
70 /*! @name Construction, assignment */
71 ///@{
72
74 bool is_dynamic = true,
76 size_type bv_max_size = bm::id_max,
77 const allocator_type& alloc = allocator_type());
79
80 /*! copy-ctor */
81 basic_bmatrix(const basic_bmatrix<BV>& bbm);
82 basic_bmatrix<BV>& operator=(const basic_bmatrix<BV>& bbm)
83 {
84 copy_from(bbm);
85 return *this;
86 }
87
88#ifndef BM_NO_CXX11
89 /*! move-ctor */
91
92 /*! move assignmment operator */
94 {
95 if (this != &bbm)
96 {
97 free_rows();
98 swap(bbm);
99 }
100 return *this;
101 }
102
103#endif
104
108
109 ///@}
110
111 // ------------------------------------------------------------
112 /*! @name content manipulation */
113 ///@{
114
115 /*! Swap content */
117
118 /*! Copy content */
119 void copy_from(const basic_bmatrix<BV>& bbm);
120
121 /*! Freeze content into read-only mode drop editing overhead */
122 void freeze();
123
124 ///@}
125
126 // ------------------------------------------------------------
127 /*! @name row access */
128 ///@{
129
130 /*! Get row bit-vector. Can return NULL */
131 const bvector_type* row(size_type i) const BMNOEXCEPT;
132
133 /*! Get row bit-vector. Can return NULL */
135
136 /*! Get row bit-vector. Can return NULL */
138
139 /*! get number of value rows */
140 size_type rows() const BMNOEXCEPT { return rsize_; }
141
142 /*! get number of value rows without (not) NULLs bvector */
144
145 /*! get number of assigned avlue rows without \ NULLs bvector */
147
148
149 /*! Make sure row is constructed, return bit-vector */
151
152 /*! Make sure row is copy-constructed, return bit-vector */
154
155 /*! destruct/deallocate row */
157
158 /*! clear row bit-vector */
159 void clear_row(size_type row, bool free_mem);
160
161 /** return index of the NULL vector */
163
164 /** set index of the NULL vector */
165 void set_null_idx(size_type null_idx) BMNOEXCEPT;
166
167 /** allocate matrix rows of bit-vectors (new rows are NULLs) */
168 void allocate_rows(size_type rsize);
169
170 /** Free all rows */
171 void free_rows() BMNOEXCEPT;
172
173 ///@}
174
175
176 // ------------------------------------------------------------
177 /*! @name octet access and transposition */
178 ///@{
179
180 /*!
181 Bit-transpose an octet and assign it to a bit-matrix
182
183 @param pos - column position in the matrix
184 @param octet_idx - octet based row position (1 octet - 8 rows)
185 @param octet - value to assign
186 */
187 void set_octet(size_type pos, size_type octet_idx, unsigned char octet);
188
189 /*!
190 Bit-transpose and insert an octet and assign it to a bit-matrix
191
192 @param pos - column position in the matrix
193 @param octet_idx - octet based row position (1 octet - 8 rows)
194 @param octet - value to assign
195 */
196 void insert_octet(size_type pos, size_type octet_idx, unsigned char octet);
197
198 /*!
199 return octet from the matrix
200
201 @param pos - column position in the matrix
202 @param octet_idx - octet based row position (1 octet - 8 rows)
203 */
204 unsigned char get_octet(size_type pos, size_type octet_idx) const BMNOEXCEPT;
205
206 /*!
207 Compare vector[pos] with octet
208
209 It uses regulat comparison of chars to comply with the (signed)
210 char sort order.
211
212 @param pos - column position in the matrix
213 @param octet_idx - octet based row position (1 octet - 8 rows)
214 @param octet - octet value to compare
215
216 @return 0 - equal, -1 - less(vect[pos] < octet), 1 - greater
217 */
218 int compare_octet(size_type pos,
219 size_type octet_idx, char octet) const BMNOEXCEPT;
220
221 /*!
222 Return number of octet currently allocated rows in the matrix
223 */
225
226 ///@}
227
228
229 // ------------------------------------------------------------
230 /*! @name Utility functions */
231 ///@{
232
233
234 /// Get low level internal access to
235 const bm::word_t* get_block(size_type p,
236 unsigned i, unsigned j) const BMNOEXCEPT;
237
238 /**
239 Clear bit-planes bit
240 @param slice_from - clear from [from, until)
241 @param slice_until - clear until (open interval!)
242 @param idx - bit index
243 */
244 void clear_slices_range(unsigned slice_from, unsigned slize_until,
245 size_type idx);
246
247 unsigned get_half_octet(size_type pos, size_type row_idx) const BMNOEXCEPT;
248
249 /*!
250 \brief run memory optimization for all bit-vector rows
251 \param temp_block - pre-allocated memory block to avoid re-allocs
252 \param opt_mode - requested compression depth
253 \param stat - memory allocation statistics after optimization
254 */
255 void optimize(
256 bm::word_t* temp_block = 0,
257 typename bvector_type::optmode opt_mode = bvector_type::opt_compress,
258 typename bvector_type::statistics* stat = 0);
259
260 /*! Optimize block in all planes
261 @internal
262 */
263 void optimize_block(block_idx_type nb, typename BV::optmode opt_mode);
264
265 /*! Compute memory statistics
266 @param st [out] - statistics object
267 @param rsize - row size (for cases when operation is limited not to touch the NULL bit-vector)
268 */
269 void calc_stat(typename bvector_type::statistics& st,
270 size_type rsize) const BMNOEXCEPT;
271
272 /*! Erase column/element
273 @param idx - index (of column) / element of bit-vectors to erase
274 @param erase_null - erase all including NULL vector (true)
275 */
276 void erase_column(size_type idx, bool erase_null);
277
278 /*! Insert value 0 into a range of rows
279 @param idx - index (of column) / element of bit-vectors to erase
280 @param row_from - row to start from
281 */
282 void insert_column(size_type idx, size_type row_from);
283
284 /*! Clear value (set 0) into a range of rows
285 @param idx - index (of column) / element of bit-vectors
286 @param row_from - row to start from
287 */
288 void clear_column(size_type idx, size_type row_from);
289
290 /*! Swap columns (bits in all rows)
291 @param idx1 - column index 1
292 @param idx2 - column index 2
293 */
294 void swap_columns(size_type idx1, size_type idx2);
295
296 /**
297 Set SUB (MINUS) operation on all existing rows
298 @param bv - argument vector row[i] -= bv
299 @param use_null - if true clear the NULL vector as well
300 */
301 void bit_sub_rows(const bvector_type& bv, bool use_null);
302
303 /**
304 Set AND (intersect) operation on all existing rows
305 @param bv - argument vector row[i] &= bv
306 */
307 void bit_and_rows(const bvector_type& bv);
308
309 /// Return if matrix is dynamic resizable
310 bool is_dynamic() const BMNOEXCEPT { return is_dynamic_; }
311
312
313 /// Debugging function to check if two matrixes have the same rows created
314 /// @return true - if the same
315 ///
316 bool is_same_structure(const basic_bmatrix<BV>& bbm) const BMNOEXCEPT;
317
318 ///@}
319
320protected:
321
323 void destruct_bvector(bvector_type* bv) const;
324
325 static
326 void throw_bad_alloc() { BV::throw_bad_alloc(); }
327
328 template<typename Val, typename BVect, unsigned MAX_SIZE>
329 friend class base_sparse_vector;
330
331protected:
336
339 bool is_dynamic_ = true; ///< if rsize is dynamic (variable length)
340 size_type null_idx_ = 0; ///< Index of the NULL row
341};
342
343/**
344 Base class for bit-transposed(bit-sliced) sparse vector construction.
345 Keeps the basic housekeeping lements like matrix of sparse elements
346
347 @ingroup bmagic
348 @internal
349*/
350template<typename Val, typename BV, unsigned MAX_SIZE>
352{
353public:
355 {
356 sv_slices = (sizeof(Val) * 8 * MAX_SIZE + 1),
357 sv_value_slices = (sizeof(Val) * 8 * MAX_SIZE)
358 };
359
361 {
363 };
364
365 typedef Val value_type;
366 typedef BV bvector_type;
367 typedef typename BV::size_type size_type;
371 typedef typename BV::allocator_type allocator_type;
374 typedef typename allocator_type::allocator_pool_type allocator_pool_type;
376 typedef typename std::make_unsigned<value_type>::type unsigned_value_type;
377
378public:
380
382 bool is_dynamic,
384 size_type bv_max_size = bm::id_max,
385 const allocator_type& alloc = allocator_type());
386
388
389#ifndef BM_NO_CXX11
390 /*! move-ctor */
392 {
393 bmatr_.swap(bsv.bmatr_);
394 size_ = bsv.size_;
395 effective_slices_ = bsv.effective_slices_;
396 bsv.size_ = 0;
397 }
398#endif
399
401
402 size_type size() const BMNOEXCEPT { return size_; }
403
404 void resize(size_type new_size, bool set_null);
405
406 void clear_range(size_type left, size_type right, bool set_null);
407
409 bm::null_support slice_null);
410
411 /*! \brief resize to zero, free memory
412 @param free_mem - fully destroys the plane vectors if true
413 */
414 void clear_all(bool free_mem = true) BMNOEXCEPT;
415
416 /*! return true if empty */
417 bool empty() const BMNOEXCEPT { return size() == 0; }
418
419 /** swap two vector elements */
421 { bmatr_.swap_columns(idx1, idx2); }
422
423public:
424
425 // ------------------------------------------------------------
426 /*! @name Various traits */
427 ///@{
428 ///
429
430 /**
431 \brief returns true if value type is signed integral type
432 */
433 static constexpr bool is_signed() BMNOEXCEPT
434 { return std::is_signed<value_type>::value; }
435
436 /**
437 \brief check if container supports NULL(unassigned) values
438 */
439 bool is_nullable() const BMNOEXCEPT { return bmatr_.get_null_idx(); }
440
441 /**
442 \brief check if container supports NULL (unassigned) values
443 */
446
447 /**
448 \brief Get bit-vector of assigned values or NULL
449 (if not constructed that way)
450 */
452 {
453 if (size_type null_idx = bmatr_.get_null_idx())
454 return bmatr_.get_row(null_idx);
455 return 0;
456 }
457
458 /** \brief test if specified element is NULL
459 \param idx - element index
460 \return true if it is NULL false if it was assigned or container
461 is not configured to support assignment flags
462 */
463 bool is_null(size_type idx) const BMNOEXCEPT;
464
465 /**
466 Set allocation pool
467 */
469 { bmatr_.set_allocator_pool(pool_ptr); }
470
471 /**
472 Get allocation pool
473 */
475 { return bmatr_.get_allocator_pool(); }
476
477 ///@}
478
479
480 // ------------------------------------------------------------
481 /*! @name Access to internals */
482 ///@{
483
484 /*!
485 \brief get access to bit-plain, function checks and creates a plane
486 \return bit-vector for the bit plain
487 @internal
488 */
490
491 /*!
492 \brief get read-only access to bit-plane
493 \return bit-vector for the bit plane or NULL
494 @internal
495 */
497 get_slice(unsigned i) const BMNOEXCEPT { return bmatr_.row(i); }
498
499 /*!
500 \brief get total number of bit-planes in the vector
501 @internal
502 */
503 static unsigned slices() BMNOEXCEPT { return value_bits(); }
504
505 /** Number of stored bit-planes (value planes + extra
506 @internal
507 */
508 static unsigned stored_slices() BMNOEXCEPT { return value_bits()+1; }
509
510
511 /** Number of effective bit-planes in the value type
512 @internal
513 */
515 { return effective_slices_ + 1; }
516
517 /*!
518 \brief get access to bit-plane as is (can return NULL)
519 @internal
520 */
521 bvector_type_ptr slice(unsigned i) BMNOEXCEPT { return bmatr_.get_row(i); }
523 { return bmatr_.get_row(i); }
524
526 {
527 if (size_type null_idx = bmatr_.get_null_idx())
528 return bmatr_.get_row(null_idx);
529 return 0;
530 }
531
532 /*!
533 \brief free memory in bit-plane
534 @internal
535 */
536 void free_slice(unsigned i) { bmatr_.destruct_row(i); }
537
538 /*!
539 return mask of allocated bit-planes
540 1 in the mask - means bit-plane N is present
541 returns 64-bit unsigned mask for sub 64-bit types (like int)
542 unallocated mask bits will be zero extended
543
544 @return 64-bit mask
545 @internal
546 */
547 bm::id64_t get_slice_mask(unsigned element_idx) const BMNOEXCEPT;
548
549 /*!
550 get read-only access to inetrnal bit-matrix
551 @internal
552 */
553 const bmatrix_type& get_bmatrix() const BMNOEXCEPT { return bmatr_; }
554
555 /**
556 access to internal bit-matrix
557 @internal
558 */
560
561 /**
562 Set NULL plain index
563 @internal
564 */
565 void mark_null_idx(unsigned null_idx) BMNOEXCEPT
566 { bmatr_.null_idx_ = null_idx; }
567 /**
568 Convert signed value type to unsigned representation
569 @internal
570 */
571 static
573
574 /**
575 Convert unsigned value type to signed representation
576 @internal
577 */
578 static
580
581
582 ///@}
583 ///
584 // -------------------------------------------------------------------
585
586 /*!
587 \brief run memory optimization for all bit-vector rows
588 \param temp_block - pre-allocated memory block to avoid unnecessary re-allocs
589 \param opt_mode - requested compression depth
590 \param stat - memory allocation statistics after optimization
591 */
592 void optimize(bm::word_t* temp_block = 0,
594 typename bvector_type::statistics* stat = 0);
595
596 /*!
597 @brief Calculates memory statistics.
598
599 Function fills statistics structure containing information about how
600 this vector uses memory and estimation of max. amount of memory
601 bvector needs to serialize itself.
602
603 @param st - pointer on statistics structure to be filled in.
604
605 @sa statistics
606 */
608
609 /*!
610 \brief check if another sparse vector has the same content and size
611
612 \param sv - sparse vector for comparison
613 \param null_able - flag to consider NULL vector in comparison (default)
614 or compare only value content planes
615
616 \return true, if it is the same
617 */
619 bm::null_support null_able = bm::use_null) const BMNOEXCEPT;
620
621protected:
623
624 /**
625 Merge plane bvectors from an outside base matrix
626 Note: outside base matrix gets destroyed
627 */
629
630 /**
631 Turn on RO mode
632 */
633 void freeze_matr() { bmatr_.freeze(); is_ro_ = true; }
634
635 /*!
636 clear column in all value planes
637 \param plane_idx - row (plane index to start from)
638 \param idx - bit (column) to clear
639 */
640 void clear_value_planes_from(unsigned plane_idx, size_type idx);
641
642 /*!
643 insert false (clear) column in all value planes
644 \param plane_idx - row (plane index to start from)
645 \param idx - bit (column) to clear insert
646 */
647 void insert_clear_value_planes_from(unsigned plane_idx, size_type idx);
648
649 /*!
650 erase bit (column) from all planes
651 \param idx - bit (column) to erase
652 \param erase_null - erase the NULL vector
653 */
654 void erase_column(size_type idx, bool erase_null);
655
656 /*!
657 insert (NOT) NULL value
658 */
659 void insert_null(size_type idx, bool not_null);
660
661 /**
662 Set SUB (MINUS) operation on all existing bit-slices
663 @param bv - argument vector row[i] -= bv
664 */
665 void bit_sub_rows(const bvector_type& bv, bool use_null)
666 { bmatr_.bit_sub_rows(bv, use_null); }
667
668 /**
669 Set AND (intersect) operation on all existing bit-slices
670 @param bv - argument vector row[i] -= bv
671 */
672 void bit_and_rows(const bvector_type& bv) { bmatr_.bit_and_rows(bv); }
673
674protected:
676
677 /** Number of total bit-planes in the value type*/
680
681 /** plane index for the "NOT NULL" flags plane */
682 //static constexpr unsigned null_plane() BMNOEXCEPT { return value_bits(); }
683
684 /** optimize block in all matrix planes */
685 void optimize_block(block_idx_type nb, typename BV::optmode opt_mode)
686 { bmatr_.optimize_block(nb, opt_mode); }
687
688 /// Sybc read-only state
690
691 /**
692 Perform copy_range() on a set of planes
693 */
695 const base_sparse_vector<Val, BV, MAX_SIZE>& bsv,
696 typename base_sparse_vector<Val, BV, MAX_SIZE>::size_type left,
697 typename base_sparse_vector<Val, BV, MAX_SIZE>::size_type right,
698 bm::null_support slice_null);
699
700protected:
701 bmatrix_type bmatr_; ///< bit-transposed matrix
702 unsigned_value_type slice_mask_ = 0; ///< slice presence bit-mask
703 size_type size_ = 0; ///< array size
704 unsigned effective_slices_=0; ///< number of bit slices actually allocated
705 bool is_ro_=false; ///< read-only
706};
707
708//---------------------------------------------------------------------
709//
710//---------------------------------------------------------------------
711
712#ifdef _MSC_VER
713#pragma warning( push )
714#pragma warning( disable : 4146 )
715#endif
716
717template<typename BV>
719 bool is_dynamic,
721 size_type bv_max_size,
722 const allocator_type& alloc)
723: bv_size_(bv_max_size),
724 alloc_(alloc),
725 ap_(ap)
726{
727 allocate_rows(rsize);
729}
730
731//---------------------------------------------------------------------
732
733template<typename BV>
738
739//---------------------------------------------------------------------
740
741template<typename BV>
743: bv_size_(bbm.bv_size_),
744 alloc_(bbm.alloc_),
745 ap_(bbm.ap_)
746{
747 copy_from(bbm);
749}
750
751//---------------------------------------------------------------------
752
753template<typename BV>
755: bv_size_(bbm.bv_size_),
756 alloc_(bbm.alloc_),
757 ap_(bbm.ap_)
758{
759 swap(bbm);
760 is_dynamic_ = bbm.is_dynamic_;
761}
762
763//---------------------------------------------------------------------
764
765template<typename BV>
768{
769 BM_ASSERT(i < rsize_);
770 return bv_rows_[i];
771}
772
773//---------------------------------------------------------------------
774
775template<typename BV>
778{
779 BM_ASSERT(i < rsize_);
780 return bv_rows_[i];
781}
782
783//---------------------------------------------------------------------
784
785template<typename BV>
792
793//---------------------------------------------------------------------
794
795template<typename BV>
797{
798 BM_ASSERT(null_idx);
799 BM_ASSERT(get_row(null_idx));
800 null_idx_ = null_idx;
801}
802
803//---------------------------------------------------------------------
804
805template<typename BV>
807{
808 if (this == &bbm) // nothing to do
809 return;
810 free_rows();
811
812 bv_size_ = bbm.bv_size_;
813 alloc_ = bbm.alloc_;
814 ap_ = bbm.ap_;
815
816 null_idx_ = bbm.null_idx_;
817
818 size_type rsize = bbm.rsize_;
819 if (rsize)
820 {
821 bv_rows_ = (bvector_type_ptr*)alloc_.alloc_ptr(rsize);
822 if (!bv_rows_)
824 rsize_ = rsize;
825 for (size_type i = 0; i < rsize_; ++i)
826 {
827 const bvector_type_ptr bv = bbm.bv_rows_[i];
828 bv_rows_[i] = bv ? construct_bvector(bv) : 0;
829 }
830 }
831}
832
833//---------------------------------------------------------------------
834
835template<typename BV>
837{
838 // relies that NULL bvector is the last
839 size_type r_to = (!erase_null && null_idx_) ? null_idx_ : rsize_;
840 for (size_type i = 0; i < r_to; ++i)
841 if (bvector_type* bv = get_row(i))
842 bv->erase(idx);
843}
844
845//---------------------------------------------------------------------
846
847template<typename BV>
849 size_type row_from)
850{
851 for (size_type i = row_from; i < rsize_; ++i)
852 if (bvector_type* bv = get_row(i))
853 bv->insert(idx, false);
854}
855
856//---------------------------------------------------------------------
857
858template<typename BV>
860 size_type row_from)
861{
862 for (size_type i = row_from; i < rsize_; ++i)
863 if (bvector_type* bv = get_row(i))
864 bv->clear_bit_no_check(idx);
865}
866
867//---------------------------------------------------------------------
868
869template<typename BV>
871{
872 for (size_type i = 0; i < rsize_; ++i)
873 if (bvector_type* bv = get_row(i))
874 bv->swap(idx1, idx2);
875}
876
877//---------------------------------------------------------------------
878
879template<typename BV>
881{
882 size_type rsize_prev(rsize_);
883 if (rsize <= rsize_prev)
884 return; // nothing to do
885 bvector_type_ptr* bv_rows_prev(bv_rows_);
886
887 BM_ASSERT(rsize);
888 bv_rows_ = (bvector_type_ptr*)alloc_.alloc_ptr(unsigned(rsize));
889 if (!bv_rows_)
891 rsize_ = rsize;
892 BM_ASSERT((!null_idx_) || (rsize & 1u));
893 ::memset(&bv_rows_[0], 0, rsize * sizeof(bv_rows_[0]));
894 if (bv_rows_prev) // deallocate prev, reset NULL
895 {
896 for (size_type i = 0; i < rsize_prev; ++i)
897 bv_rows_[i] = bv_rows_prev[i];
898 alloc_.free_ptr(bv_rows_prev, unsigned(rsize_prev));
899 if (null_idx_) // shift-up the NULL row
900 {
901 bv_rows_[rsize-1] = bv_rows_[null_idx_];
902 bv_rows_[null_idx_] = 0;
903 null_idx_ = rsize-1;
904 BM_ASSERT(rsize & 1u);
905 }
906 }
907}
908
909//---------------------------------------------------------------------
910
911template<typename BV>
914{
915 size_type osize = (7 + rows_not_null()) / 8;
916 return osize;
917}
918
919
920//---------------------------------------------------------------------
921
922template<typename BV>
924{
925 for (size_type i = 0; i < rsize_; ++i)
926 {
927 if (bvector_type_ptr bv = bv_rows_[i])
928 {
930 bv_rows_[i] = 0;
931 }
932 } // for i
933 if (bv_rows_)
934 alloc_.free_ptr(bv_rows_, unsigned(rsize_));
935 bv_rows_ = 0;
936}
937
938//---------------------------------------------------------------------
939
940template<typename BV>
942 const basic_bmatrix<BV>& bbm) const BMNOEXCEPT
943{
944 BM_ASSERT(this != &bbm);
945
946 if (rsize_ != bbm.rsize_)
947 return false;
948 if (null_idx_ != bbm.null_idx_)
949 return false;
950 for (size_type i = 0; i < rsize_; ++i)
951 {
952 const bvector_type* bv = bv_rows_[i];
953 const bvector_type* bv_arg = bbm.bv_rows_[i];
954 if (bool(bv) != bool(bv_arg))
955 return false;
956 } // for i
957
958
959 return true;
960}
961
962//---------------------------------------------------------------------
963
964template<typename BV>
966{
967 if (pool_ != pool_ptr)
968 {
969 for (size_type i = 0; i < rsize_; ++i)
970 if (bvector_type_ptr bv = bv_rows_[i])
971 bv->set_allocator_pool(pool_ptr);
972 }
973 pool_ = pool_ptr;
974}
975
976
977//---------------------------------------------------------------------
978
979template<typename BV>
982{
983 // TODO: SIMD
984 auto i = rows_not_null();
985 for (--i; i > 0; --i)
986 {
987 if (bv_rows_[i])
988 {
989 ++i;
990 break;
991 }
992 }
993 return i;
994}
995
996//---------------------------------------------------------------------
997
998template<typename BV>
1000{
1002 for (size_type i = 0; i < sz; ++i)
1003 {
1004 if (bvector_type_ptr bv_r = bv_rows_[i])
1005 bv_r->bit_sub(bv);
1006 } // for i
1007}
1008
1009//---------------------------------------------------------------------
1010
1011template<typename BV>
1013{
1014 for (size_type i = 0; i < rsize_; ++i)
1015 {
1016 if (bvector_type_ptr bv_r = bv_rows_[i])
1017 bv_r->bit_and(bv);
1018 } // for i
1019}
1020
1021//---------------------------------------------------------------------
1022
1023template<typename BV>
1025{
1026 if (this == &bbm)
1027 return;
1028
1029 bm::xor_swap(bv_size_, bbm.bv_size_);
1030
1031 allocator_type alloc_tmp = alloc_;
1032 alloc_ = bbm.alloc_;
1033 bbm.alloc_ = alloc_tmp;
1034
1035 allocation_policy_type ap_tmp = ap_;
1036 ap_ = bbm.ap_;
1037 bbm.ap_ = ap_tmp;
1038
1039 allocator_pool_type* pool_tmp = pool_;
1040 pool_ = bbm.pool_;
1041 bbm.pool_ = pool_tmp;
1042
1043 bm::xor_swap(rsize_, bbm.rsize_);
1044 bm::xor_swap(null_idx_, bbm.null_idx_);
1045
1046 bvector_type_ptr* rtmp = bv_rows_;
1047 bv_rows_ = bbm.bv_rows_;
1048 bbm.bv_rows_ = rtmp;
1049}
1050
1051//---------------------------------------------------------------------
1052
1053template<typename BV>
1056{
1057 if (is_dynamic())
1058 {
1059 if (row >= rsize_)
1060 allocate_rows(rsize_ + 8);
1061 }
1062 BM_ASSERT(row < rsize_);
1064 if (!bv)
1065 bv = bv_rows_[row] = construct_bvector(0);
1066 return bv;
1067}
1068
1069//---------------------------------------------------------------------
1070
1071template<typename BV>
1074{
1075 if (row >= rsize_)
1076 allocate_rows(row + 8);
1077 BM_ASSERT(row < rsize_);
1079 if (bv)
1080 *bv = bv_src;
1081 else
1082 bv = bv_rows_[row] = construct_bvector(&bv_src);
1083 return bv;
1084}
1085
1086
1087//---------------------------------------------------------------------
1088
1089template<typename BV>
1091{
1092 BM_ASSERT(row < rsize_);
1093 if (bvector_type_ptr bv = bv_rows_[row])
1094 {
1095 destruct_bvector(bv);
1096 bv_rows_[row] = 0;
1097 }
1098}
1099
1100//---------------------------------------------------------------------
1101
1102template<typename BV>
1104{
1105 BM_ASSERT(row < rsize_);
1106 if (bvector_type_ptr bv = bv_rows_[row])
1107 {
1108 if (free_mem)
1109 {
1110 destruct_bvector(bv);
1111 bv_rows_[row] = 0;
1112 }
1113 else
1114 bv->clear(true);
1115 }
1116}
1117
1118//---------------------------------------------------------------------
1119
1120template<typename BV>
1123{
1124 bvector_type* rbv = 0;
1125#ifdef BM_NO_STL // C compatibility mode
1126 void* mem = ::malloc(sizeof(bvector_type));
1127 if (mem == 0)
1128 {
1129 BM_THROW(false, BM_ERR_BADALLOC);
1130 }
1131 if (bv)
1132 rbv = new(mem) bvector_type(*bv);
1133 else
1134 {
1135 rbv = new(mem) bvector_type(ap_.strat, ap_.glevel_len, bv_size_, alloc_);
1136 rbv->init();
1137 }
1138#else
1139 if (bv)
1140 rbv = new bvector_type(*bv);
1141 else
1142 {
1143 rbv = new bvector_type(ap_.strat, ap_.glevel_len, bv_size_, alloc_);
1144 rbv->init();
1145 }
1146#endif
1147 if (pool_)
1148 rbv->set_allocator_pool(pool_);
1149 return rbv;
1150}
1151
1152//---------------------------------------------------------------------
1153
1154template<typename BV>
1156{
1157#ifdef BM_NO_STL // C compatibility mode
1158 bv->~TBM_bvector();
1159 ::free((void*)bv);
1160#else
1161 delete bv;
1162#endif
1163}
1164
1165//---------------------------------------------------------------------
1166
1167template<typename BV>
1168const bm::word_t*
1170 unsigned i, unsigned j) const BMNOEXCEPT
1171{
1172 if (bvector_type_const_ptr bv = this->row(p))
1173 return bv->get_blocks_manager().get_block_ptr(i, j);
1174 return 0;
1175}
1176
1177//---------------------------------------------------------------------
1178
1179template<typename BV>
1181 unsigned slice_from, unsigned slice_until,
1182 size_type idx)
1183{
1184 for (unsigned p = slice_from; p < slice_until; ++p)
1185 if (bvector_type* bv = this->get_row(p)) // TODO: optimize cleaning
1186 bv->clear_bit_no_check(idx);
1187}
1188
1189
1190//---------------------------------------------------------------------
1191
1192template<typename BV>
1194 size_type octet_idx,
1195 unsigned char octet)
1196{
1197 if (7u + octet_idx * 8u > rsize_)
1198 allocate_rows(rsize_ + 16);
1199
1200 size_type row = octet_idx * 8;
1201 size_type row_end = row + 8;
1202 for (; row < row_end; ++row)
1203 {
1204 bvector_type* bv = (row < rsize_) ? this->get_row(row) : 0;
1205 if (octet & 1u)
1206 {
1207 if (!bv)
1208 bv = this->construct_row(row);
1209 bv->set_bit_no_check(pos);
1210 }
1211 else
1212 {
1213 if (bv)
1214 bv->clear_bit_no_check(pos);
1215 }
1216 octet >>= 1;
1217 if (!octet)
1218 break;
1219 } // for
1220
1221 // clear the tail
1222 if (row_end > rsize_)
1223 row_end = rsize_;
1224 for (++row; row < row_end; ++row)
1225 if (bvector_type* bv = this->get_row(row))
1226 bv->clear_bit_no_check(pos);
1227}
1228
1229//---------------------------------------------------------------------
1230
1231template<typename BV>
1233 size_type octet_idx,
1234 unsigned char octet)
1235{
1236 BM_ASSERT(octet_idx * 8u < rsize_);
1237
1238 size_type oct = octet;
1239 size_type row = octet_idx * 8;
1240 size_type row_end = row + 8;
1241 for (; row < row_end; ++row)
1242 {
1243 bvector_type* bv = (row < rsize_) ? this->get_row(row) : 0;
1244 if (oct & 1u)
1245 {
1246 if (!bv)
1247 {
1248 bv = this->construct_row(row);
1249 bv->set_bit_no_check(pos);
1250 }
1251 else
1252 {
1253 bv->insert(pos, true);
1254 }
1255 }
1256 else
1257 {
1258 if (bv)
1259 bv->insert(pos, false);
1260 }
1261 oct >>= 1;
1262 if (!oct)
1263 break;
1264 } // for
1265
1266 // clear the tail
1267 if (row_end > rsize_)
1268 row_end = rsize_;
1269 for (++row; row < row_end; ++row)
1270 if (bvector_type* bv = this->get_row(row))
1271 bv->insert(pos, false);
1272}
1273
1274
1275//---------------------------------------------------------------------
1276
1277/// @internal
1278inline
1279bool check_any_fullb(const bm::word_t* blka[8], const bm::word_t* FBADDR)
1280{
1281 bool b1, b2;
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);
1290 return b1 | b2;
1291}
1292
1293template<typename BV>
1294unsigned char
1296{
1297 const bm::word_t* blka[8];
1298 unsigned v = 0;
1299
1300 block_idx_type nb = (pos >> bm::set_block_shift);
1301 unsigned i0, j0;
1302 bm::get_block_coord(nb, i0, j0);
1303
1304 unsigned row_idx = unsigned(octet_idx * 8);
1305 if (row_idx + 7 >= rsize_ ||
1306 (null_idx_ && (row_idx + 7 > null_idx_))) // out of bounds request?
1307 return (unsigned char)v;
1308
1309 blka[0] = get_block(row_idx+0, i0, j0);
1310 blka[1] = get_block(row_idx+1, i0, j0);
1311 blka[2] = get_block(row_idx+2, i0, j0);
1312 blka[3] = get_block(row_idx+3, i0, j0);
1313 blka[4] = get_block(row_idx+4, i0, j0);
1314 blka[5] = get_block(row_idx+5, i0, j0);
1315 blka[6] = get_block(row_idx+6, i0, j0);
1316 blka[7] = get_block(row_idx+7, i0, j0);
1317
1318
1319 const bm::word_t* const FBADDR = FULL_BLOCK_FAKE_ADDR;
1320
1321 unsigned is_set;
1322 unsigned nbit = unsigned(pos & bm::set_block_mask);
1323 const unsigned nword = unsigned(nbit >> bm::set_word_shift);
1324 const unsigned mask0 = 1u << (nbit & bm::set_word_mask);
1325#if 0
1326 bool any_full = bm::check_any_fullb(blka, FBADDR);
1327 if (!any_full)
1328 {
1329 if (const bm::word_t* blk; (blk = blka[0])!=0)
1330 {
1331 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1332 v |= (unsigned)bool(is_set);
1333 }
1334 if (const bm::word_t* blk;(blk = blka[1])!=0)
1335 {
1336 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1337 v |= unsigned(bool(is_set)) << 1u;
1338 }
1339 if (const bm::word_t* blk;(blk = blka[2])!=0)
1340 {
1341 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1342 v |= unsigned(bool(is_set)) << 2u;
1343 }
1344 if (const bm::word_t* blk;(blk = blka[3])!=0)
1345 {
1346 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1347 v |= unsigned(bool(is_set)) << 3u;
1348 }
1349 if (const bm::word_t* blk;(blk = blka[4])!=0)
1350 {
1351 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1352 v |= unsigned(bool(is_set)) << 4u;
1353 }
1354 if (const bm::word_t* blk;(blk = blka[5])!=0)
1355 {
1356 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1357 v |= unsigned(bool(is_set)) << 5u;
1358 }
1359 if (const bm::word_t* blk;(blk = blka[6])!=0)
1360 {
1361 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1362 v |= unsigned(bool(is_set)) << 6u;
1363 }
1364 if (const bm::word_t* blk;(blk = blka[7])!=0)
1365 {
1366 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1367 v |= unsigned(bool(is_set)) << 7u;
1368 }
1369 return (unsigned char)v;
1370 }
1371#endif
1372 const bm::word_t* blk;
1373 if ((blk = blka[0])!=0)
1374 {
1375 if (blk == FBADDR)
1376 is_set = 1;
1377 else
1378 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1379 v |= (unsigned)bool(is_set);
1380 }
1381 if ((blk = blka[1])!=0)
1382 {
1383 if (blk == FBADDR)
1384 is_set = 1;
1385 else
1386 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1387 v |= unsigned(bool(is_set)) << 1u;
1388 }
1389 if ((blk = blka[2])!=0)
1390 {
1391 if (blk == FBADDR)
1392 is_set = 1;
1393 else
1394 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1395 v |= unsigned(bool(is_set)) << 2u;
1396 }
1397 if ((blk = blka[3])!=0)
1398 {
1399 if (blk == FBADDR)
1400 is_set = 1;
1401 else
1402 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1403 v |= unsigned(bool(is_set)) << 3u;
1404 }
1405
1406 if ((blk = blka[4])!=0)
1407 {
1408 if (blk == FBADDR)
1409 is_set = 1;
1410 else
1411 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1412 v |= unsigned(bool(is_set)) << 4u;
1413 }
1414 if ((blk = blka[5])!=0)
1415 {
1416 if (blk == FBADDR)
1417 is_set = 1;
1418 else
1419 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1420 v |= unsigned(bool(is_set)) << 5u;
1421 }
1422 if ((blk = blka[6])!=0)
1423 {
1424 if (blk == FBADDR)
1425 is_set = 1;
1426 else
1427 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1428 v |= unsigned(bool(is_set)) << 6u;
1429 }
1430 if ((blk = blka[7])!=0)
1431 {
1432 if (blk == FBADDR)
1433 is_set = 1;
1434 else
1435 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1436 v |= unsigned(bool(is_set)) << 7u;
1437 }
1438
1439 return (unsigned char)v;
1440}
1441
1442//---------------------------------------------------------------------
1443
1444template<typename BV>
1446 size_type octet_idx,
1447 char octet) const BMNOEXCEPT
1448{
1449 char value = char(get_octet(pos, octet_idx));
1450 return (value > octet) - (value < octet);
1451}
1452
1453//---------------------------------------------------------------------
1454
1455/**
1456 Test 4 pointers are all marked as GAPs
1457 @internal
1458 */
1459inline
1460bool test_4gaps(const bm::word_t* p0, const bm::word_t* p1,
1461 const bm::word_t* p2, const bm::word_t* p3) BMNOEXCEPT
1462{
1463 uintptr_t p
1464 = uintptr_t(p0) | uintptr_t(p1) | uintptr_t(p2) | uintptr_t(p3);
1465 return (p & 1);
1466}
1467/**
1468 Test 4 pointers are not NULL and not marked as FULLBLOCK
1469 @internal
1470*/
1471inline
1472bool test_4bits(const bm::word_t* p0, const bm::word_t* p1,
1473 const bm::word_t* p2, const bm::word_t* p3) BMNOEXCEPT
1474{
1475 return p0 && p0!=FULL_BLOCK_FAKE_ADDR &&
1476 p1 && p1!=FULL_BLOCK_FAKE_ADDR &&
1477 p2 && p2!=FULL_BLOCK_FAKE_ADDR &&
1478 p3 && p3!=FULL_BLOCK_FAKE_ADDR;
1479}
1480
1481
1482template<typename BV>
1483unsigned
1485{
1486 unsigned v = 0;
1487
1488 block_idx_type nb = (pos >> bm::set_block_shift);
1489 unsigned i0, j0;
1490 bm::get_block_coord(nb, i0, j0);
1491
1492 const bm::word_t* blk;
1493 const bm::word_t* blka[4];
1494 unsigned nbit = unsigned(pos & bm::set_block_mask);
1495
1496 blka[0] = get_block(row_idx+0, i0, j0);
1497 blka[1] = get_block(row_idx+1, i0, j0);
1498 blka[2] = get_block(row_idx+2, i0, j0);
1499 blka[3] = get_block(row_idx+3, i0, j0);
1500 unsigned is_set;
1501
1502
1503 unsigned nword = unsigned(nbit >> bm::set_word_shift);
1504 unsigned mask0 = 1u << (nbit & bm::set_word_mask);
1505
1506 // speculative assumption that nibble is often 4 bit-blocks
1507 // and we will be able to extract it faster with less mispredicts
1508 //
1509 if (!test_4gaps(blka[0], blka[1], blka[2], blka[3]))
1510 {
1511 if (test_4bits(blka[0], blka[1], blka[2], blka[3]))
1512 {
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);
1517 return v;
1518 }
1519 }
1520 // hypothesis above didn't work out extract the regular way
1521 unsigned i = 0;
1522 do
1523 {
1524 if ((blk = blka[i])!=0)
1525 {
1526 if (blk == FULL_BLOCK_FAKE_ADDR)
1527 is_set = 1;
1528 else
1529 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1530 v |= unsigned(bool(is_set)) << i;
1531 }
1532 if ((blk = blka[++i])!=0)
1533 {
1534 if (blk == FULL_BLOCK_FAKE_ADDR)
1535 is_set = 1;
1536 else
1537 is_set = (BM_IS_GAP(blk)) ? bm::gap_test_unr(BMGAP_PTR(blk), nbit) : (blk[nword] & mask0);
1538 v |= unsigned(bool(is_set)) << i;
1539 }
1540 } while(++i < 4);
1541 return v;
1542}
1543
1544//---------------------------------------------------------------------
1545
1546template<typename BV>
1548 typename bvector_type::optmode opt_mode,
1549 typename bvector_type::statistics* st)
1550{
1551 if (st)
1552 st->reset();
1553
1555 if (!temp_block)
1556 temp_block = tb;
1557
1558 for (unsigned k = 0; k < rsize_; ++k)
1559 {
1560 if (bvector_type* bv = get_row(k))
1561 {
1562 typename bvector_type::statistics stbv;
1563 stbv.reset();
1564 bv->optimize(temp_block, opt_mode, st ? &stbv : 0);
1565 if (st)
1566 st->add(stbv);
1567 }
1568 } // for k
1569}
1570
1571//---------------------------------------------------------------------
1572
1573template<typename BV>
1575{
1576 for (unsigned k = 0; k < rsize_; ++k)
1577 if (bvector_type* bv = get_row(k))
1578 bv->freeze();
1579}
1580
1581//---------------------------------------------------------------------
1582
1583template<typename BV>
1585 size_type rsize) const BMNOEXCEPT
1586{
1587 for (size_type i = 0; i < rsize; ++i)
1588 if (const bvector_type* bv = row(i))
1589 {
1590 typename bvector_type::statistics stbv;
1591 bv->calc_stat(&stbv);
1592 st.add(stbv);
1593 }
1594 else
1595 st.max_serialize_mem += 8;
1596}
1597
1598//---------------------------------------------------------------------
1599
1600template<typename BV>
1602 typename BV::optmode opt_mode)
1603{
1604 for (unsigned k = 0; k < rsize_; ++k)
1605 {
1606 if (bvector_type* bv = get_row(k))
1607 {
1608 unsigned i, j;
1609 bm::get_block_coord(nb, i, j);
1610 typename bvector_type::blocks_manager_type& bman =
1611 bv->get_blocks_manager();
1612 bman.optimize_bit_block(i, j, opt_mode);
1613 }
1614 } // for k
1615
1616}
1617
1618//---------------------------------------------------------------------
1619//
1620//---------------------------------------------------------------------
1621
1622
1623
1624template<class Val, class BV, unsigned MAX_SIZE>
1628
1629//---------------------------------------------------------------------
1630
1631template<class Val, class BV, unsigned MAX_SIZE>
1633 bm::null_support null_able,
1634 bool is_dynamic,
1636 size_type bv_max_size,
1637 const allocator_type& alloc)
1638: bmatr_(sv_slices, is_dynamic, ap, bv_max_size, alloc)
1639{
1640 if (null_able == bm::use_null)
1641 {
1642 size_type null_idx = (MAX_SIZE * sizeof(Val) * 8);
1643 bmatr_.construct_row(null_idx)->init();
1644 bmatr_.set_null_idx(null_idx);
1645 slice_mask_ |= unsigned_value_type(1) << null_idx;
1646 }
1647}
1648
1649//---------------------------------------------------------------------
1650
1651template<class Val, class BV, unsigned MAX_SIZE>
1659
1660//---------------------------------------------------------------------
1661
1662template<class Val, class BV, unsigned MAX_SIZE>
1665{
1666 resize(bsv.size(), true);
1668
1669 size_type arg_null_idx = bsv.bmatr_.get_null_idx();
1670 if (arg_null_idx)
1671 bmatr_.null_idx_ = arg_null_idx;
1672
1673 size_type slices = bsv.get_bmatrix().rows(); //stored_slices();
1674 bmatr_.allocate_rows(slices);
1675 for (size_type i = 0; i < slices; ++i)
1676 {
1677 bvector_type* bv = bmatr_.get_row(i);
1678 const bvector_type* bv_src = bsv.bmatr_.row(i);
1679
1680 if (i && (i == arg_null_idx)) // NULL plane copy
1681 {
1682 if (bv && !bv_src) // special case (copy from not NULL)
1683 {
1684 if (size_)
1685 bv->set_range(0, size_-1);
1686 continue;
1687 }
1688 }
1689 if (bv)
1690 {
1691 bmatr_.destruct_row(i);
1692 slice_mask_ &= ~(unsigned_value_type(1) << i);
1693 }
1694 if (bv_src)
1695 {
1696 bmatr_.construct_row(i, *bv_src);
1697 slice_mask_ |= (unsigned_value_type(1) << i);
1698 }
1699 } // for i
1700}
1701
1702//---------------------------------------------------------------------
1703
1704template<class Val, class BV, unsigned MAX_SIZE>
1706 bmatrix_type& bmatr)
1707{
1708 size_type rows = this->bmatr_.rows();
1709 const size_type arg_rows = bmatr.rows();
1710 if (rows < arg_rows)
1711 {
1712 rows = arg_rows;
1713 bmatr_.allocate_rows(rows);
1714 BM_ASSERT(this->bmatr_.rows() == arg_rows);
1715 }
1716
1717 bvector_type* bv_null_arg = 0;
1718 size_type null_idx = bmatr.get_null_idx();
1719 if (null_idx)
1720 bv_null_arg = bmatr.get_row(null_idx);
1721
1722 if (bvector_type* bv_null = get_null_bvect())
1723 {
1724 BM_ASSERT(bv_null_arg);
1725 bv_null->merge(*bv_null_arg);
1726 }
1727 if (rows > arg_rows)
1728 rows = arg_rows; // min
1729 for (unsigned j = 0; j < rows; ++j)
1730 {
1731 bvector_type* arg_bv = bmatr.get_row(j);
1732 if (arg_bv && arg_bv != bv_null_arg)
1733 {
1734 bvector_type* bv = this->get_create_slice(j);
1735 slice_mask_ |= (unsigned_value_type(1) << j);
1736 bv->merge(*arg_bv);
1737 }
1738 } // for j
1739}
1740
1741//---------------------------------------------------------------------
1742
1743template<class Val, class BV, unsigned MAX_SIZE>
1746{
1747 if (this != &bsv)
1748 {
1749 bmatr_.swap(bsv.bmatr_);
1750 bm::xor_swap(slice_mask_, bsv.slice_mask_);
1751 bm::xor_swap(size_, bsv.size_);
1752 bm::xor_swap(effective_slices_, bsv.effective_slices_);
1753 }
1754}
1755
1756//---------------------------------------------------------------------
1757
1758template<class Val, class BV, unsigned MAX_SIZE>
1760{
1761 auto slices = bmatr_.rows();
1762 bvector_type* bv_null = this->get_null_bvect();
1763 for (size_type i = 0; i < slices; ++i)
1764 if (bvector_type* bv = this->bmatr_.get_row(i))
1765 if (bv != bv_null)
1766 bmatr_.clear_row(i, free_mem);
1767 slice_mask_ = 0; size_ = 0;
1768 if (bv_null)
1769 bv_null->clear(true);
1770 is_ro_ = false;
1771}
1772
1773//---------------------------------------------------------------------
1774
1775template<class Val, class BV, unsigned MAX_SIZE>
1779 bool set_null)
1780{
1781 if (right < left)
1782 return clear_range(right, left, set_null);
1783 auto planes = bmatr_.rows();
1784 bvector_type* bv_null = this->get_null_bvect();
1785 for (unsigned i = 0; i < planes; ++i)
1786 {
1787 if (bvector_type* bv = this->bmatr_.get_row(i))
1788 if (bv != bv_null)
1789 bv->clear_range_no_check(left, right);
1790 }
1791 if (set_null && bv_null)
1792 bv_null->clear_range_no_check(left, right);
1793}
1794
1795//---------------------------------------------------------------------
1796
1797template<class Val, class BV, unsigned MAX_SIZE>
1799 size_type left, size_type right,
1800 bm::null_support slice_null)
1801{
1802 if (left)
1803 this->clear_range(0, left-1, (slice_null == bm::use_null));
1804 size_type sz = size();
1805 if (right < sz)
1806 this->clear_range(right + 1, sz, (slice_null == bm::use_null));
1807}
1808
1809//---------------------------------------------------------------------
1810
1811template<class Val, class BV, unsigned MAX_SIZE>
1813{
1814 if (sz == size()) // nothing to do
1815 return;
1816 if (!sz) // resize to zero is an equivalent of non-destructive deallocation
1817 {
1818 clear_all();
1819 return;
1820 }
1821 if (sz < size()) // vector shrink
1822 clear_range(sz, this->size_, set_null); // clear the tails and NULL
1823 size_ = sz;
1824}
1825
1826
1827//---------------------------------------------------------------------
1828
1829template<class Val, class BV, unsigned MAX_SIZE>
1831 size_type idx) const BMNOEXCEPT
1832{
1833 const bvector_type* bv_null = get_null_bvector();
1834 return (bv_null) ? (!bv_null->test(idx)) : false;
1835}
1836
1837//---------------------------------------------------------------------
1838
1839template<class Val, class BV, unsigned MAX_SIZE>
1841 bool not_null)
1842{
1843 if (bvector_type* bv_null = this->get_null_bvect())
1844 bv_null->insert(idx, not_null);
1845}
1846
1847//---------------------------------------------------------------------
1848
1849template<class Val, class BV, unsigned MAX_SIZE>
1852{
1853 bvector_type_ptr bv = bmatr_.construct_row(i);
1854
1855 // slice mask or efective_slices does not extend beyond the natural size
1856 // (in bits)
1857 if (i < (sizeof(value_type) * 8))
1858 {
1859 // note: unsigned int shift by << 32 is UNDEFINED behav.
1860 slice_mask_ |= (unsigned_value_type(1) << i);
1861 if (i > effective_slices_)
1863 }
1864 return bv;
1865}
1866
1867//---------------------------------------------------------------------
1868
1869template<class Val, class BV, unsigned MAX_SIZE>
1871 unsigned element_idx) const BMNOEXCEPT
1872{
1873 bm::id64_t mask = 0;
1874 bm::id64_t mask1 = 1;
1875 const unsigned planes = sizeof(value_type) * 8;
1876 unsigned bidx = 0;
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;
1882 return mask;
1883}
1884
1885//---------------------------------------------------------------------
1886
1887template<class Val, class BV, unsigned MAX_SIZE>
1889 typename bvector_type::optmode opt_mode,
1890 typename bvector_type::statistics* st)
1891{
1892 typename bvector_type::statistics stbv;
1893 bmatr_.optimize(temp_block, opt_mode, &stbv);
1894 if (st)
1895 st->add(stbv);
1896
1897 bvector_type* bv_null = this->get_null_bvect();
1898 unsigned slices = (unsigned)this->bmatr_.rows();
1899 for (unsigned j = 0; j < slices; ++j)
1900 {
1901 bvector_type* bv = this->bmatr_.get_row(j);
1902 if (bv && (bv != bv_null)) // protect the NULL vector from de-allocation
1903 {
1904 // TODO: check if this can be done within optimize loop
1905 if (!bv->any()) // empty vector?
1906 {
1907 this->bmatr_.destruct_row(j);
1908 slice_mask_ &= ~(unsigned_value_type(1) << j);
1909 continue;
1910 }
1911 }
1912 } // for j
1913}
1914
1915//---------------------------------------------------------------------
1916
1917template<class Val, class BV, unsigned MAX_SIZE>
1919 typename bvector_type::statistics* st) const BMNOEXCEPT
1920{
1921 BM_ASSERT(st);
1922 st->reset();
1923 size_type slices = this->get_bmatrix().rows();//stored_slices();
1924 bmatr_.calc_stat(*st, slices);
1925
1926 // header accounting
1927 st->max_serialize_mem += 1 + 1 + 1 + 1 + 8 + (8 * slices);
1928 st->max_serialize_mem += 1 + 8; // extra header fields for large bit-matrixes
1929}
1930
1931//---------------------------------------------------------------------
1932
1933template<class Val, class BV, unsigned MAX_SIZE>
1935 unsigned plane_idx, size_type idx)
1936{
1937 bmatr_.clear_column(idx, plane_idx);
1938}
1939
1940//---------------------------------------------------------------------
1941
1942template<class Val, class BV, unsigned MAX_SIZE>
1944 unsigned plane_idx, size_type idx)
1945{
1946 bmatr_.insert_column(idx, plane_idx);
1947}
1948
1949//---------------------------------------------------------------------
1950
1951template<class Val, class BV, unsigned MAX_SIZE>
1953 size_type idx, bool erase_null)
1954{
1955 bmatr_.erase_column(idx, erase_null);
1956}
1957
1958//---------------------------------------------------------------------
1959
1960template<class Val, class BV, unsigned MAX_SIZE>
1963 bm::null_support null_able) const BMNOEXCEPT
1964{
1965 if (size_type arg_size = sv.size(); this->size_ != arg_size)
1966 return false;
1967
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;
1973
1974 const bvector_type* bv_null = this->get_null_bvector();
1975 const bvector_type* bv_null_arg = sv.get_null_bvector();
1976
1977 for (unsigned j = 0; j < max_slices; ++j)
1978 {
1979 const bvector_type* bv;
1980 const bvector_type* arg_bv;
1981
1982 bv = (j < slices) ? this->bmatr_.get_row(j) : 0;
1983 arg_bv = (j < arg_slices) ? sv.bmatr_.get_row(j) : 0;
1984 if (bv == bv_null)
1985 bv = 0; // NULL vector compare postponed for later
1986 if (arg_bv == bv_null_arg)
1987 arg_bv = 0;
1988 if (bv == arg_bv) // same NULL
1989 continue;
1990
1991 // check if any not NULL and not empty
1992 if (!bv && arg_bv)
1993 {
1994 if (arg_bv->any())
1995 return false;
1996 continue;
1997 }
1998 if (bv && !arg_bv)
1999 {
2000 if (bv->any())
2001 return false;
2002 continue;
2003 }
2004 // both not NULL
2005 bool eq = bv->equal(*arg_bv);
2006 if (!eq)
2007 return false;
2008 } // for j
2009
2010 if (null_able == bm::use_null)
2011 {
2012 // check the NULL vectors
2013 if (bv_null == bv_null_arg)
2014 return true;
2015 if (!bv_null || !bv_null_arg)
2016 return false; // TODO: this may need an improvement when one is null, others not null
2017
2018 BM_ASSERT(bv_null);
2019 BM_ASSERT(bv_null_arg);
2020 bool eq = bv_null->equal(*bv_null_arg);
2021 if (!eq)
2022 return false;
2023 }
2024 return true;
2025}
2026
2027//---------------------------------------------------------------------
2028
2029template<class Val, class BV, unsigned MAX_SIZE>
2031{
2032 unsigned slices = (unsigned) this->bmatr_.rows();
2033 for (unsigned j = 0; j < slices; ++j)
2034 {
2035 if (const bvector_type* bv = this->bmatr_.get_row(j))
2036 {
2037 if (bv->is_ro())
2038 {
2039 is_ro_ = true;
2040 break;
2041 }
2042 }
2043 } // for j
2044}
2045
2046//---------------------------------------------------------------------
2047
2048template<class Val, class BV, unsigned MAX_SIZE>
2053 bm::null_support slice_null)
2054{
2055 if (bmatr_.rows() < bsv.bmatr_.rows())
2056 bmatr_.allocate_rows(bsv.bmatr_.rows());
2057
2058 size_type spli;
2059 const bvector_type* bv_null_arg = bsv.get_null_bvector();
2060 if (bvector_type* bv_null = get_null_bvect())
2061 {
2062 spli = this->bmatr_.rows(); //stored_slices();
2063 if (bv_null_arg && (slice_null == bm::use_null))
2064 bv_null->copy_range(*bv_null_arg, left, right);
2065 --spli;
2066 }
2067 else
2068 spli = this->bmatr_.rows();
2069
2070 for (size_type j = 0; j < spli; ++j)
2071 {
2072 if (const bvector_type* arg_bv = bsv.bmatr_.row(j))
2073 {
2074 if (arg_bv == bv_null_arg)
2075 continue;
2076 bvector_type* bv = this->get_create_slice(unsigned(j));
2077 bv->copy_range(*arg_bv, left, right);
2078 }
2079 } // for j
2080
2081}
2082
2083//---------------------------------------------------------------------
2084
2085template<class Val, class BV, unsigned MAX_SIZE>
2088{
2089 if constexpr (is_signed())
2090 {
2091 if (v < 0)
2092 {
2093 // the +1 trick is to get abs of INT_MIN without overflowing
2094 // https://stackoverflow.com/questions/22268815/absolute-value-of-int-min
2095 value_type uv = -(v+1);
2096 return 1u | unsigned_value_type((unsigned_value_type(uv) << 1u));
2097 }
2099 }
2100 else
2101 return v;
2102}
2103
2104//---------------------------------------------------------------------
2105
2106template<class Val, class BV, unsigned MAX_SIZE>
2109{
2110 if constexpr (is_signed())
2111 {
2112 if (uv & 1u) // signed
2113 {
2114 value_type s = (-(uv >> 1u)) - 1;
2115 return s;
2116 }
2117 return value_type(uv >> 1u);
2118 }
2119 else
2120 return uv;
2121}
2122#ifdef _MSC_VER
2123#pragma warning( pop )
2124#endif
2125
2126
2127} // namespace
2128
2129#endif
Compressed bit-vector bvector<> container, set algebraic methods, traversal iterators.
#define BM_DECLARE_TEMP_BLOCK(x)
Definition bm.h:47
Constants, lookup tables and typedefs.
Definitions(internal).
#define BMNOEXCEPT
Definition bmdef.h:82
#define BMGAP_PTR(ptr)
Definition bmdef.h:189
#define BM_IS_GAP(ptr)
Definition bmdef.h:191
#define BM_ASSERT
Definition bmdef.h:139
#define FULL_BLOCK_FAKE_ADDR
Definition bmdef.h:158
Utilities for bit transposition (internal) (experimental!).
void freeze_matr()
Turn on RO mode.
Definition bmbmatrix.h:633
bvector_type_const_ptr get_slice(unsigned i) const BMNOEXCEPT
get read-only access to bit-plane
Definition bmbmatrix.h:497
void swap(base_sparse_vector< Val, BV, MAX_SIZE > &bsv) BMNOEXCEPT
Definition bmbmatrix.h:1744
void resize(size_type new_size, bool set_null)
Definition bmbmatrix.h:1812
bm::null_support get_null_support() const BMNOEXCEPT
check if container supports NULL (unassigned) values
Definition bmbmatrix.h:444
unsigned effective_slices() const BMNOEXCEPT
Number of effective bit-planes in the value type.
Definition bmbmatrix.h:514
const bvector_type * bvector_type_const_ptr
Definition bmbmatrix.h:369
void merge_matr(bmatrix_type &bmatr)
Merge plane bvectors from an outside base matrix Note: outside base matrix gets destroyed.
Definition bmbmatrix.h:1705
static unsigned slices() BMNOEXCEPT
get total number of bit-planes in the vector
Definition bmbmatrix.h:503
static value_type u2s(unsigned_value_type v) BMNOEXCEPT
Convert unsigned value type to signed representation.
Definition bmbmatrix.h:2108
bvector_type * bvector_type_ptr
Definition bmbmatrix.h:368
const value_type & const_reference
Definition bmbmatrix.h:370
const bvector_type * get_null_bvector() const BMNOEXCEPT
Get bit-vector of assigned values or NULL (if not constructed that way).
Definition bmbmatrix.h:451
bvector_type_ptr slice(unsigned i) BMNOEXCEPT
get access to bit-plane as is (can return NULL)
Definition bmbmatrix.h:521
void copy_from(const base_sparse_vector< Val, BV, MAX_SIZE > &bsv)
Definition bmbmatrix.h:1663
static unsigned_value_type s2u(value_type v) BMNOEXCEPT
Convert signed value type to unsigned representation.
Definition bmbmatrix.h:2087
bvector_type::allocation_policy allocation_policy_type
Definition bmbmatrix.h:372
void set_allocator_pool(allocator_pool_type *pool_ptr) BMNOEXCEPT
Set allocation pool.
Definition bmbmatrix.h:468
void clear_range(size_type left, size_type right, bool set_null)
Definition bmbmatrix.h:1776
bvector_type_ptr get_create_slice(unsigned i)
get access to bit-plain, function checks and creates a plane
Definition bmbmatrix.h:1851
size_type size() const BMNOEXCEPT
Definition bmbmatrix.h:402
base_sparse_vector(const base_sparse_vector< Val, BV, MAX_SIZE > &bsv)
Definition bmbmatrix.h:1652
bool empty() const BMNOEXCEPT
Definition bmbmatrix.h:417
void free_slice(unsigned i)
free memory in bit-plane
Definition bmbmatrix.h:536
void optimize_block(block_idx_type nb, typename BV::optmode opt_mode)
plane index for the "NOT NULL" flags plane
Definition bmbmatrix.h:685
void erase_column(size_type idx, bool erase_null)
Definition bmbmatrix.h:1952
allocator_type::allocator_pool_type allocator_pool_type
Definition bmbmatrix.h:374
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())
Definition bmbmatrix.h:1632
void swap_elements(size_type idx1, size_type idx2)
swap two vector elements
Definition bmbmatrix.h:420
allocator_pool_type * get_allocator_pool() const BMNOEXCEPT
Get allocation pool.
Definition bmbmatrix.h:474
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
Definition bmbmatrix.h:391
bm::id64_t get_slice_mask(unsigned element_idx) const BMNOEXCEPT
Definition bmbmatrix.h:1870
static unsigned stored_slices() BMNOEXCEPT
Number of stored bit-planes (value planes + extra.
Definition bmbmatrix.h:508
static constexpr unsigned value_bits() BMNOEXCEPT
Number of total bit-planes in the value type.
Definition bmbmatrix.h:678
bool is_null(size_type idx) const BMNOEXCEPT
test if specified element is NULL
Definition bmbmatrix.h:1830
void bit_and_rows(const bvector_type &bv)
Set AND (intersect) operation on all existing bit-slices.
Definition bmbmatrix.h:672
void keep_range_no_check(size_type left, size_type right, bm::null_support slice_null)
Definition bmbmatrix.h:1798
std::make_unsigned< value_type >::type unsigned_value_type
Definition bmbmatrix.h:376
const bmatrix_type & get_bmatrix() const BMNOEXCEPT
Definition bmbmatrix.h:553
bvector_type * get_null_bvect() BMNOEXCEPT
Definition bmbmatrix.h:525
void mark_null_idx(unsigned null_idx) BMNOEXCEPT
Set NULL plain index.
Definition bmbmatrix.h:565
bvector_type_const_ptr slice(unsigned i) const BMNOEXCEPT
Definition bmbmatrix.h:522
BV::size_type size_type
Definition bmbmatrix.h:367
bvector_type::enumerator bvector_enumerator_type
Definition bmbmatrix.h:373
void sync_ro() BMNOEXCEPT
Sybc read-only state.
Definition bmbmatrix.h:2030
void bit_sub_rows(const bvector_type &bv, bool use_null)
Set SUB (MINUS) operation on all existing bit-slices.
Definition bmbmatrix.h:665
void clear_all(bool free_mem=true) BMNOEXCEPT
resize to zero, free memory
Definition bmbmatrix.h:1759
bmatrix_type & get_bmatrix() BMNOEXCEPT
access to internal bit-matrix
Definition bmbmatrix.h:559
bm::basic_bmatrix< BV > bmatrix_type
Definition bmbmatrix.h:375
BV::allocator_type allocator_type
Definition bmbmatrix.h:371
static constexpr bool is_signed() BMNOEXCEPT
returns true if value type is signed integral type
Definition bmbmatrix.h:433
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
Definition bmbmatrix.h:1888
void insert_null(size_type idx, bool not_null)
Definition bmbmatrix.h:1840
void clear_value_planes_from(unsigned plane_idx, size_type idx)
Definition bmbmatrix.h:1934
void calc_stat(typename bvector_type::statistics *st) const BMNOEXCEPT
Calculates memory statistics.
Definition bmbmatrix.h:1918
bool is_nullable() const BMNOEXCEPT
check if container supports NULL(unassigned) values
Definition bmbmatrix.h:439
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
Definition bmbmatrix.h:1961
void insert_clear_value_planes_from(unsigned plane_idx, size_type idx)
Definition bmbmatrix.h:1943
bvector_type::block_idx_type block_idx_type
Definition bmbmatrix.h:675
Basic dense bit-matrix class.
Definition bmbmatrix.h:56
void insert_octet(size_type pos, size_type octet_idx, unsigned char octet)
Definition bmbmatrix.h:1232
void insert_column(size_type idx, size_type row_from)
Definition bmbmatrix.h:848
bvector_type::block_idx_type block_idx_type
Definition bmbmatrix.h:65
void swap(basic_bmatrix< BV > &bbm) BMNOEXCEPT
Definition bmbmatrix.h:1024
~basic_bmatrix() BMNOEXCEPT
Definition bmbmatrix.h:734
bvector_type * bvector_type_ptr
Definition bmbmatrix.h:59
bvector_type_ptr * bv_rows_
Definition bmbmatrix.h:337
allocator_type alloc_
Definition bmbmatrix.h:333
void swap_columns(size_type idx1, size_type idx2)
Definition bmbmatrix.h:870
bool is_dynamic_
if rsize is dynamic (variable length)
Definition bmbmatrix.h:339
void set_allocator_pool(allocator_pool_type *pool_ptr) BMNOEXCEPT
Definition bmbmatrix.h:965
void set_null_idx(size_type null_idx) BMNOEXCEPT
set index of the NULL vector
Definition bmbmatrix.h:796
bvector_type_ptr construct_row(size_type row)
Definition bmbmatrix.h:1055
unsigned get_half_octet(size_type pos, size_type row_idx) const BMNOEXCEPT
Definition bmbmatrix.h:1484
BV::allocator_type allocator_type
Definition bmbmatrix.h:61
bvector_type::allocation_policy allocation_policy_type
Definition bmbmatrix.h:62
size_type null_idx_
Index of the NULL row.
Definition bmbmatrix.h:340
allocator_type::allocator_pool_type allocator_pool_type
Definition bmbmatrix.h:63
size_type get_null_idx() const BMNOEXCEPT
return index of the NULL vector
Definition bmbmatrix.h:162
void destruct_row(size_type row)
Definition bmbmatrix.h:1090
const bvector_type * bvector_type_const_ptr
Definition bmbmatrix.h:60
bvector_type * construct_bvector(const bvector_type *bv) const
Definition bmbmatrix.h:1122
const bm::word_t * get_block(size_type p, unsigned i, unsigned j) const BMNOEXCEPT
Get low level internal access to.
Definition bmbmatrix.h:1169
void bit_and_rows(const bvector_type &bv)
Set AND (intersect) operation on all existing rows.
Definition bmbmatrix.h:1012
basic_bmatrix< BV > & operator=(const basic_bmatrix< BV > &bbm)
Definition bmbmatrix.h:82
void calc_stat(typename bvector_type::statistics &st, size_type rsize) const BMNOEXCEPT
Definition bmbmatrix.h:1584
int compare_octet(size_type pos, size_type octet_idx, char octet) const BMNOEXCEPT
Definition bmbmatrix.h:1445
size_type rows_not_null() const BMNOEXCEPT
Definition bmbmatrix.h:143
size_type rsize_
Definition bmbmatrix.h:338
allocator_pool_type * pool_
Definition bmbmatrix.h:335
allocator_pool_type * get_allocator_pool() const BMNOEXCEPT
Definition bmbmatrix.h:106
void copy_from(const basic_bmatrix< BV > &bbm)
Definition bmbmatrix.h:806
bool is_same_structure(const basic_bmatrix< BV > &bbm) const BMNOEXCEPT
Debugging function to check if two matrixes have the same rows created.
Definition bmbmatrix.h:941
static void throw_bad_alloc()
Definition bmbmatrix.h:326
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
Definition bmbmatrix.h:1547
void clear_slices_range(unsigned slice_from, unsigned slize_until, size_type idx)
Clear bit-planes bit.
Definition bmbmatrix.h:1180
unsigned char octet_type
Definition bmbmatrix.h:66
void clear_column(size_type idx, size_type row_from)
Definition bmbmatrix.h:859
size_type bv_size_
Definition bmbmatrix.h:332
void clear_row(size_type row, bool free_mem)
Definition bmbmatrix.h:1103
bool is_dynamic() const BMNOEXCEPT
Return if matrix is dynamic resizable.
Definition bmbmatrix.h:310
const bvector_type * row(size_type i) const BMNOEXCEPT
Definition bmbmatrix.h:767
void allocate_rows(size_type rsize)
allocate matrix rows of bit-vectors (new rows are NULLs)
Definition bmbmatrix.h:880
void optimize_block(block_idx_type nb, typename BV::optmode opt_mode)
Definition bmbmatrix.h:1601
allocation_policy_type ap_
Definition bmbmatrix.h:334
size_type rows() const BMNOEXCEPT
Definition bmbmatrix.h:140
void destruct_bvector(bvector_type *bv) const
Definition bmbmatrix.h:1155
size_type calc_effective_rows_not_null() const BMNOEXCEPT
Definition bmbmatrix.h:981
void set_octet(size_type pos, size_type octet_idx, unsigned char octet)
Definition bmbmatrix.h:1193
void erase_column(size_type idx, bool erase_null)
Definition bmbmatrix.h:836
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())
Definition bmbmatrix.h:718
void bit_sub_rows(const bvector_type &bv, bool use_null)
Set SUB (MINUS) operation on all existing rows.
Definition bmbmatrix.h:999
size_type octet_size() const BMNOEXCEPT
Definition bmbmatrix.h:913
void free_rows() BMNOEXCEPT
Free all rows.
Definition bmbmatrix.h:923
friend class base_sparse_vector
Definition bmbmatrix.h:329
unsigned char get_octet(size_type pos, size_type octet_idx) const BMNOEXCEPT
Definition bmbmatrix.h:1295
bvector_type::size_type size_type
Definition bmbmatrix.h:64
bvector_type_const_ptr get_row(size_type i) const BMNOEXCEPT
Definition bmbmatrix.h:777
Constant iterator designed to enumerate "ON" bits.
Definition bm.h:603
optmode
Optimization mode Every next level means additional checks (better compression vs time).
Definition bm.h:133
@ opt_compress
compress blocks when possible (GAP/prefix sum)
Definition bm.h:137
blocks_manager< Alloc > blocks_manager_type
Definition bm.h:119
bvector_size_type size_type
Definition bm.h:121
void init()
Explicit post-construction initialization. Must be caled to make sure safe use of *_no_check() method...
Definition bm.h:2280
void copy_range(const bvector< Alloc > &bvect, size_type left, size_type right)
Copy all bits in the specified closed interval [left,right].
Definition bm.h:7981
blocks_manager_type::block_idx_type block_idx_type
Definition bm.h:120
null_support
NULL-able value support.
Definition bmconst.h:229
@ use_null
support "non-assigned" or "NULL" logic
Definition bmconst.h:230
@ no_null
do not support NULL values
Definition bmconst.h:231
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.
Definition bmfunc.h:1833
Definition bm.h:78
const unsigned id_max
Definition bmconst.h:109
unsigned int word_t
Definition bmconst.h:39
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.
Definition bmbmatrix.h:1472
const unsigned set_block_mask
Definition bmconst.h:57
BMFORCEINLINE void get_block_coord(BI_TYPE nb, unsigned &i, unsigned &j) BMNOEXCEPT
Recalc linear bvector block index into 2D matrix coordinates.
Definition bmfunc.h:180
bool check_any_fullb(const bm::word_t *blka[8], const bm::word_t *FBADDR)
Definition bmbmatrix.h:1279
const unsigned set_word_shift
Definition bmconst.h:72
BMFORCEINLINE void xor_swap(W &x, W &y) BMNOEXCEPT
XOR swap two variables.
Definition bmutil.h:534
unsigned long long int id64_t
Definition bmconst.h:35
const unsigned set_block_shift
Definition bmconst.h:56
const unsigned set_word_mask
Definition bmconst.h:73
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.
Definition bmbmatrix.h:1460
void reset() BMNOEXCEPT
Reset statisctics.
Definition bmfunc.h:94
void add(const bv_statistics &st) BMNOEXCEPT
Sum data from another sttructure.
Definition bmfunc.h:103
memory allocation policy
Definition bm.h:805
Statistical information about bitset's memory allocation details.
Definition bm.h:125
static TBVector * construct_bvector()
bm::bvector bvector_type