BitMagic-C++
bmsparsevec_compr.h
Go to the documentation of this file.
1 #ifndef BMSPARSEVEC_COMPR_H__INCLUDED__
2 #define BMSPARSEVEC_COMPR_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 bmsparsevec_compr.h
22  \brief Compressed sparse container rsc_sparse_vector<> for integer types
23 */
24 
25 #include <memory.h>
26 
27 #ifndef BM_NO_STL
28 #include <stdexcept>
29 #endif
30 
31 #ifndef BM__H__INCLUDED__
32 // BitMagic utility headers do not include main "bm.h" declaration
33 // #include "bm.h" or "bm64.h" explicitly
34 # error missing include (bm.h or bm64.h)
35 #endif
36 
37 
38 #include "bmsparsevec.h"
39 #include "bmdef.h"
40 
41 namespace bm
42 {
43 
44 
45 /*!
46  \brief Rank-Select compressed sparse vector
47 
48  Container uses Rank-Select method of compression, where
49  all NULL columns gets dropped, effective address of columns is computed
50  using address bit-vector.
51 
52  Use for cases, where memory efficiency is preferable over
53  single element access latency.
54 
55  \ingroup sv
56 */
57 template<class Val, class SV>
59 {
60 public:
62  {
63  sv_plains = (sizeof(Val) * 8 + 1),
64  sv_value_plains = (sizeof(Val) * 8)
65  };
66 
67  typedef Val value_type;
68  typedef const value_type& const_reference;
69  typedef typename SV::size_type size_type;
70  typedef SV sparse_vector_type;
71  typedef typename SV::const_iterator sparse_vector_const_iterator;
72  typedef typename SV::bvector_type bvector_type;
73  typedef bvector_type* bvector_type_ptr;
74  typedef const bvector_type* bvector_type_const_ptr;
79 
81  {
83  };
84 
85  struct is_remap_support { enum trait { value = false }; };
86  struct is_rsc_support { enum trait { value = true }; };
87 
88 public:
89  /*! Statistical information about memory allocation details. */
90  struct statistics : public bv_statistics
91  {};
92 
93 public:
94  /**
95  Reference class to access elements via common [] operator
96  */
97  class reference
98  {
99  public:
101  : csv_(csv), idx_(idx)
102  {}
103  operator value_type() const { return csv_.get(idx_); }
104  bool operator==(const reference& ref) const
105  { return bool(*this) == bool(ref); }
106  bool is_null() const { return csv_.is_null(idx_); }
107  private:
109  size_type idx_;
110  };
111 
112 public:
113  // ------------------------------------------------------------
114  /*! @name Construction and assignment */
115  //@{
116 
118  allocation_policy_type ap = allocation_policy_type(),
119  size_type bv_max_size = bm::id_max,
120  const allocator_type& alloc = allocator_type());
122 
123  /*! copy-ctor */
125 
126 
127  /*! copy assignmment operator */
129  {
130  if (this != &csv)
131  {
132  sv_ = csv.sv_;
133  max_id_ = csv.max_id_;
134  in_sync_ = csv.in_sync_;
135  if (in_sync_)
136  {
137  bv_blocks_ptr_->copy_from(*(csv.bv_blocks_ptr_));
138  }
139  }
140  return *this;
141  }
142 
143 #ifndef BM_NO_CXX11
144  /*! move-ctor */
146 
147  /*! move assignmment operator */
149  {
150  if (this != &csv)
151  {
152  clear();
153  sv_.swap(csv.sv_);
154  max_id_ = csv.max_id_; in_sync_ = csv.in_sync_;
155  if (in_sync_)
156  {
157  bv_blocks_ptr_->copy_from(*(csv.bv_blocks_ptr_));
158  }
159  }
160  return *this;
161  }
162 #endif
163 
164  //@}
165  // ------------------------------------------------------------
166  /*! @name Size, etc */
167  ///@{
168 
169  /*! \brief return size of the vector
170  \return size of sparse vector
171  */
172  size_type size() const;
173 
174  /*! \brief return true if vector is empty
175  \return true if empty
176  */
177  bool empty() const { return sv_.empty(); }
178 
179  ///@}
180 
181  // ------------------------------------------------------------
182  /*! @name Element access */
183  //@{
184 
185  /*!
186  \brief get specified element without bounds checking
187  \param idx - element index
188  \return value of the element
189  */
190  value_type operator[](size_type idx) const { return this->get(idx); }
191 
192  /*!
193  \brief access specified element with bounds checking
194  \param idx - element index
195  \return value of the element
196  */
197  value_type at(size_type idx) const;
198 
199  /*!
200  \brief get specified element without bounds checking
201  \param idx - element index
202  \return value of the element
203  */
204  value_type get(size_type idx) const;
205 
206  /*!
207  \brief set specified element with bounds checking and automatic resize
208 
209  Method cannot insert elements, so every new idx has to be greater or equal
210  than what it used before. Elements must be loaded in a sorted order.
211 
212  \param idx - element index
213  \param v - element value
214  */
215  void push_back(size_type idx, value_type v);
216 
217  /*!
218  \brief set specified element with bounds checking and automatic resize
219  \param idx - element index
220  \param v - element value
221  */
222  void set(size_type idx, value_type v);
223 
224  /*!
225  \brief set specified element to NULL
226  RSC vector actually erases element when it is set to NULL (expensive).
227  \param idx - element index
228  */
229  void set_null(size_type idx);
230 
231 
232 
233  /** \brief test if specified element is NULL
234  \param idx - element index
235  \return true if it is NULL false if it was assigned or container
236  is not configured to support assignment flags
237  */
238  bool is_null(size_type idx) const;
239 
240  /**
241  \brief Get bit-vector of assigned values (or NULL)
242  */
243  const bvector_type* get_null_bvector() const;
244 
245  /**
246  \brief find position of compressed element by its rank
247  \param rank - rank (virtual index in sparse vector)
248  \param idx - index (true position)
249  */
250  bool find_rank(size_type rank, size_type& idx) const;
251 
252  //@}
253 
254  // ------------------------------------------------------------
255  /*! @name Export content to C-stype array */
256  ///@{
257 
258  size_type decode(value_type* arr,
259  size_type idx_from,
260  size_type size,
261  bool zero_mem = true) const;
262 
263  ///@}
264 
265 
266  // ------------------------------------------------------------
267  /*! @name Various traits */
268  //@{
269  /**
270  \brief if container supports NULL(unassigned) values (true)
271  */
272  bool is_nullable() const { return true; }
273 
274  /** \brief trait if sparse vector is "compressed" (true)
275  */
276  static
277  bool is_compressed() { return true; }
278 
279  ///@}
280 
281 
282  // ------------------------------------------------------------
283  /*! @name Comparison */
284  //@{
285 
286  /*!
287  \brief check if another vector has the same content
288  \return true, if it is the same
289  */
290  bool equal(const rsc_sparse_vector<Val, SV>& csv) const;
291  //@}
292 
293 
294  // ------------------------------------------------------------
295  /*! @name Load-Export compressed vector with data */
296 
297  //@{
298 
299 
300  /*!
301  \brief Load compressed vector from a sparse vector (with NULLs)
302  \param sv_src - source sparse vector
303  */
304  void load_from(const sparse_vector_type& sv_src);
305 
306  /*!
307  \brief Exort compressed vector to a sparse vector (with NULLs)
308  \param sv - target sparse vector
309  */
310  void load_to(sparse_vector_type& sv) const;
311 
312  //@}
313 
314  // ------------------------------------------------------------
315  /*! @name Memory optimization */
316  ///@{
317 
318  /*!
319  \brief run memory optimization for all vector plains
320  \param temp_block - pre-allocated memory block to avoid unnecessary re-allocs
321  \param opt_mode - requested compression depth
322  \param stat - memory allocation statistics after optimization
323  */
324  void optimize(bm::word_t* temp_block = 0,
326  statistics* stat = 0);
327 
328  /*! \brief resize to zero, free memory
329  */
330  void clear() BMNOEXEPT;
331 
332  /*!
333  @brief Calculates memory statistics.
334 
335  Function fills statistics structure containing information about how
336  this vector uses memory and estimation of max. amount of memory
337  bvector needs to serialize itself.
338 
339  @param st - pointer on statistics structure to be filled in.
340 
341  @sa statistics
342  */
343  void calc_stat(struct rsc_sparse_vector<Val, SV>::statistics* st) const;
344 
345  ///@}
346 
347 
348  // ------------------------------------------------------------
349  /*! @name Fast access structues sync */
350  //@{
351  /*!
352  \brief Re-calculate prefix sum table used for rank search
353  \param force - force recalculation even if it is already recalculated
354  */
355  void sync(bool force);
356 
357  /*!
358  \brief Re-calculate prefix sum table used for rank search (if necessary)
359  */
360  void sync() { sync(false); }
361 
362  /*!
363  \brief returns true if prefix sum table is in sync with the vector
364  */
365  bool in_sync() const { return in_sync_; }
366 
367  /*!
368  \brief Unsync the prefix sum table
369  */
370  void unsync() { in_sync_ = false; }
371  ///@}
372 
373  // ------------------------------------------------------------
374  /*! @name Access to internals */
375  ///@{
376 
377  /*!
378  \brief get access to bit-plain, function checks and creates a plain
379  \return bit-vector for the bit plain
380  */
381  bvector_type_const_ptr get_plain(unsigned i) const { return sv_.get_plain(i); }
382 
383  bvector_type_ptr get_plain(unsigned i) { return sv_.get_plain(i); }
384 
385  /*!
386  Number of effective bit-plains in the value type
387  */
388  unsigned effective_plains() const { return sv_.effective_plains(); }
389 
390  /*!
391  \brief get total number of bit-plains in the vector
392  */
393  static unsigned plains() { return sparse_vector_type::plains(); }
394 
395  /** Number of stored bit-plains (value plains + extra */
396  static unsigned stored_plains() { return sparse_vector_type::stored_plains(); }
397 
398  /*!
399  \brief access dense vector
400  */
401  const sparse_vector_type& get_sv() const { return sv_; }
402 
403  /*!
404  \brief size of internal dense vector
405  */
406  size_type effective_size() const { return sv_.size(); }
407 
408  /**
409  \brief Always 1 (non-matrix type)
410  */
411  size_type effective_vector_max() const { return 1; }
412 
413  ///@}
414 
415 protected:
417  {
419  };
420 
421  /*!
422  \brief Resolve logical address to access via rank compressed address
423 
424  \param idx - input id to resolve
425  \param idx_to - output id
426 
427  \return true if id is known and resolved successfully
428  */
429  bool resolve(size_type idx, size_type* idx_to) const;
430 
431  void resize_internal(size_type sz) { sv_.resize_internal(sz); }
432  size_type size_internal() const { return sv_.size(); }
433 
434  bool is_remap() const { return false; }
435  size_t remap_size() const { return 0; }
436  const unsigned char* get_remap_buffer() const { return 0; }
437  unsigned char* init_remap_buffer() { return 0; }
438  void set_remap() { }
439 
440  void push_back_no_check(size_type idx, value_type v);
441 
442 
443 private:
444  void construct_bv_blocks();
445  void free_bv_blocks();
446 
447 protected:
448  template<class SVect> friend class sparse_vector_scanner;
449  template<class SVect> friend class sparse_vector_serializer;
450  template<class SVect> friend class sparse_vector_deserializer;
451 
452 private:
453  sparse_vector_type sv_; ///< transpose-sparse vector for "dense" packing
454  size_type max_id_; ///< control variable for sorted load
455  bool in_sync_; ///< flag if prefix sum is in-sync with vector
456  rs_index_type* bv_blocks_ptr_ = 0; ///< prefix sum for rank translation
457 };
458 
459 //---------------------------------------------------------------------
460 //---------------------------------------------------------------------
461 
462 template<class Val, class SV>
465  size_type bv_max_size,
466  const allocator_type& alloc)
467 : sv_(null_able, ap, bv_max_size, alloc),
468  max_id_(0), in_sync_(false)
469 {
470  BM_ASSERT(null_able == bm::use_null);
471  BM_ASSERT(int(sv_value_plains) == int(SV::sv_value_plains));
472 
473  construct_bv_blocks();
474 }
475 
476 //---------------------------------------------------------------------
477 
478 template<class Val, class SV>
480 {
481  free_bv_blocks();
482 }
483 
484 //---------------------------------------------------------------------
485 
486 template<class Val, class SV>
488  const rsc_sparse_vector<Val, SV>& csv)
489 : sv_(csv.sv_),
490  max_id_(csv.max_id_),
491  in_sync_(csv.in_sync_)
492 {
493  BM_ASSERT(int(sv_value_plains) == int(SV::sv_value_plains));
494 
495  construct_bv_blocks();
496  if (in_sync_)
497  {
498  bv_blocks_ptr_->copy_from(*(csv.bv_blocks_ptr_));
499  }
500 }
501 
502 //---------------------------------------------------------------------
503 
504 template<class Val, class SV>
506 : sv_(bm::use_null),
507  max_id_(0), in_sync_(false)
508 {
509  if (this != &csv)
510  {
511  sv_.swap(csv.sv_);
512  max_id_ = csv.max_id_; in_sync_ = csv.in_sync_;
513 
514  bv_blocks_ptr_ = csv.bv_blocks_ptr_; csv.bv_blocks_ptr_ = 0;
515  }
516 }
517 
518 //---------------------------------------------------------------------
519 
520 template<class Val, class SV>
523 {
524  return max_id_+1;
525 }
526 
527 //---------------------------------------------------------------------
528 
529 template<class Val, class SV>
531 {
532  if (sv_.empty())
533  {}
534  else
535  if (idx <= max_id_)
536  {
537  sv_.throw_range_error("compressed sparse vector push_back() range error");
538  }
539  push_back_no_check(idx, v);
540 }
541 
542 //---------------------------------------------------------------------
543 
544 template<class Val, class SV>
546 {
547  bvector_type* bv_null = sv_.get_null_bvect();
548  BM_ASSERT(bv_null);
549 
550  bv_null->set_bit_no_check(idx);
551  sv_.push_back_no_null(v);
552 
553  max_id_ = idx;
554  in_sync_ = false;
555 }
556 
557 //---------------------------------------------------------------------
558 
559 template<class Val, class SV>
561 {
562  bvector_type* bv_null = sv_.get_null_bvect();
563  BM_ASSERT(bv_null);
564 
565  bool found = bv_null->test(idx);
566  if (found)
567  {
568  size_type sv_idx = bv_null->count_range(0, idx);
569  bv_null->clear_bit_no_check(idx);
570  sv_.erase(--sv_idx);
571  }
572 }
573 
574 //---------------------------------------------------------------------
575 
576 template<class Val, class SV>
578 {
579  bvector_type* bv_null = sv_.get_null_bvect();
580  BM_ASSERT(bv_null);
581 
582  bool found = bv_null->test(idx);
583  size_type sv_idx = bv_null->count_range(0, idx); // TODO: make test'n'count
584 
585  if (found)
586  {
587  sv_.set(--sv_idx, v);
588  }
589  else
590  {
591  sv_.insert_value_no_null(sv_idx, v);
592  bv_null->set_bit_no_check(idx);
593 
594  if (idx > max_id_)
595  max_id_ = idx;
596  in_sync_ = false;
597  }
598 }
599 
600 //---------------------------------------------------------------------
601 
602 template<class Val, class SV>
604  const rsc_sparse_vector<Val, SV>& csv) const
605 {
606  if (this == &csv)
607  return true;
608  if (max_id_ != csv.max_id_)
609  return false;
610  bool same_sv = sv_.equal(csv.sv_);
611  return same_sv;
612 }
613 
614 //---------------------------------------------------------------------
615 
616 template<class Val, class SV>
618  const sparse_vector_type& sv_src)
619 {
620  max_id_ = 0;
621 
622  bvector_type* bv_null = sv_.get_null_bvect();
623  BM_ASSERT(bv_null);
624 
625  const bvector_type* bv_null_src = sv_src.get_null_bvector();
626  if (!bv_null_src) // dense vector (no NULL columns)
627  {
628  sv_ = sv_src;
629  BM_ASSERT(sv_.get_null_bvect());
630  }
631  else
632  {
633  sv_.clear();
634  *bv_null = *bv_null_src;
635 
636  bm::rank_compressor<bvector_type> rank_compr; // re-used for plains
637 
638  unsigned src_plains = sv_src.plains();
639  for (unsigned i = 0; i < src_plains; ++i)
640  {
641  const bvector_type* bv_src_plain = sv_src.get_plain(i);
642  if (bv_src_plain)
643  {
644  bvector_type* bv_plain = sv_.get_plain(i);
645  rank_compr.compress(*bv_plain, *bv_null, *bv_src_plain);
646  }
647  } // for
648  size_type count = bv_null->count(); // set correct sizes
649  sv_.resize(count);
650  }
651 
652  sync(true);
653 }
654 
655 //---------------------------------------------------------------------
656 
657 template<class Val, class SV>
659 {
660  sv.clear();
661 
662  const bvector_type* bv_null_src = this->get_null_bvector();
663  if (!bv_null_src)
664  {
665  BM_ASSERT(bv_null_src);
666  return;
667  }
668 
669  bvector_type* bv_null = sv.get_null_bvect();
670  BM_ASSERT(bv_null);
671  *bv_null = *bv_null_src;
672 
673  bm::rank_compressor<bvector_type> rank_compr; // re-used for plains
674 
675  unsigned src_plains = sv_.plains();
676  for (unsigned i = 0; i < src_plains; ++i)
677  {
678  const bvector_type* bv_src_plain = sv_.get_plain(i);
679  if (bv_src_plain)
680  {
681  bvector_type* bv_plain = sv.get_plain(i);
682  rank_compr.decompress(*bv_plain, *bv_null, *bv_src_plain);
683  }
684  } // for
685  sv.resize(this->size());
686 }
687 
688 //---------------------------------------------------------------------
689 
690 template<class Val, class SV>
692 {
693  if (in_sync_ && force == false)
694  return; // nothing to do
695  const bvector_type* bv_null = sv_.get_null_bvector();
696  BM_ASSERT(bv_null);
697  bv_null->build_rs_index(bv_blocks_ptr_); // compute popcount prefix list
698 
699  // sync the max-id
700  bool found = bv_null->find_reverse(max_id_);
701  if (!found)
702  {
703  BM_ASSERT(!bv_null->any());
704  max_id_ = 0;
705  }
706  in_sync_ = true;
707 }
708 
709 //---------------------------------------------------------------------
710 
711 template<class Val, class SV>
713 {
714  BM_ASSERT(idx_to);
715 
716  const bvector_type* bv_null = sv_.get_null_bvector();
717  if (in_sync_)
718  {
719  *idx_to = bv_null->count_to_test(idx, *bv_blocks_ptr_);
720  }
721  else // slow access
722  {
723  bool found = bv_null->test(idx);
724  if (!found)
725  {
726  *idx_to = 0;
727  }
728  else
729  {
730  *idx_to = bv_null->count_range(0, idx);
731  }
732  }
733  return bool(*idx_to);
734 }
735 
736 //---------------------------------------------------------------------
737 
738 template<class Val, class SV>
741 {
742  size_type sv_idx;
743  bool found = resolve(idx, &sv_idx);
744  if (!found)
745  {
746  sv_.throw_range_error("compressed collection item not found");
747  }
748  return sv_.at(--sv_idx);
749 }
750 
751 //---------------------------------------------------------------------
752 
753 template<class Val, class SV>
756 {
757  size_type sv_idx;
758  bool found = resolve(idx, &sv_idx);
759  if (!found)
760  return value_type();
761 
762  return sv_.get(--sv_idx);
763 }
764 
765 //---------------------------------------------------------------------
766 
767 template<class Val, class SV>
769 {
770  const bvector_type* bv_null = sv_.get_null_bvector();
771  BM_ASSERT(bv_null);
772  return !(bv_null->test(idx));
773 }
774 
775 //---------------------------------------------------------------------
776 
777 template<class Val, class SV>
779  typename bvector_type::optmode opt_mode,
780  statistics* st)
781 {
782  sv_.optimize(temp_block, opt_mode, (typename sparse_vector_type::statistics*)st);
783  if (st)
784  {
785  st->memory_used += sizeof(rs_index_type);
786  st->memory_used += bv_blocks_ptr_->get_total() *
787  (sizeof(typename rs_index_type::size_type)
788  + sizeof(typename rs_index_type::sb_pair_type));
789  }
790 }
791 
792 //---------------------------------------------------------------------
793 
794 template<class Val, class SV>
796 {
797  sv_.clear();
798  in_sync_ = false; max_id_ = 0;
799 }
800 
801 //---------------------------------------------------------------------
802 
803 template<class Val, class SV>
806 {
807  BM_ASSERT(st);
808  sv_.calc_stat((typename sparse_vector_type::statistics*)st);
809  if (st)
810  {
811  st->memory_used += sizeof(rs_index_type);
812  st->memory_used += bv_blocks_ptr_->get_total() *
813  (sizeof(typename rs_index_type::size_type)
814  + sizeof(typename rs_index_type::sb_pair_type));
815  }
816 }
817 
818 //---------------------------------------------------------------------
819 
820 template<class Val, class SV>
823 {
824  return sv_.get_null_bvector();
825 }
826 
827 //---------------------------------------------------------------------
828 
829 template<class Val, class SV>
830 bool
832 {
833  BM_ASSERT(rank);
834  bool b;
835  const bvector_type* bv_null = get_null_bvector();
836  if (in_sync())
837  b = bv_null->select(rank, idx, *bv_blocks_ptr_);
838  else
839  b = bv_null->find_rank(rank, 0, idx);
840  return b;
841 }
842 
843 //---------------------------------------------------------------------
844 
845 
846 template<class Val, class SV>
849  size_type idx_from,
850  size_type size,
851  bool /*zero_mem*/) const
852 {
853  BM_ASSERT(arr);
854  BM_ASSERT(in_sync_); // call sync() before decoding
855  BM_ASSERT(bv_blocks_ptr_);
856 
857  if (size == 0)
858  return 0;
859  if (idx_from >= this->size())
860  return 0;
861 
862  if ((bm::id_max - size) <= idx_from)
863  size = bm::id_max - idx_from;
864 
865  const bvector_type* bv_null = sv_.get_null_bvector();
866 
867  size_type rank = bv_null->count_to(idx_from, *bv_blocks_ptr_);
868  bool b = bv_null->test(idx_from);
869 
870  bvector_enumerator_type en_i = bv_null->get_enumerator(idx_from);
871  size_type i = *en_i;
872  if (idx_from + size <= i) // empty space (all zeros)
873  {
874  ::memset(arr, 0, sizeof(value_type)*size);
875  return size;
876  }
877  rank -= b;
878  sparse_vector_const_iterator it = sv_.get_const_iterator(rank);
879  i = 0;
880  while (it.valid())
881  {
882  if (!en_i.valid())
883  break;
884  size_type en_idx = *en_i;
885  while (idx_from < en_idx) // zero the empty prefix
886  {
887  arr[i] ^= arr[i];
888  ++i; ++idx_from;
889  if (i == size)
890  return i;
891  }
892  BM_ASSERT(idx_from == en_idx);
893  arr[i] = *it;
894  ++i; ++idx_from;
895  if (i == size)
896  return i;
897 
898  en_i.advance();
899  it.advance();
900  } // while
901 
902  return i;
903 }
904 
905 //---------------------------------------------------------------------
906 
907 template<class Val, class SV>
909 {
910  if (bv_blocks_ptr_)
911  return;
912  bv_blocks_ptr_ =
914  bv_blocks_ptr_ = new(bv_blocks_ptr_) rs_index_type(); // placement new
915 }
916 
917 //---------------------------------------------------------------------
918 
919 template<class Val, class SV>
921 {
922  if (bv_blocks_ptr_)
923  {
924  bv_blocks_ptr_->~rs_index_type();
925  bm::aligned_free(bv_blocks_ptr_);
926  }
927 }
928 
929 //---------------------------------------------------------------------
930 
931 
932 } // namespace bm
933 
934 #include "bmundef.h"
935 
936 
937 #endif
size_type size() const
return size of the vector
memory allocation policy
Definition: bm.h:1243
value_type get(size_type idx) const
get specified element without bounds checking
void clear() BMNOEXEPT
resize to zero, free memory
bool operator==(const reference &ref) const
size_type size_internal() const
size_type effective_size() const
size of internal dense vector
rs_index< allocator_type > rs_index_type
Definition: bm.h:1255
rsc_sparse_vector< Val, SV > & operator=(const rsc_sparse_vector< Val, SV > &csv)
bvector_type::allocation_policy allocation_policy_type
Sparse constainer sparse_vector<> for integer types using bit-transposition transform.
void push_back_no_check(size_type idx, value_type v)
void optimize(bm::word_t *temp_block=0, typename bvector_type::optmode opt_mode=bvector_type::opt_compress, statistics *stat=0)
run memory optimization for all vector plains
void * aligned_new_malloc(size_t size)
Aligned malloc (unlike classic malloc it throws bad_alloc exception)
Definition: bmalloc.h:401
bool find_rank(size_type rank, size_type &idx) const
find position of compressed element by its rank
Rank-Select compressed sparse vector.
Definition: bm.h:76
void load_to(sparse_vector_type &sv) const
Exort compressed vector to a sparse vector (with NULLs)
pre-processor un-defines to avoid global space pollution (internal)
value_type operator[](size_type idx) const
get specified element without bounds checking
size_type decode(value_type *arr, size_type idx_from, size_type size, bool zero_mem=true) const
static unsigned stored_plains()
Number of stored bit-plains (value plains + extra.
#define BMNOEXEPT
Definition: bmdef.h:78
algorithms for sparse_vector scan/seach
const value_type & const_reference
compress blocks when possible (GAP/prefix sum)
Definition: bm.h:134
void set(size_type idx, value_type v)
set specified element with bounds checking and automatic resize
bool resolve(size_type idx, size_type *idx_to) const
Resolve logical address to access via rank compressed address.
const unsigned id_max
Definition: bmconst.h:105
SV::bvector_type bvector_type
void aligned_free(void *ptr)
Aligned free.
Definition: bmalloc.h:429
void unsync()
Unsync the prefix sum table.
null_support
NULL-able value support.
Definition: bmconst.h:214
const sparse_vector_type & get_sv() const
access dense vector
SV::const_iterator sparse_vector_const_iterator
bool is_nullable() const
if container supports NULL(unassigned) values (true)
void load_from(const sparse_vector_type &sv_src)
Load compressed vector from a sparse vector (with NULLs)
Alloc allocator_type
Definition: bm.h:110
unsigned int word_t
Definition: bmconst.h:38
void decompress(BV &bv_target, const BV &bv_idx, const BV &bv_src)
Rank decompression.
Definition: bmalgo.h:294
bvector_type * bvector_type_ptr
support "non-assigned" or "NULL" logic
Definition: bmconst.h:216
bool in_sync() const
returns true if prefix sum table is in sync with the vector
void resize_internal(size_type sz)
size_type effective_vector_max() const
Always 1 (non-matrix type)
unsigned effective_plains() const
unsigned char * init_remap_buffer()
const unsigned char * get_remap_buffer() const
const bvector_type * get_null_bvector() const
Get bit-vector of assigned values (or NULL)
value_type at(size_type idx) const
access specified element with bounds checking
bool valid() const
Checks if iterator is still valid.
Definition: bm.h:277
bvector_type::enumerator bvector_enumerator_type
bool equal(const rsc_sparse_vector< Val, SV > &csv) const
check if another vector has the same content
Definitions(internal)
void calc_stat(struct rsc_sparse_vector< Val, SV >::statistics *st) const
Calculates memory statistics.
rsc_sparse_vector< Val, SV > & operator=(rsc_sparse_vector< Val, SV > &&csv) BMNOEXEPT
static bool is_compressed()
trait if sparse vector is "compressed" (true)
bvector_type::rs_index_type rs_index_type
Serialize sparse vector into a memory buffer(s) structure.
bool is_null(size_type idx) const
test if specified element is NULL
const bvector_type * bvector_type_const_ptr
rsc_sparse_vector(bm::null_support null_able=bm::use_null, allocation_policy_type ap=allocation_policy_type(), size_type bv_max_size=bm::id_max, const allocator_type &alloc=allocator_type())
Constant iterator designed to enumerate "ON" bits.
Definition: bm.h:590
optmode
Optimization mode Every next level means additional checks (better compression vs time) ...
Definition: bm.h:129
void sync()
Re-calculate prefix sum table used for rank search (if necessary)
void set_null(size_type idx)
set specified element to NULL RSC vector actually erases element when it is set to NULL (expensive)...
sparse vector de-serializer
bvector_type_const_ptr get_plain(unsigned i) const
get access to bit-plain, function checks and creates a plain
reference(rsc_sparse_vector< Val, SV > &csv, size_type idx) BMNOEXEPT
bvector_type::allocator_type allocator_type
bool empty() const
return true if vector is empty
void compress(BV &bv_target, const BV &bv_idx, const BV &bv_src)
Rank compression algorithm based on two palallel iterators/enumerators set of source vector gets re-m...
Definition: bmalgo.h:220
#define BM_ASSERT
Definition: bmdef.h:117
bvector_type_ptr get_plain(unsigned i)
void advance()
advance iterator forward by one
Definition: bm.h:717
bm::bvector bvector_type
Reference class to access elements via common [] operator.
Structure with statistical information about memory allocation footprint, serialization projection...
Definition: bmfunc.h:54
void push_back(size_type idx, value_type v)
set specified element with bounds checking and automatic resize
static unsigned plains()
get total number of bit-plains in the vector