📄 bm.h
字号:
/* * =========================================================================== * PRODUCTION $Log: bm.h,v $ * PRODUCTION Revision 1000.1 2004/06/01 19:39:05 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5 * PRODUCTION * =========================================================================== *//*Copyright (c) 2002,2003 Anatoliy Kuznetsov.Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/#ifndef BM__H__INCLUDED__#define BM__H__INCLUDED__#include <string.h>#include <assert.h>#include <limits.h>// define BM_NO_STL if you use BM in "STL free" environment and want// to disable any references to STL headers#ifndef BM_NO_STL# include <iterator>#endif#include "bmconst.h"#include "bmdef.h"// Vector based optimizations are incompatible with 64-bit optimization// which is considered a form of vectorization#ifdef BMSSE2OPT# undef BM64OPT# define BMVECTOPT# include "bmsse2.h"#endif#include "bmfwd.h"#include "bmfunc.h"#include "bmvmin.h"#include "encoding.h"#include "bmalloc.h"namespace bm{#ifdef BMCOUNTOPT# define BMCOUNT_INC ++count_;# define BMCOUNT_DEC --count_;# define BMCOUNT_VALID(x) count_is_valid_ = x;# define BMCOUNT_SET(x) count_ = x; count_is_valid_ = true;# define BMCOUNT_ADJ(x) if (x) ++count_; else --count_;#else# define BMCOUNT_INC# define BMCOUNT_DEC# define BMCOUNT_VALID(x)# define BMCOUNT_SET(x)# define BMCOUNT_ADJ(x)#endif// Serialization related constantsconst unsigned char set_block_end = 0; //!< End of serializationconst unsigned char set_block_1zero = 1; //!< One all-zero blockconst unsigned char set_block_1one = 2; //!< One block all-set (1111...)const unsigned char set_block_8zero = 3; //!< Up to 256 zero blocksconst unsigned char set_block_8one = 4; //!< Up to 256 all-set blocksconst unsigned char set_block_16zero= 5; //!< Up to 65536 zero blocksconst unsigned char set_block_16one = 6; //!< UP to 65536 all-set blocksconst unsigned char set_block_32zero= 7; //!< Up to 4G zero blocksconst unsigned char set_block_32one = 8; //!< UP to 4G all-set blocksconst unsigned char set_block_azero = 9; //!< All other blocks zeroconst unsigned char set_block_aone = 10; //!< All other blocks oneconst unsigned char set_block_bit = 11; //!< Plain bit blockconst unsigned char set_block_sgapbit = 12; //!< SGAP compressed bitblockconst unsigned char set_block_sgapgap = 13; //!< SGAP compressed GAP blockconst unsigned char set_block_gap = 14; //!< Plain GAP blockconst unsigned char set_block_gapbit = 15; //!< GAP compressed bitblock const unsigned char set_block_arrbit = 16; //!< List of bits ON#define SER_NEXT_GRP(enc, nb, B_1ZERO, B_8ZERO, B_16ZERO, B_32ZERO) \ if (nb == 1) \ enc.put_8(B_1ZERO); \ else if (nb < 256) \ { \ enc.put_8(B_8ZERO); \ enc.put_8((unsigned char)nb); \ } \ else if (nb < 65536) \ { \ enc.put_8(B_16ZERO); \ enc.put_16((unsigned short)nb); \ } \ else \ {\ enc.put_8(B_32ZERO); \ enc.put_32(nb); \ }#define BM_SET_ONE_BLOCKS(x) \ {\ unsigned end_block = i + x; \ for (;i < end_block; ++i) \ blockman_.set_block_all_set(i); \ } \ --itypedef bm::miniset<bm::block_allocator, bm::set_total_blocks> mem_save_set;/** @defgroup bvector The Main bvector<> Group * This is the main group. It includes bvector template: front end of the bm library. * *//*! @brief Block allocation strategies. @ingroup bvector*/enum strategy{ BM_BIT = 0, //!< No GAP compression strategy. All new blocks are bit blocks. BM_GAP = 1 //!< GAP compression is ON.};/*! @brief bitvector with runtime compression of bits. @ingroup bvector*/template<class A, class MS> class bvector{public: /*! @brief Structure with statistical information about bitset's memory allocation details. @ingroup bvector */ struct statistics { /// Number of bit blocks. unsigned bit_blocks; /// Number of GAP blocks. unsigned gap_blocks; /// Estimated maximum of memory required for serialization. unsigned max_serialize_mem; /// Memory used by bitvector including temp and service blocks unsigned memory_used; /// Array of all GAP block lengths in the bvector. gap_word_t gap_length[bm::set_total_blocks]; /// GAP lengths used by bvector gap_word_t gap_levels[bm::gap_levels]; }; /** @brief Class reference implements an object for bit assignment. Since C++ does not provide with build-in bit type supporting l-value operations we have to emulate it. @ingroup bvector */ class reference { public: reference(bvector<A, MS>& bv, bm::id_t position) :bv_(bv),position_(position) {} reference(const reference& ref): bv_(ref.bv_), position_(ref.position_) { bv_.set(position_, ref.bv_.get_bit(position_)); } operator bool() const { return bv_.get_bit(position_); } const reference& operator=(const reference& ref) const { bv_.set(position_, (bool)ref); return *this; } const reference& operator=(bool value) const { bv_.set(position_, value); return *this; } bool operator==(const reference& ref) const { return bool(*this) == bool(ref); } /*! Bitwise AND. Performs operation: bit = bit AND value */ const reference& operator&=(bool value) const { bv_.set(position_, value); return *this; } /*! Bitwise OR. Performs operation: bit = bit OR value */ const reference& operator|=(bool value) const { if (value != bv_.get_bit(position_)) { bv_.set_bit(position_); } return *this; } /*! Bitwise exclusive-OR (XOR). Performs operation: bit = bit XOR value */ const reference& operator^=(bool value) const { bv_.set(position_, value != bv_.get_bit(position_)); return *this; } /*! Logical Not operator */ bool operator!() const { return !bv_.get_bit(position_); } /*! Bit Not operator */ bool operator~() const { return !bv_.get_bit(position_); } /*! Negates the bit value */ reference& flip() { bv_.flip(position_); return *this; } private: bvector<A, MS>& bv_; //!< Reference variable on parent bitvector. bm::id_t position_; //!< Position in parent bitvector. }; typedef bool const_reference; /*! @brief Base class for all iterators. @ingroup bvector */ class iterator_base { friend class bvector; public: iterator_base() : block_(0) {} bool operator==(const iterator_base& it) const { return (position_ == it.position_) && (bv_ == it.bv_); } bool operator!=(const iterator_base& it) const { return ! operator==(it); } bool operator < (const iterator_base& it) const { return position_ < it.position_; } bool operator <= (const iterator_base& it) const { return position_ <= it.position_; } bool operator > (const iterator_base& it) const { return position_ > it.position_; } bool operator >= (const iterator_base& it) const { return position_ >= it.position_; } /** \fn bool bm::bvector::iterator_base::valid() const \brief Checks if iterator is still valid. Analog of != 0 comparison for pointers. \returns true if iterator is valid. */ bool valid() const { return position_ != bm::id_max; } /** \fn bool bm::bvector::iterator_base::invalidate() \brief Turns iterator into an invalid state. */ void invalidate() { position_ = bm::id_max; } public: /** Information about current bitblock. */ struct bitblock_descr { const bm::word_t* ptr; //!< Word pointer. unsigned bits[32]; //!< Unpacked list of ON bits unsigned idx; //!< Current position in the bit list unsigned cnt; //!< Number of ON bits bm::id_t pos; //!< Last bit position before }; /** Information about current DGAP block. */ struct dgap_descr { const gap_word_t* ptr; //!< Word pointer. gap_word_t gap_len; //!< Current dgap length. }; protected: bm::bvector<A, MS>* bv_; //!< Pointer on parent bitvector. bm::id_t position_; //!< Bit position (bit number) in the bitvector. const bm::word_t* block_; //!< Block pointer. If NULL iterator is considered invalid. unsigned block_type_; //!< Type of the current block. 0 - Bit, 1 - GAP unsigned block_idx_; //!< Block index. /*! Block type dependent information for current block. */ union block_descr { bitblock_descr bit_; //!< BitBlock related info. dgap_descr gap_; //!< DGAP block related info. } bdescr_; }; /*! @brief Output iterator iterator designed to set "ON" bits based on their indeces. STL container can be converted to bvector using this iterator @ingroup bvector */ class insert_iterator { public:#ifndef BM_NO_STL typedef std::output_iterator_tag iterator_category;#endif typedef unsigned value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(bvector<A, MS>& bvect) : bvect_(bvect) {} insert_iterator& operator=(bm::id_t n) { bvect_.set(n); return *this; } /*! Returns *this without doing nothing */ insert_iterator& operator*() { return *this; } /*! Returns *this. This iterator does not move */ insert_iterator& operator++() { return *this; } /*! Returns *this. This iterator does not move */ insert_iterator& operator++(int) { return *this; } protected: bm::bvector<A, MS>& bvect_; }; /*! @brief Constant input iterator designed to enumerate "ON" bits @ingroup bvector */ class enumerator : public iterator_base { public:#ifndef BM_NO_STL typedef std::input_iterator_tag iterator_category;#endif typedef unsigned value_type; typedef unsigned difference_type; typedef unsigned* pointer; typedef unsigned& reference; public: enumerator() : iterator_base() {} enumerator(const bvector* bvect, int position) : iterator_base() { this->bv_ = const_cast<bvector<A, MS>*>(bvect); if (position == 0) { go_first(); } else { this->invalidate(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -