Exemple #1
0
    //  Computes N_1+( * ab * )
    uint64_t N1PlusFrontBack(const node_type& node, const node_type& node_rev,
                             pattern_iterator pattern_begin, pattern_iterator pattern_end) const
    {
        auto timer = lm_bench::bench(timer_type::N1PlusFrontBack);
        // ASSUMPTION: lb, rb already identify the suffix array range corresponding to 'pattern' in
        // the forward tree
        // ASSUMPTION: pattern_begin, pattern_end cover just the pattern we're interested in (i.e.,
        // we want N1+ dot pattern dot)
        uint64_t pattern_size = std::distance(pattern_begin, pattern_end);
        uint64_t back_N1plus_front = 0;

        // this is when the pattern matches a full edge in the CST
        if (!m_cst.is_leaf(node) && pattern_size == m_cst.depth(node)) {
            if (*pattern_begin == PAT_START_SYM) {
                return m_cst.degree(node);
            }
            auto w = m_cst.select_child(node, 1);
            auto root_id = m_cst.id(m_cst.root());
            std::vector<uint64_t> new_pattern(pattern_begin, pattern_end);
            new_pattern.push_back(EOS_SYM);
            while (m_cst.id(w) != root_id) {
                auto lb_rev_stored = m_cst_rev.lb(node_rev);
                auto rb_rev_stored = m_cst_rev.rb(node_rev);
                uint64_t symbol = m_cst.edge(w, pattern_size + 1);
                assert(symbol != EOS_SYM);
                new_pattern.back() = symbol;
                // find the symbol to the right
                // (which is first in the reverse order)
                backward_search_wrapper(m_cst_rev.csa, lb_rev_stored, rb_rev_stored, symbol, lb_rev_stored,
                                        rb_rev_stored);

                back_N1plus_front += N1PlusBack(m_cst_rev.node(lb_rev_stored, rb_rev_stored),
                                                new_pattern.begin(), new_pattern.end());
                w = m_cst.sibling(w);
            }
            return back_N1plus_front;
        } else {
            // special case, only one way of extending this pattern to the right
            if (*pattern_begin == PAT_START_SYM && *(pattern_end - 1) == PAT_END_SYM) {
                /* pattern must be 13xyz41 -> #P(*3xyz4*) == 0 */
                return 0;
            } else if (*pattern_begin == PAT_START_SYM) {
                /* pattern must be 13xyzA -> #P(*3xyz*) == 1 */
                return 1;
            } else {
                /* pattern must be *xyzA -> #P(*xyz*) == N1PlusBack */
                return N1PlusBack(node_rev, pattern_begin, pattern_end);
            }
        }
    }
	iterator_type& operator++()
	{
		m_cur_node = m_cst->sibling(m_cur_node);
		return *this;
	}