📄 bmalgo.h
字号:
{ arg_blk = bman2.get_block(i, j); arg_gap = BM_IS_GAP(bman2, arg_blk, block_idx); if (!arg_blk) continue; combine_count_operation_with_block(blk, blk_gap, arg_blk, arg_gap, temp_blk, dmit, dmit_end); } // for j continue; } for (j = 0; j < bm::set_array_size; ++j, ++block_idx) { blk = blk_blk[j]; arg_blk = bman2.get_block(i, j); if (blk == 0 && arg_blk == 0) continue; arg_gap = BM_IS_GAP(bman2, arg_blk, block_idx); blk_gap = BM_IS_GAP(bman1, blk, block_idx); combine_count_operation_with_block(blk, blk_gap, arg_blk, arg_gap, temp_blk, dmit, dmit_end); } // for j } // for i if (temp_blk) { BV::free_tempblock(temp_blk); }}/*! \brief Computes bitcount of AND operation of two bitsets \param bv1 - Argument bit-vector. \param bv2 - Argument bit-vector. \return bitcount of the result \ingroup distance*/template<class BV>bm::id_t count_and(const BV& bv1, const BV& bv2){ distance_metric_descriptor dmd(bm::COUNT_AND); distance_operation(bv1, bv2, &dmd, &dmd+1); return dmd.result;}/*! \brief Computes bitcount of XOR operation of two bitsets \param bv1 - Argument bit-vector. \param bv2 - Argument bit-vector. \return bitcount of the result \ingroup distance*/template<class BV>bm::id_t count_xor(const BV& bv1, const BV& bv2){ distance_metric_descriptor dmd(bm::COUNT_XOR); distance_operation(bv1, bv2, &dmd, &dmd+1); return dmd.result;}/*! \brief Computes bitcount of SUB operation of two bitsets \param bv1 - Argument bit-vector. \param bv2 - Argument bit-vector. \return bitcount of the result \ingroup distance*/template<class BV>bm::id_t count_sub(const BV& bv1, const BV& bv2){ distance_metric_descriptor dmd(bm::COUNT_SUB_AB); distance_operation(bv1, bv2, &dmd, &dmd+1); return dmd.result;}/*! \brief Computes bitcount of OR operation of two bitsets \param bv1 - Argument bit-vector. \param bv2 - Argument bit-vector. \return bitcount of the result \ingroup distance*/template<class BV>bm::id_t count_or(const BV& bv1, const BV& bv2){ distance_metric_descriptor dmd(bm::COUNT_OR); distance_operation(bv1, bv2, &dmd, &dmd+1); return dmd.result;}/** \brief Internal algorithms scans the input for the block range limit \internal*/template<class It>It block_range_scan(It first, It last, unsigned nblock){ It right; for (right = first; right != last; ++right) { unsigned nb = unsigned((*right) >> bm::set_block_shift); if (nb != nblock) break; } return right;}/** \brief OR Combine bitvector and the iterable sequence Algorithm combines bvector with sequence of integers (represents another set). When the agrument set is sorted this method can give serious increase in performance. \param bv - destination bitvector \param first - first element of the iterated sequence \param last - last element of the iterated sequence \ingroup setalgo*/template<class BV, class It>void combine_or(BV& bv, It first, It last){ typename BV::blocks_manager& bman = bv.get_blocks_manager(); while (first < last) { unsigned nblock = unsigned((*first) >> bm::set_block_shift); It right = block_range_scan(first, last, nblock); // now we have one in-block array of bits to set label1: int block_type; bm::word_t* blk = bman.check_allocate_block(nblock, true, bv.get_new_blocks_strat(), &block_type); if (!blk) continue; if (block_type == 1) // gap { bm::gap_word_t* gap_blk = BMGAP_PTR(blk); unsigned threshold = bm::gap_limit(gap_blk, bman.glen()); for (; first < right; ++first) { unsigned is_set; unsigned nbit = (*first) & bm::set_block_mask; unsigned new_block_len = gap_set_value(true, gap_blk, nbit, &is_set); if (new_block_len > threshold) { bman.extend_gap_block(nblock, gap_blk); ++first; goto label1; // block pointer changed - goto reset } } } else // bit block { for (; first < right; ++first) { unsigned nbit = unsigned(*first & bm::set_block_mask); unsigned nword = unsigned(nbit >> bm::set_word_shift); nbit &= bm::set_word_mask; blk[nword] |= (bm::word_t)1 << nbit; } // for } } // while bv.forget_count();}/** \brief XOR Combine bitvector and the iterable sequence Algorithm combines bvector with sequence of integers (represents another set). When the agrument set is sorted this method can give serious increase in performance. \param bv - destination bitvector \param first - first element of the iterated sequence \param last - last element of the iterated sequence \ingroup setalgo*/template<class BV, class It>void combine_xor(BV& bv, It first, It last){ typename BV::blocks_manager& bman = bv.get_blocks_manager(); while (first < last) { unsigned nblock = unsigned((*first) >> bm::set_block_shift); It right = block_range_scan(first, last, nblock); // now we have one in-block array of bits to set label1: int block_type; bm::word_t* blk = bman.check_allocate_block(nblock, true, bv.get_new_blocks_strat(), &block_type, false /* no null return */); BM_ASSERT(blk); if (block_type == 1) // gap { bm::gap_word_t* gap_blk = BMGAP_PTR(blk); unsigned threshold = bm::gap_limit(gap_blk, bman.glen()); for (; first < right; ++first) { unsigned is_set; unsigned nbit = (*first) & bm::set_block_mask; is_set = gap_test(gap_blk, nbit); BM_ASSERT(is_set <= 1); is_set ^= 1; unsigned new_block_len = gap_set_value(is_set, gap_blk, nbit, &is_set); if (new_block_len > threshold) { bman.extend_gap_block(nblock, gap_blk); ++first; goto label1; // block pointer changed - goto reset } } } else // bit block { for (; first < right; ++first) { unsigned nbit = unsigned(*first & bm::set_block_mask); unsigned nword = unsigned(nbit >> bm::set_word_shift); nbit &= bm::set_word_mask; blk[nword] ^= (bm::word_t)1 << nbit; } // for } } // while bv.forget_count();}/** \brief SUB Combine bitvector and the iterable sequence Algorithm combines bvector with sequence of integers (represents another set). When the agrument set is sorted this method can give serious increase in performance. \param bv - destination bitvector \param first - first element of the iterated sequence \param last - last element of the iterated sequence \ingroup setalgo*/template<class BV, class It>void combine_sub(BV& bv, It first, It last){ typename BV::blocks_manager& bman = bv.get_blocks_manager(); while (first < last) { unsigned nblock = unsigned((*first) >> bm::set_block_shift); It right = block_range_scan(first, last, nblock); // now we have one in-block array of bits to set label1: int block_type; bm::word_t* blk = bman.check_allocate_block(nblock, false, bv.get_new_blocks_strat(), &block_type); if (!blk) continue; if (block_type == 1) // gap { bm::gap_word_t* gap_blk = BMGAP_PTR(blk); unsigned threshold = bm::gap_limit(gap_blk, bman.glen()); for (; first < right; ++first) { unsigned is_set; unsigned nbit = (*first) & bm::set_block_mask; is_set = gap_test(gap_blk, nbit); if (!is_set) continue; unsigned new_block_len = gap_set_value(false, gap_blk, nbit, &is_set); if (new_block_len > threshold) { bman.extend_gap_block(nblock, gap_blk); ++first; goto label1; // block pointer changed - goto reset } } } else // bit block { for (; first < right; ++first) { unsigned nbit = unsigned(*first & bm::set_block_mask); unsigned nword = unsigned(nbit >> bm::set_word_shift); nbit &= bm::set_word_mask; blk[nword] &= ~((bm::word_t)1 << nbit); } // for } } // while bv.forget_count();}/** \brief AND Combine bitvector and the iterable sequence Algorithm combines bvector with sequence of integers (represents another set). When the agrument set is sorted this method can give serious increase in performance. \param bv - destination bitvector \param first - first element of the iterated sequence \param last - last element of the iterated sequence \ingroup setalgo*/template<class BV, class It>void combine_and(BV& bv, It first, It last){ BV bv_tmp; combine_or(bv_tmp, first, last); bv &= bv_tmp;}/*! \brief Compute number of bit intervals (GAPs) in the bitvector Algorithm traverses bit vector and count number of uninterrupted intervals of 1s and 0s. <pre> For example: 00001111100000 - gives us 3 intervals 10001111100000 - 4 intervals 00000000000000 - 1 interval 11111111111111 - 1 interval </pre> \return Number of intervals \ingroup setalgo*/template<class BV>bm::id_t count_intervals(const BV& bv){ const typename BV::blocks_manager& bman = bv.get_blocks_manager(); bm::word_t*** blk_root = bman.get_rootblock(); typename BV::blocks_manager::block_count_change_func func(bman); for_each_block(blk_root, bman.top_block_size(), bm::set_array_size, func); return func.count(); }} // namespace bm#include "bmundef.h"#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -