NCBI C++ ToolKit
bmbmatrix.h
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef BMBMATRIX__H__INCLUDED__
2 #define BMBMATRIX__H__INCLUDED__
3 /*
4 Copyright(c) 2002-2017 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
5 
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 
18 For 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 
40 namespace 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 */
54 template<typename BV>
56 {
57 public:
58  typedef BV bvector_type;
61  typedef typename BV::allocator_type allocator_type;
62  typedef typename bvector_type::allocation_policy allocation_policy_type;
63  typedef typename allocator_type::allocator_pool_type allocator_pool_type;
66  typedef unsigned char octet_type;
67 
68 public:
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 */
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 
107  { return pool_; }
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 */
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 */
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 */
166 
167  /** allocate matrix rows of bit-vectors (new rows are NULLs) */
169 
170  /** Free all rows */
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  */
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
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 
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  */
302 
303  /**
304  Set AND (intersect) operation on all existing rows
305  @param bv - argument vector row[i] &= bv
306  */
308 
309  /// Return if matrix is dynamic resizable
311 
312 
313  /// Debugging function to check if two matrixes have the same rows created
314  /// @return true - if the same
315  ///
317 
318  ///@}
319 
320 protected:
321 
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 
331 protected:
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 */
350 template<typename Val, typename BV, unsigned MAX_SIZE>
352 {
353 public:
355  {
356  sv_slices = (sizeof(Val) * 8 * MAX_SIZE + 1),
357  sv_value_slices = (sizeof(Val) * 8 * MAX_SIZE)
358  };
359 
361  {
362  max_vector_size = MAX_SIZE
363  };
364 
365  typedef Val value_type;
366  typedef BV bvector_type;
367  typedef typename BV::size_type size_type;
370  typedef const value_type& const_reference;
371  typedef typename BV::allocator_type allocator_type;
372  typedef typename bvector_type::allocation_policy allocation_policy_type;
373  typedef typename bvector_type::enumerator bvector_enumerator_type;
374  typedef typename allocator_type::allocator_pool_type allocator_pool_type;
377 
378 public:
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 
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 
423 public:
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
435 
436  /**
437  \brief check if container supports NULL(unassigned) values
438  */
440 
441  /**
442  \brief check if container supports NULL (unassigned) values
443  */
445  { return is_nullable() ? bm::use_null : bm::no_null; }
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  */
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  */
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,
593  typename bvector_type::optmode opt_mode = bvector_type::opt_compress,
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  */
607  void calc_stat(typename bvector_type::statistics* st) const BMNOEXCEPT;
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 
621 protected:
623 
624  /**
625  Merge plane bvectors from an outside base matrix
626  Note: outside base matrix gets destroyed
627  */
628  void merge_matr(bmatrix_type& bmatr);
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 
674 protected:
675  typedef typename bvector_type::block_idx_type block_idx_type;
676 
677  /** Number of total bit-planes in the value type*/
678  static constexpr unsigned value_bits() BMNOEXCEPT
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 
700 protected:
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 
717 template<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 
733 template<typename BV>
735 {
736  free_rows();
737 }
738 
739 //---------------------------------------------------------------------
740 
741 template<typename BV>
743 : bv_size_(bbm.bv_size_),
744  alloc_(bbm.alloc_),
745  ap_(bbm.ap_)
746 {
747  copy_from(bbm);
748  is_dynamic_ = bbm.is_dynamic_;
749 }
750 
751 //---------------------------------------------------------------------
752 
753 template<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 
765 template<typename BV>
766 const typename basic_bmatrix<BV>::bvector_type*
768 {
769  BM_ASSERT(i < rsize_);
770  return bv_rows_[i];
771 }
772 
773 //---------------------------------------------------------------------
774 
775 template<typename BV>
776 const typename basic_bmatrix<BV>::bvector_type*
778 {
779  BM_ASSERT(i < rsize_);
780  return bv_rows_[i];
781 }
782 
783 //---------------------------------------------------------------------
784 
785 template<typename BV>
788 {
789  BM_ASSERT(i < rsize_);
790  return bv_rows_[i];
791 }
792 
793 //---------------------------------------------------------------------
794 
795 template<typename BV>
797 {
798  BM_ASSERT(null_idx);
799  BM_ASSERT(get_row(null_idx));
800  null_idx_ = null_idx;
801 }
802 
803 //---------------------------------------------------------------------
804 
805 template<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_)
823  throw_bad_alloc();
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 
835 template<typename BV>
836 void basic_bmatrix<BV>::erase_column(size_type idx, bool erase_null)
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 
847 template<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 
858 template<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 
869 template<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 
879 template<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_)
890  throw_bad_alloc();
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 
911 template<typename BV>
914 {
915  size_type osize = (7 + rows_not_null()) / 8;
916  return osize;
917 }
918 
919 
920 //---------------------------------------------------------------------
921 
922 template<typename BV>
924 {
925  for (size_type i = 0; i < rsize_; ++i)
926  {
927  if (bvector_type_ptr bv = bv_rows_[i])
928  {
929  destruct_bvector(bv);
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 
940 template<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 
964 template<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 
979 template<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 
998 template<typename BV>
1000 {
1001  size_type sz = use_null ? rsize_: calc_effective_rows_not_null();
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 
1011 template<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 
1023 template<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 
1053 template<typename BV>
1056 {
1057  if (is_dynamic())
1058  {
1059  if (row >= rsize_)
1060  allocate_rows(rsize_ + 8);
1061  }
1062  BM_ASSERT(row < rsize_);
1063  bvector_type_ptr bv = bv_rows_[row];
1064  if (!bv)
1065  bv = bv_rows_[row] = construct_bvector(0);
1066  return bv;
1067 }
1068 
1069 //---------------------------------------------------------------------
1070 
1071 template<typename BV>
1074 {
1075  if (row >= rsize_)
1076  allocate_rows(row + 8);
1077  BM_ASSERT(row < rsize_);
1078  bvector_type_ptr bv = bv_rows_[row];
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 
1089 template<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 
1102 template<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 
1120 template<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 
1154 template<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 
1167 template<typename BV>
1168 const 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 
1179 template<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 
1192 template<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 
1231 template<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
1278 inline
1279 bool 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 
1293 template<typename BV>
1294 unsigned 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 
1444 template<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  */
1459 inline
1460 bool 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 */
1471 inline
1472 bool 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 
1482 template<typename BV>
1483 unsigned
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 
1546 template<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 
1573 template<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 
1583 template<typename BV>
1584 void basic_bmatrix<BV>::calc_stat(typename bvector_type::statistics& st,
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 
1600 template<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 
1624 template<class Val, class BV, unsigned MAX_SIZE>
1626 : bmatr_(sv_slices, true, allocation_policy_type(), bm::id_max, allocator_type())
1627 {}
1628 
1629 //---------------------------------------------------------------------
1630 
1631 template<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 
1651 template<class Val, class BV, unsigned MAX_SIZE>
1654 : bmatr_(bsv.bmatr_),
1655  slice_mask_(bsv.slice_mask_),
1656  size_(bsv.size_),
1657  effective_slices_(bsv.effective_slices_)
1658 {}
1659 
1660 //---------------------------------------------------------------------
1661 
1662 template<class Val, class BV, unsigned MAX_SIZE>
1665 {
1666  resize(bsv.size(), true);
1667  effective_slices_ = bsv.effective_slices_;
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 
1704 template<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 
1743 template<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 
1758 template<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 
1775 template<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 
1797 template<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 
1811 template<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 
1829 template<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 
1839 template<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 
1849 template<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_)
1862  effective_slices_ = i;
1863  }
1864  return bv;
1865 }
1866 
1867 //---------------------------------------------------------------------
1868 
1869 template<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 
1887 template<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 
1917 template<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 
1933 template<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 
1942 template<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 
1951 template<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 
1960 template<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 
2029 template<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 
2048 template<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 
2085 template<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  }
2098  return unsigned_value_type(unsigned_value_type(v) << 1u);
2099  }
2100  else
2101  return v;
2102 }
2103 
2104 //---------------------------------------------------------------------
2105 
2106 template<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
ncbi::TMaskedQueryRegions mask
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!)
Base class for bit-transposed(bit-sliced) sparse vector construction.
Definition: bmbmatrix.h:352
allocator_pool_type * get_allocator_pool() const noexcept
Get allocation pool.
Definition: bmbmatrix.h:474
void freeze_matr()
Turn on RO mode.
Definition: bmbmatrix.h:633
void clear_all(bool free_mem=true) noexcept
resize to zero, free memory
Definition: bmbmatrix.h:1759
bm::id64_t get_slice_mask(unsigned element_idx) const noexcept
Definition: bmbmatrix.h:1870
void resize(size_type new_size, bool set_null)
Definition: bmbmatrix.h:1812
unsigned_value_type slice_mask_
slice presence bit-mask
Definition: bmbmatrix.h:702
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
const bmatrix_type & get_bmatrix() const noexcept
Definition: bmbmatrix.h:553
bvector_type * bvector_type_ptr
Definition: bmbmatrix.h:368
const value_type & const_reference
Definition: bmbmatrix.h:370
void copy_from(const base_sparse_vector< Val, BV, MAX_SIZE > &bsv)
Definition: bmbmatrix.h:1663
bool empty() const noexcept
Definition: bmbmatrix.h:417
bvector_type_ptr slice(unsigned i) noexcept
get access to bit-plane as is (can return NULL)
Definition: bmbmatrix.h:521
bvector_type_const_ptr slice(unsigned i) const noexcept
Definition: bmbmatrix.h:522
bvector_type::allocation_policy allocation_policy_type
Definition: bmbmatrix.h:372
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
static constexpr unsigned value_bits() noexcept
Number of total bit-planes in the value type.
Definition: bmbmatrix.h:678
static unsigned slices() noexcept
get total number of bit-planes in the vector
Definition: bmbmatrix.h:503
static value_type u2s(unsigned_value_type v) noexcept
Convert unsigned value type to signed representation.
Definition: bmbmatrix.h:2108
size_type size() const noexcept
Definition: bmbmatrix.h:402
void sync_ro() noexcept
Sybc read-only state.
Definition: bmbmatrix.h:2030
base_sparse_vector(const base_sparse_vector< Val, BV, MAX_SIZE > &bsv)
Definition: bmbmatrix.h:1652
unsigned effective_slices() const noexcept
Number of effective bit-planes in the value type.
Definition: bmbmatrix.h:514
bool is_nullable() const noexcept
check if container supports NULL(unassigned) values
Definition: bmbmatrix.h:439
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
bool is_null(size_type idx) const noexcept
test if specified element is NULL
Definition: bmbmatrix.h:1830
unsigned effective_slices_
number of bit slices actually allocated
Definition: bmbmatrix.h:704
void calc_stat(typename bvector_type::statistics *st) const noexcept
Calculates memory statistics.
Definition: bmbmatrix.h:1918
bvector_type_const_ptr get_slice(unsigned i) const noexcept
get read-only access to bit-plane
Definition: bmbmatrix.h:497
bmatrix_type bmatr_
bit-transposed matrix
Definition: bmbmatrix.h:701
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
void swap(base_sparse_vector< Val, BV, MAX_SIZE > &bsv) noexcept
Definition: bmbmatrix.h:1744
bool is_ro_
read-only
Definition: bmbmatrix.h:705
bmatrix_type & get_bmatrix() noexcept
access to internal bit-matrix
Definition: bmbmatrix.h:559
static unsigned_value_type s2u(value_type v) noexcept
Convert signed value type to unsigned representation.
Definition: bmbmatrix.h:2087
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)
Perform copy_range() on a set of planes.
Definition: bmbmatrix.h:2049
void set_allocator_pool(allocator_pool_type *pool_ptr) noexcept
Set allocation pool.
Definition: bmbmatrix.h:468
size_type size_
array size
Definition: bmbmatrix.h:703
void bit_and_rows(const bvector_type &bv)
Set AND (intersect) operation on all existing bit-slices.
Definition: bmbmatrix.h:672
bool equal(const base_sparse_vector< Val, BV, MAX_SIZE > &sv, bm::null_support null_able=bm::use_null) const noexcept
check if another sparse vector has the same content and size
Definition: bmbmatrix.h:1961
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
BV::size_type size_type
Definition: bmbmatrix.h:367
bvector_type::enumerator bvector_enumerator_type
Definition: bmbmatrix.h:373
void bit_sub_rows(const bvector_type &bv, bool use_null)
Set SUB (MINUS) operation on all existing bit-slices.
Definition: bmbmatrix.h:665
bm::basic_bmatrix< BV > bmatrix_type
Definition: bmbmatrix.h:375
static constexpr bool is_signed() noexcept
returns true if value type is signed integral type
Definition: bmbmatrix.h:433
static unsigned stored_slices() noexcept
Number of stored bit-planes (value planes + extra.
Definition: bmbmatrix.h:508
const bvector_type * get_null_bvector() const noexcept
Get bit-vector of assigned values or NULL (if not constructed that way)
Definition: bmbmatrix.h:451
bm::null_support get_null_support() const noexcept
check if container supports NULL (unassigned) values
Definition: bmbmatrix.h:444
base_sparse_vector(base_sparse_vector< Val, BV, MAX_SIZE > &&bsv) noexcept
Definition: bmbmatrix.h:391
bvector_type * get_null_bvect() noexcept
Definition: bmbmatrix.h:525
BV::allocator_type allocator_type
Definition: bmbmatrix.h:371
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 mark_null_idx(unsigned null_idx) noexcept
Set NULL plain index.
Definition: bmbmatrix.h:565
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
allocator_pool_type * get_allocator_pool() const noexcept
Definition: bmbmatrix.h:106
unsigned char get_octet(size_type pos, size_type octet_idx) const noexcept
Definition: bmbmatrix.h:1295
bvector_type::block_idx_type block_idx_type
Definition: bmbmatrix.h:65
basic_bmatrix< BV > & operator=(const basic_bmatrix< BV > &bbm)
Definition: bmbmatrix.h:82
int compare_octet(size_type pos, size_type octet_idx, char octet) const noexcept
Definition: bmbmatrix.h:1445
bool is_same_structure(const basic_bmatrix< BV > &bbm) const noexcept
Debugging function to check if two matrixes have the same rows created.
Definition: bmbmatrix.h:941
void set_allocator_pool(allocator_pool_type *pool_ptr) noexcept
Definition: bmbmatrix.h:965
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 swap(basic_bmatrix< BV > &bbm) noexcept
Definition: bmbmatrix.h:1024
unsigned get_half_octet(size_type pos, size_type row_idx) const noexcept
Definition: bmbmatrix.h:1484
bvector_type_ptr construct_row(size_type row)
Definition: bmbmatrix.h:1055
void set_null_idx(size_type null_idx) noexcept
set index of the NULL vector
Definition: bmbmatrix.h:796
const bvector_type * row(size_type i) const noexcept
Definition: bmbmatrix.h:767
void calc_stat(typename bvector_type::statistics &st, size_type rsize) const noexcept
Definition: bmbmatrix.h:1584
size_type rows_not_null() const noexcept
Definition: bmbmatrix.h:143
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
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 noexcept
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
size_type rsize_
Definition: bmbmatrix.h:338
allocator_pool_type * pool_
Definition: bmbmatrix.h:335
void free_rows() noexcept
Free all rows.
Definition: bmbmatrix.h:923
void copy_from(const basic_bmatrix< BV > &bbm)
Definition: bmbmatrix.h:806
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
~basic_bmatrix() noexcept
Definition: bmbmatrix.h:734
bvector_type * get_row(size_type i) noexcept
Definition: bmbmatrix.h:787
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
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
size_type calc_effective_rows_not_null() const noexcept
Definition: bmbmatrix.h:981
allocation_policy_type ap_
Definition: bmbmatrix.h:334
bvector_type_const_ptr get_row(size_type i) const noexcept
Definition: bmbmatrix.h:777
void destruct_bvector(bvector_type *bv) const
Definition: bmbmatrix.h:1155
size_type octet_size() const noexcept
Definition: bmbmatrix.h:913
void set_octet(size_type pos, size_type octet_idx, unsigned char octet)
Definition: bmbmatrix.h:1193
bool is_dynamic() const noexcept
Return if matrix is dynamic resizable.
Definition: bmbmatrix.h:310
void erase_column(size_type idx, bool erase_null)
Definition: bmbmatrix.h:836
basic_bmatrix(basic_bmatrix< BV > &&bbm) noexcept
Definition: bmbmatrix.h:754
size_type get_null_idx() const noexcept
return index of the NULL vector
Definition: bmbmatrix.h:162
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 rows() const noexcept
Definition: bmbmatrix.h:140
bvector_type::size_type size_type
Definition: bmbmatrix.h:64
bvector_size_type size_type
Definition: bm.h:121
blocks_manager_type::block_idx_type block_idx_type
Definition: bm.h:120
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
#define bool
Definition: bool.h:34
static int type
Definition: getdata.c:31
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
unsigned int uintptr_t
Definition: ncbitype.h:197
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 *buf, const unsigned pos) noexcept
Tests if bit = pos is true. Analog of bm::gap_test with SIMD unrolling.
Definition: bmfunc.h:1833
int i
#include<zmmintrin.h>
Definition: bm.h:78
bool test_4gaps(const bm::word_t *p0, const bm::word_t *p1, const bm::word_t *p2, const bm::word_t *p3) noexcept
Test 4 pointers are all marked as GAPs.
Definition: bmbmatrix.h:1460
const unsigned id_max
Definition: bmconst.h:109
void xor_swap(W &x, W &y) noexcept
XOR swap two variables.
Definition: bmutil.h:534
unsigned int word_t
Definition: bmconst.h:39
const unsigned set_block_mask
Definition: bmconst.h:57
void get_block_coord(BI_TYPE nb, unsigned &i, unsigned &j) noexcept
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
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_4bits(const bm::word_t *p0, const bm::word_t *p1, const bm::word_t *p2, const bm::word_t *p3) noexcept
Test 4 pointers are not NULL and not marked as FULLBLOCK.
Definition: bmbmatrix.h:1472
double value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:228
const struct ncbi::grid::netcache::search::fields::SIZE size
void resize(vector< SMethodDef > &container)
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
bool eq(T x_, T y_, T round_)
Definition: njn_approx.hpp:79
static SLJIT_INLINE sljit_ins st(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
#define row(bind, expected)
Definition: string_bind.c:73
#define const
Definition: zconf.h:232
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Fri Sep 20 14:57:24 2024 by modify_doxy.py rev. 669887