Skip to content

Commit

Permalink
[MISC] Add alphabet type template to fm_index
Browse files Browse the repository at this point in the history
  • Loading branch information
eseiler committed Aug 21, 2019
1 parent 5a0354a commit 04abc72
Show file tree
Hide file tree
Showing 25 changed files with 219 additions and 194 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ If possible, provide tooling that performs the changes, e.g. a shell-script.
* **The `type_list` header has moved:**
If you included `<seqan3/core/type_list.hpp>` you need to change the path to `<seqan3/core/type_list/type_list.hpp>`.

#### Search

* **Changed class signature of (bi_)fm_index:**
All code that relies on automatic template deduction will be unaffected. In case you specified the template parameters
of an `seqan3::fm_index` or `seqan3::bi_fm_index` you will need to add the alphabet type as first parameter and pass a
`seqan3::text_layout` instead of a `bool` to indicate the text layout (single, collection).
For example, `fm_index<false> index{text}` where `text` is of type `dna4_vector` needs to be changed to
`fm_index<dna4, text_layout::single> index{text}`.

## Notable Bug-fixes

# 3.0.0 ("Escala")
Expand Down
2 changes: 1 addition & 1 deletion doc/tutorial/read_mapper/read_mapper_step2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void map_reads(std::filesystem::path const & query_path,
uint8_t const errors)
//! [map_reads]
{
bi_fm_index<text_layout::collection> index; // we need to know if we work on a text collection before loading
bi_fm_index<dna5, text_layout::collection> index; // we need to the alphabet and text layout before loading
{
std::ifstream is{index_path, std::ios::binary};
cereal::BinaryInputArchive iarchive{is};
Expand Down
2 changes: 1 addition & 1 deletion doc/tutorial/read_mapper/read_mapper_step3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void map_reads(std::filesystem::path const & query_path,
reference_storage_t & storage,
uint8_t const errors)
{
bi_fm_index<text_layout::collection> index; // we need to know if we work on a text collection before loading
bi_fm_index<dna5, text_layout::collection> index; // we need to the alphabet and text layout before loading
{
std::ifstream is{index_path, std::ios::binary};
cereal::BinaryInputArchive iarchive{is};
Expand Down
2 changes: 1 addition & 1 deletion doc/tutorial/read_mapper/read_mapper_step4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void map_reads(std::filesystem::path const & query_path,
reference_storage_t & storage,
uint8_t const errors)
{
bi_fm_index<text_layout::collection> index; // we need to know if we work on a text collection before loading
bi_fm_index<dna5, text_layout::collection> index; // we need to the alphabet and text layout before loading
{
std::ifstream is{index_path, std::ios::binary};
cereal::BinaryInputArchive iarchive{is};
Expand Down
3 changes: 2 additions & 1 deletion doc/tutorial/search/search_small_snippets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ fm_index index{text};

{
//![load]
fm_index<text_layout::single> index; // we need to tell the index that we work on a single text before loading
// we need to tell the index that we work on a single text and a `char` alphabet before loading
fm_index<char, text_layout::single> index;
{
std::ifstream is{"index.file", std::ios::binary};
cereal::BinaryInputArchive iarchive{is};
Expand Down
3 changes: 2 additions & 1 deletion doc/tutorial/search/search_solution1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ int main()
oarchive(index);
}

fm_index<text_layout::single> index2; // we need to tell the index that we work on a single text before loading
// we need to tell the index that we work on a single text and a `dna4` alphabet before loading
fm_index<dna4, text_layout::single> index2;
{
std::ifstream is{"index.file", std::ios::binary};
cereal::BinaryInputArchive iarchive{is};
Expand Down
4 changes: 2 additions & 2 deletions include/seqan3/search/algorithm/detail/search.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ inline auto search_single(index_t const & index, query_t & query, configuration_
}
else
{
using hit_t = std::conditional_t<index_t::is_collection_,
using hit_t = std::conditional_t<index_t::is_collection,
std::pair<typename index_t::size_type, typename index_t::size_type>,
typename index_t::size_type>;
std::vector<hit_t> hits;
Expand Down Expand Up @@ -184,7 +184,7 @@ inline auto search_all(index_t const & index, queries_t & queries, configuration
// delegate params: text_position (or cursor). we will withhold all hits of one query anyway to filter
// duplicates. more efficient to call delegate once with one vector instead of calling
// delegate for each hit separately at once.
using text_pos_t = std::conditional_t<index_t::is_collection_,
using text_pos_t = std::conditional_t<index_t::is_collection,
std::pair<typename index_t::size_type, typename index_t::size_type>,
typename index_t::size_type>;
using hit_t = std::conditional_t<cfg_t::template exists<search_cfg::output<detail::search_output_index_cursor>>(),
Expand Down
1 change: 1 addition & 0 deletions include/seqan3/search/algorithm/detail/search_trivial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include <type_traits>

#include <seqan3/alphabet/concept.hpp>
#include <seqan3/range/concept.hpp>
#include <seqan3/range/view/drop.hpp>
#include <seqan3/search/algorithm/detail/search_common.hpp>
Expand Down
72 changes: 25 additions & 47 deletions include/seqan3/search/fm_index/bi_fm_index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,13 @@
namespace seqan3
{

//!\cond
SEQAN3_DEPRECATED_310
void bi_fm_index_deprecation(bool);

template <typename t>
void bi_fm_index_deprecation(t);
//!\endcond

/*!\addtogroup submodule_fm_index
* \{
*/

/*!\brief The SeqAn Bidirectional FM Index
* \implements seqan3::BiFmIndex
* \tparam is_collection Indicates whether this index works on a text collection or a single text.
* See seqan3::text_layout.
* \tparam text_t The type the underlying text range; must model std::ranges::BidirectionalRange.
* \tparam sdsl_index_type_ The type of the underlying SDSL index, must model seqan3::SdslIndex.
* \details
*
Expand All @@ -64,18 +55,13 @@ void bi_fm_index_deprecation(t);
*
* \attention When building an index for a **text collection** over any alphabet, the symbols with rank 254 and 255
* are reserved and may not be used in the text.
*
* \deprecated Use seqan3::text_layout to indicate single texts and text collections. The use of bool is deprecated.
*/
template <auto is_collection = text_layout::single, detail::SdslIndex sdsl_index_type_ = default_sdsl_index_type>
template <Semialphabet alphabet_t,
text_layout text_layout_mode,
detail::SdslIndex sdsl_index_type_ = default_sdsl_index_type>
class bi_fm_index
{
protected:
//!\brief The alphabet size of the text.
size_t sigma{0};
//!\brief Indicates whether index is built over a collection.
static constexpr bool is_collection_{is_collection};

/*!\name Index types
* \{
*/
Expand All @@ -93,27 +79,22 @@ class bi_fm_index
//!\brief The type of the alphabet size of the underlying SDSL index.
using sdsl_sigma_type = typename sdsl_index_type::alphabet_type::sigma_type;

//!\brief The type of the underlying FM index for the original text.
using fm_index_type = fm_index<text_layout{is_collection_}, sdsl_index_type>;

//!\brief The type of the underlying FM index for the reversed text.\if DEV \todo Change sampling behaviour. \endif
using rev_fm_index_type = fm_index<text_layout{is_collection_}, sdsl_index_type>;
//!\brief The type of the underlying FM index.
using fm_index_type = fm_index<alphabet_t, text_layout_mode, sdsl_index_type>;
//!\}

//!\brief Underlying FM index for the original text.
fm_index_type fwd_fm;

//!\brief Underlying FM index for the reversed text.
rev_fm_index_type rev_fm;

//!\cond
using unused_t [[maybe_unused]] = decltype(bi_fm_index_deprecation(is_collection));
//!\endcond
fm_index_type rev_fm;

public:
/*!\name Text types
* \{
*/
//!\brief The type of the underlying character of the indexed text.
using char_type = typename fm_index_type::char_type;
//!\brief Type for representing positions in the indexed text.
using size_type = typename sdsl_index_type::size_type;
//!\}
Expand All @@ -122,13 +103,14 @@ class bi_fm_index
* \{
*/
//!\brief The type of the bidirectional cursor.
using cursor_type = bi_fm_index_cursor<bi_fm_index<is_collection, sdsl_index_type>>;
//!\brief The type of the unidirectional cursor on the original text.
using fwd_cursor_type = fm_index_cursor<fm_index_type>;
//!\brief The type of the unidirectional cursor on the reversed text.
using rev_cursor_type = fm_index_cursor<rev_fm_index_type>;
using cursor_type = bi_fm_index_cursor<bi_fm_index<alphabet_t, text_layout_mode, sdsl_index_type>>;
//!\brief The type of the unidirectional cursor.
using uni_cursor_type = fm_index_cursor<fm_index_type>;
//!\}

//!\brief Indicates whether index is built over a collection.
static constexpr bool is_collection = text_layout_mode;

template <typename fm_index_t>
friend class fm_index_cursor;

Expand All @@ -153,7 +135,7 @@ class bi_fm_index
template <std::ranges::Range text_t>
bi_fm_index(text_t && text)
{
construct(std::forward<decltype(text)>(text));
construct(std::forward<text_t>(text));
}
//!\}

Expand All @@ -177,9 +159,9 @@ class bi_fm_index
* No guarantee. \if DEV \todo Ensure strong exception guarantee. \endif
*/
template <std::ranges::Range text_t>
//!\cond
requires !is_collection_
//!\endcond
//!\cond
requires !is_collection
//!\endcond
void construct(text_t && text)
{
static_assert(std::ranges::BidirectionalRange<text_t>, "The text must model BidirectionalRange.");
Expand All @@ -193,15 +175,13 @@ class bi_fm_index
auto rev_text = std::view::reverse(text);
fwd_fm.construct(text);
rev_fm.construct(rev_text);

sigma = fwd_fm.sigma;
}

//!\overload
template <std::ranges::Range text_t>
//!\cond
requires is_collection_
//!\endcond
//!\cond
requires is_collection
//!\endcond
void construct(text_t && text)
{
static_assert(std::ranges::BidirectionalRange<text_t>, "The text must model BidirectionalRange.");
Expand All @@ -217,8 +197,6 @@ class bi_fm_index
auto rev_text = text | view::deep{std::view::reverse} | std::view::reverse;
fwd_fm.construct(text);
rev_fm.construct(rev_text);

sigma = fwd_fm.sigma;
}

/*!\brief Returns the length of the indexed text including sentinel characters.
Expand Down Expand Up @@ -316,7 +294,7 @@ class bi_fm_index
*
* No-throw guarantee.
*/
fwd_cursor_type fwd_begin() const noexcept
uni_cursor_type fwd_begin() const noexcept
{
return {fwd_fm};
}
Expand All @@ -335,7 +313,7 @@ class bi_fm_index
*
* No-throw guarantee.
*/
rev_cursor_type rev_begin() const noexcept
uni_cursor_type rev_begin() const noexcept
{
return {rev_fm};
}
Expand All @@ -361,7 +339,7 @@ class bi_fm_index
*/
//! \brief Deduces the dimensions of the text.
template <std::ranges::Range text_t>
bi_fm_index(text_t &&) -> bi_fm_index<text_layout{dimension_v<text_t> != 1}>;
bi_fm_index(text_t &&) -> bi_fm_index<innermost_value_type_t<text_t>, text_layout{dimension_v<text_t> != 1}>;
//!\}

//!\}
Expand Down
Loading

0 comments on commit 04abc72

Please sign in to comment.