SeqAn3 3.4.0-rc.4
The Modern C++ library for sequence analysis.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
interleaved_bloom_filter.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <algorithm>
13#include <bit>
14
15#include <seqan3/contrib/sdsl-lite.hpp>
17//Todo: When removing, the contents of the following header can be moved into utility/bloom_filter/bloom_filter.hpp
19
20SEQAN3_DEPRECATED_HEADER("This header and its functionality is deprecated and will be removed in a future version of SeqAn. Please use the hibf-library (url: https://github.com/seqan/hibf) instead.");
21
22namespace seqan3
23{
24
96template <data_layout data_layout_mode_ = data_layout::uncompressed>
98{
99private:
101 template <data_layout data_layout_mode>
102 friend class interleaved_bloom_filter;
104
107 seqan3::contrib::sdsl::bit_vector,
108 seqan3::contrib::sdsl::sd_vector<>>;
109
111 size_t bins{};
113 size_t technical_bins{};
115 size_t bin_size_{};
117 size_t hash_shift{};
119 size_t bin_words{};
121 size_t hash_funs{};
123 data_type data{};
125 static constexpr std::array<size_t, 5> hash_seeds{13'572'355'802'537'770'549ULL, // 2**64 / (e/2)
126 13'043'817'825'332'782'213ULL, // 2**64 / sqrt(2)
127 10'650'232'656'628'343'401ULL, // 2**64 / sqrt(3)
128 16'499'269'484'942'379'435ULL, // 2**64 / (sqrt(5)/2)
129 4'893'150'838'803'335'377ULL}; // 2**64 / (3*pi/5)
130
138 inline constexpr size_t hash_and_fit(size_t h, size_t const seed) const
139 {
140 h *= seed;
141 assert(hash_shift < 64);
142 h ^= h >> hash_shift; // XOR and shift higher bits into lower bits
143 h *= 11'400'714'819'323'198'485ULL; // = 2^64 / golden_ration, to expand h to 64 bit range
144 // Use fastrange (integer modulo without division) if possible.
145#ifdef __SIZEOF_INT128__
146 h = static_cast<uint64_t>((static_cast<__uint128_t>(h) * static_cast<__uint128_t>(bin_size_)) >> 64);
147#else
148 h %= bin_size_;
149#endif
150 h *= technical_bins;
151 return h;
152 }
153
154public:
157
158 class membership_agent_type; // documented upon definition below
159
160 template <typename value_t>
161 class counting_agent_type; // documented upon definition below
162
172
187 seqan3::bin_size size,
190 {
191 bins = bins_.get();
192 bin_size_ = size.get();
193 hash_funs = funs.get();
194
195 if (bins == 0)
196 throw std::logic_error{"The number of bins must be > 0."};
197 if (hash_funs == 0 || hash_funs > 5)
198 throw std::logic_error{"The number of hash functions must be > 0 and <= 5."};
199 if (bin_size_ == 0)
200 throw std::logic_error{"The size of a bin must be > 0."};
201
202 hash_shift = std::countl_zero(bin_size_);
203 bin_words = (bins + 63) >> 6; // = ceil(bins/64)
204 technical_bins = bin_words << 6; // = bin_words * 64
205 data = seqan3::contrib::sdsl::bit_vector(technical_bins * bin_size_);
206 }
207
218 {
219 std::tie(bins, technical_bins, bin_size_, hash_shift, bin_words, hash_funs) =
220 std::tie(ibf.bins, ibf.technical_bins, ibf.bin_size_, ibf.hash_shift, ibf.bin_words, ibf.hash_funs);
221
222 data = seqan3::contrib::sdsl::bit_vector{ibf.data.begin(), ibf.data.end()};
223 }
224
238 {
239 std::tie(bins, technical_bins, bin_size_, hash_shift, bin_words, hash_funs) =
240 std::tie(ibf.bins, ibf.technical_bins, ibf.bin_size_, ibf.hash_shift, ibf.bin_words, ibf.hash_funs);
241
242 data = seqan3::contrib::sdsl::sd_vector<>{ibf.data};
243 }
245
261 void emplace(size_t const value, bin_index const bin) noexcept
263 {
264 assert(bin.get() < bins);
265 for (size_t i = 0; i < hash_funs; ++i)
266 {
267 size_t idx = hash_and_fit(value, hash_seeds[i]);
268 idx += bin.get();
269 assert(idx < data.size());
270 data[idx] = 1;
271 };
272 }
273
285 void clear(bin_index const bin) noexcept
287 {
288 assert(bin.get() < bins);
289 for (size_t idx = bin.get(), i = 0; i < bin_size_; idx += technical_bins, ++i)
290 data[idx] = 0;
291 }
292
306 template <typename rng_t>
308 void clear(rng_t && bin_range) noexcept
309 {
310 static_assert(std::ranges::forward_range<rng_t>, "The range of bins to clear must model a forward_range.");
311 static_assert(std::same_as<std::remove_cvref_t<std::ranges::range_reference_t<rng_t>>, bin_index>,
312 "The reference type of the range to clear must be seqan3::bin_index.");
313#ifndef NDEBUG
314 for (auto && bin : bin_range)
315 assert(bin.get() < bins);
316#endif // NDEBUG
317
318 for (size_t offset = 0, i = 0; i < bin_size_; offset += technical_bins, ++i)
319 for (auto && bin : bin_range)
320 data[bin.get() + offset] = 0;
321 }
322
348 {
349 size_t new_bins = new_bins_.get();
350
351 if (new_bins < bins)
352 throw std::invalid_argument{"The number of new bins must be >= the current number of bins."};
353
354 // Equivalent to ceil(new_bins / 64)
355 size_t new_bin_words = (new_bins + 63) >> 6;
356
357 bins = new_bins;
358
359 if (new_bin_words == bin_words) // No need for internal resize if bin_words does not change.
360 return;
361
362 size_t new_technical_bins = new_bin_words << 6;
363 size_t new_bits = bin_size_ * new_technical_bins;
364
365 size_t idx_{new_bits}, idx{data.size()};
366 size_t delta = new_technical_bins - technical_bins + 64;
367
368 data.resize(new_bits);
369
370 for (size_t i = idx_, j = idx; j > 0; i -= new_technical_bins, j -= technical_bins)
371 {
372 size_t stop = i - new_technical_bins;
373
374 for (size_t ii = i - delta, jj = j - 64; stop && ii >= stop; ii -= 64, jj -= 64)
375 {
376 uint64_t old = data.get_int(jj);
377 data.set_int(jj, 0);
378 data.set_int(ii, old);
379 }
380 }
381
382 bin_words = new_bin_words;
383 technical_bins = new_technical_bins;
384 }
386
402 {
403 return membership_agent_type{*this};
404 }
405
417 template <typename value_t = uint16_t>
423
431 {
432 return hash_funs;
433 }
434
439 {
440 return bins;
441 }
442
447 {
448 return bin_size_;
449 }
450
455 {
456 return data.size();
457 }
459
469 {
470 return std::tie(lhs.bins,
471 lhs.technical_bins,
472 lhs.bin_size_,
473 lhs.hash_shift,
474 lhs.bin_words,
475 lhs.hash_funs,
476 lhs.data)
477 == std::tie(rhs.bins,
478 rhs.technical_bins,
479 rhs.bin_size_,
480 rhs.hash_shift,
481 rhs.bin_words,
482 rhs.hash_funs,
483 rhs.data);
484 }
485
492 {
493 return !(lhs == rhs);
494 }
496
508 {
509 return data;
510 }
511
513 constexpr data_type const & raw_data() const noexcept
514 {
515 return data;
516 }
518
526 template <cereal_archive archive_t>
528 {
529 archive(bins);
530 archive(technical_bins);
531 archive(bin_size_);
532 archive(hash_shift);
533 archive(bin_words);
534 archive(hash_funs);
535 archive(data);
536 }
538};
539
550template <data_layout data_layout_mode>
552{
553private:
556
558 ibf_t const * ibf_ptr{nullptr};
559
560public:
561 class binning_bitvector;
562
572
577 explicit membership_agent_type(ibf_t const & ibf) : ibf_ptr(std::addressof(ibf)), result_buffer(ibf.bin_count())
578 {}
580
583
604 [[nodiscard]] binning_bitvector const & bulk_contains(size_t const value) & noexcept
605 {
606 assert(ibf_ptr != nullptr);
607 assert(result_buffer.size() == ibf_ptr->bin_count());
608
610 std::memcpy(&bloom_filter_indices, &ibf_ptr->hash_seeds, sizeof(size_t) * ibf_ptr->hash_funs);
611
612 for (size_t i = 0; i < ibf_ptr->hash_funs; ++i)
613 bloom_filter_indices[i] = ibf_ptr->hash_and_fit(value, bloom_filter_indices[i]);
614
615 for (size_t batch = 0; batch < ibf_ptr->bin_words; ++batch)
616 {
617 size_t tmp{-1ULL};
618 for (size_t i = 0; i < ibf_ptr->hash_funs; ++i)
619 {
620 assert(bloom_filter_indices[i] < ibf_ptr->data.size());
621 tmp &= ibf_ptr->data.get_int(bloom_filter_indices[i]);
622 bloom_filter_indices[i] += 64;
623 }
624
625 result_buffer.data.set_int(batch << 6, tmp);
626 }
627
628 return result_buffer;
629 }
630
631 // `bulk_contains` cannot be called on a temporary, since the object the returned reference points to
632 // is immediately destroyed.
633 [[nodiscard]] binning_bitvector const & bulk_contains(size_t const value) && noexcept = delete;
635};
636
638template <data_layout data_layout_mode>
640{
641private:
643 using data_type = seqan3::contrib::sdsl::bit_vector;
645 data_type data{};
646
647 friend class membership_agent_type;
648
649public:
653 binning_bitvector() = default;
658 ~binning_bitvector() = default;
659
661 explicit binning_bitvector(size_t const size) : data(size)
662 {}
664
667 {
668 return data.size();
669 }
670
676 {
677 return data.begin();
678 }
679
682 {
683 return data.begin();
684 }
685
688 {
689 return data.end();
690 }
691
694 {
695 return data.end();
696 }
698
703 friend bool operator==(binning_bitvector const & lhs, binning_bitvector const & rhs) noexcept
704 {
705 return lhs.data == rhs.data;
706 }
707
709 friend bool operator!=(binning_bitvector const & lhs, binning_bitvector const & rhs) noexcept
710 {
711 return !(lhs == rhs);
712 }
714
719 auto operator[](size_t const i) noexcept
720 {
721 assert(i < size());
722 return data[i];
723 }
724
726 auto operator[](size_t const i) const noexcept
727 {
728 assert(i < size());
729 return data[i];
730 }
731
739 constexpr data_type & raw_data() noexcept
740 {
741 return data;
742 }
743
745 constexpr data_type const & raw_data() const noexcept
746 {
747 return data;
748 }
750};
751
775template <std::integral value_t>
776class counting_vector : public std::vector<value_t>
777{
778private:
781
783 template <typename binning_bitvector_t>
784 static constexpr bool is_binning_bitvector =
785 std::same_as<binning_bitvector_t,
787 || std::same_as<binning_bitvector_t,
789
790public:
794 counting_vector() = default;
795 counting_vector(counting_vector const &) = default;
799 ~counting_vector() = default;
800
801 using base_t::base_t;
803
816 template <typename binning_bitvector_t>
818 counting_vector & operator+=(binning_bitvector_t const & binning_bitvector)
819 {
820 for_each_set_bin(binning_bitvector,
821 [this](size_t const bin)
822 {
823 ++(*this)[bin];
824 });
825 return *this;
826 }
827
835 template <typename binning_bitvector_t>
837 counting_vector & operator-=(binning_bitvector_t const & binning_bitvector)
838 {
839 for_each_set_bin(binning_bitvector,
840 [this](size_t const bin)
841 {
842 assert((*this)[bin] > 0);
843 --(*this)[bin];
844 });
845 return *this;
846 }
847
859 {
860 assert(this->size() >= rhs.size()); // The counting vector may be bigger than what we need.
861
862 std::transform(this->begin(), this->end(), rhs.begin(), this->begin(), std::plus<value_t>());
863
864 return *this;
865 }
866
872 {
873 assert(this->size() >= rhs.size()); // The counting vector may be bigger than what we need.
874
875 std::transform(this->begin(),
876 this->end(),
877 rhs.begin(),
878 this->begin(),
879 [](auto a, auto b)
880 {
881 assert(a >= b);
882 return a - b;
883 });
884
885 return *this;
886 }
887
888private:
890 template <typename binning_bitvector_t, typename on_bin_fn_t>
891 void for_each_set_bin(binning_bitvector_t && binning_bitvector, on_bin_fn_t && on_bin_fn)
892 {
893 assert(this->size() >= binning_bitvector.size()); // The counting vector may be bigger than what we need.
894
895 // Jump to the next 1 and return the number of places jumped in the bit_sequence
896 auto jump_to_next_1bit = [](size_t & x)
897 {
898 auto const zeros = std::countr_zero(x);
899 x >>= zeros; // skip number of zeros
900 return zeros;
901 };
902
903 // Each iteration can handle 64 bits
904 for (size_t bit_pos = 0; bit_pos < binning_bitvector.size(); bit_pos += 64)
905 {
906 // get 64 bits starting at position `bit_pos`
907 size_t bit_sequence = binning_bitvector.raw_data().get_int(bit_pos);
908
909 // process each relative bin inside the bit_sequence
910 for (size_t bin = bit_pos; bit_sequence != 0u; ++bin, bit_sequence >>= 1)
911 {
912 // Jump to the next 1 and
913 bin += jump_to_next_1bit(bit_sequence);
914
915 on_bin_fn(bin);
916 }
917 }
918 }
919};
920
930template <data_layout data_layout_mode>
931template <typename value_t>
933{
934private:
935 static_assert(std::integral<value_t>, "The value type must model std::integral.");
936
939
941 ibf_t const * ibf_ptr{nullptr};
942
945
946public:
956
961 explicit counting_agent_type(ibf_t const & ibf) :
962 ibf_ptr(std::addressof(ibf)),
964 result_buffer(ibf.bin_count())
965 {}
967
970
993 template <std::ranges::range value_range_t>
995 {
996 assert(ibf_ptr != nullptr);
997 assert(result_buffer.size() == ibf_ptr->bin_count());
998
999 static_assert(std::ranges::input_range<value_range_t>, "The values must model input_range.");
1000 static_assert(std::unsigned_integral<std::ranges::range_value_t<value_range_t>>,
1001 "An individual value must be an unsigned integral.");
1002
1003 std::ranges::fill(result_buffer, 0);
1004
1005 for (auto && value : values)
1006 result_buffer += membership_agent.bulk_contains(value);
1007
1008 return result_buffer;
1009 }
1010
1011 // `bulk_count` cannot be called on a temporary, since the object the returned reference points to
1012 // is immediately destroyed.
1013 template <std::ranges::range value_range_t>
1014 [[nodiscard]] counting_vector<value_t> const & bulk_count(value_range_t && values) && noexcept = delete;
1016};
1017
1018} // namespace seqan3
Provides strong types for the (Interleaved) Bloom Filter.
Adaptions of concepts from the Cereal library.
A data structure that behaves like a std::vector and can be used to consolidate the results of multip...
Definition interleaved_bloom_filter.hpp:777
counting_vector & operator+=(counting_vector const &rhs)
Bin-wise addition of two seqan3::counting_vectors.
Definition interleaved_bloom_filter.hpp:858
counting_vector & operator=(counting_vector const &)=default
Defaulted.
counting_vector & operator=(counting_vector &&)=default
Defaulted.
counting_vector & operator+=(binning_bitvector_t const &binning_bitvector)
Bin-wise adds the bits of a seqan3::interleaved_bloom_filter::membership_agent_type::binning_bitvecto...
Definition interleaved_bloom_filter.hpp:818
counting_vector(counting_vector const &)=default
Defaulted.
~counting_vector()=default
Defaulted.
counting_vector(counting_vector &&)=default
Defaulted.
counting_vector & operator-=(binning_bitvector_t const &binning_bitvector)
Bin-wise subtracts the bits of a seqan3::interleaved_bloom_filter::membership_agent_type::binning_bit...
Definition interleaved_bloom_filter.hpp:837
counting_vector()=default
Defaulted.
counting_vector & operator-=(counting_vector const &rhs)
Bin-wise substraction of two seqan3::counting_vectors.
Definition interleaved_bloom_filter.hpp:871
A "pretty printer" for most SeqAn data structures and related types.
Definition debug_stream_type.hpp:79
Manages counting ranges of values for the seqan3::interleaved_bloom_filter.
Definition interleaved_bloom_filter.hpp:933
counting_vector< value_t > const & bulk_count(value_range_t &&values) &noexcept
Counts the occurrences in each bin for all values in a range.
Definition interleaved_bloom_filter.hpp:994
counting_agent_type(counting_agent_type &&)=default
Defaulted.
counting_agent_type(counting_agent_type const &)=default
Defaulted.
counting_vector< value_t > const & bulk_count(value_range_t &&values) &&noexcept=delete
Counts the occurrences in each bin for all values in a range.
counting_agent_type & operator=(counting_agent_type const &)=default
Defaulted.
counting_vector< value_t > result_buffer
Stores the result of bulk_count().
Definition interleaved_bloom_filter.hpp:969
counting_agent_type & operator=(counting_agent_type &&)=default
Defaulted.
A bitvector representing the result of a call to bulk_contains of the seqan3::interleaved_bloom_filte...
Definition interleaved_bloom_filter.hpp:640
constexpr data_type & raw_data() noexcept
Provides direct, unsafe access to the underlying data structure.
Definition interleaved_bloom_filter.hpp:739
auto end() noexcept
Returns an iterator to the element following the last element of the container.
Definition interleaved_bloom_filter.hpp:687
constexpr data_type const & raw_data() const noexcept
Provides direct, unsafe access to the underlying data structure.
Definition interleaved_bloom_filter.hpp:745
binning_bitvector(binning_bitvector const &)=default
Defaulted.
auto end() const noexcept
Returns an iterator to the element following the last element of the container.
Definition interleaved_bloom_filter.hpp:693
auto operator[](size_t const i) const noexcept
Return the i-th element.
Definition interleaved_bloom_filter.hpp:726
binning_bitvector(size_t const size)
Construct with given size.
Definition interleaved_bloom_filter.hpp:661
size_t size() const noexcept
Returns the number of elements.
Definition interleaved_bloom_filter.hpp:666
binning_bitvector & operator=(binning_bitvector &&)=default
Defaulted.
auto begin() noexcept
Returns an iterator to the first element of the container.
Definition interleaved_bloom_filter.hpp:675
auto begin() const noexcept
Returns an iterator to the first element of the container.
Definition interleaved_bloom_filter.hpp:681
auto operator[](size_t const i) noexcept
Return the i-th element.
Definition interleaved_bloom_filter.hpp:719
binning_bitvector & operator=(binning_bitvector const &)=default
Defaulted.
friend bool operator==(binning_bitvector const &lhs, binning_bitvector const &rhs) noexcept
Test for equality.
Definition interleaved_bloom_filter.hpp:703
friend bool operator!=(binning_bitvector const &lhs, binning_bitvector const &rhs) noexcept
Test for inequality.
Definition interleaved_bloom_filter.hpp:709
Manages membership queries for the seqan3::interleaved_bloom_filter.
Definition interleaved_bloom_filter.hpp:552
binning_bitvector const & bulk_contains(size_t const value) &noexcept
Determines set membership of a given value.
Definition interleaved_bloom_filter.hpp:604
membership_agent_type & operator=(membership_agent_type const &)=default
Defaulted.
binning_bitvector const & bulk_contains(size_t const value) &&noexcept=delete
Determines set membership of a given value.
membership_agent_type(membership_agent_type &&)=default
Defaulted.
membership_agent_type(membership_agent_type const &)=default
Defaulted.
membership_agent_type & operator=(membership_agent_type &&)=default
Defaulted.
binning_bitvector result_buffer
Stores the result of bulk_contains().
Definition interleaved_bloom_filter.hpp:582
The IBF binning directory. A data structure that efficiently answers set-membership queries for multi...
Definition interleaved_bloom_filter.hpp:98
interleaved_bloom_filter(interleaved_bloom_filter< data_layout::uncompressed > const &ibf)
Construct a compressed Interleaved Bloom Filter.
Definition interleaved_bloom_filter.hpp:236
void emplace(size_t const value, bin_index const bin) noexcept
Inserts a value into a specific bin.
Definition interleaved_bloom_filter.hpp:261
interleaved_bloom_filter(interleaved_bloom_filter< data_layout::compressed > const &ibf)
Construct an uncompressed Interleaved Bloom Filter from a compressed one.
Definition interleaved_bloom_filter.hpp:216
interleaved_bloom_filter & operator=(interleaved_bloom_filter const &)=default
Defaulted.
membership_agent_type membership_agent() const
Returns a seqan3::interleaved_bloom_filter::membership_agent_type to be used for lookup.
Definition interleaved_bloom_filter.hpp:401
size_t hash_function_count() const noexcept
Returns the number of hash functions used in the Interleaved Bloom Filter.
Definition interleaved_bloom_filter.hpp:430
constexpr data_type const & raw_data() const noexcept
Provides direct, unsafe access to the underlying data structure.
Definition interleaved_bloom_filter.hpp:513
void clear(bin_index const bin) noexcept
Clears a specific bin.
Definition interleaved_bloom_filter.hpp:285
interleaved_bloom_filter(seqan3::bin_count bins_, seqan3::bin_size size, seqan3::hash_function_count funs=seqan3::hash_function_count{2u})
Construct an uncompressed Interleaved Bloom Filter.
Definition interleaved_bloom_filter.hpp:186
interleaved_bloom_filter()=default
Defaulted.
counting_agent_type< value_t > counting_agent() const
Returns a seqan3::interleaved_bloom_filter::counting_agent_type to be used for counting.
Definition interleaved_bloom_filter.hpp:418
constexpr data_type & raw_data() noexcept
Provides direct, unsafe access to the underlying data structure.
Definition interleaved_bloom_filter.hpp:507
interleaved_bloom_filter & operator=(interleaved_bloom_filter &&)=default
Defaulted.
friend bool operator!=(interleaved_bloom_filter const &lhs, interleaved_bloom_filter const &rhs) noexcept
Test for inequality.
Definition interleaved_bloom_filter.hpp:491
interleaved_bloom_filter(interleaved_bloom_filter &&)=default
Defaulted.
void increase_bin_number_to(bin_count const new_bins_)
Increases the number of bins stored in the Interleaved Bloom Filter.
Definition interleaved_bloom_filter.hpp:346
size_t bin_count() const noexcept
Returns the number of bins that the Interleaved Bloom Filter manages.
Definition interleaved_bloom_filter.hpp:438
void clear(rng_t &&bin_range) noexcept
Clears a range of bins.
Definition interleaved_bloom_filter.hpp:308
size_t bin_size() const noexcept
Returns the size of a single bin that the Interleaved Bloom Filter manages.
Definition interleaved_bloom_filter.hpp:446
size_t bit_size() const noexcept
Returns the size of the underlying bitvector.
Definition interleaved_bloom_filter.hpp:454
interleaved_bloom_filter(interleaved_bloom_filter const &)=default
Defaulted.
~interleaved_bloom_filter()=default
Defaulted.
friend bool operator==(interleaved_bloom_filter const &lhs, interleaved_bloom_filter const &rhs) noexcept
Test for equality.
Definition interleaved_bloom_filter.hpp:468
static constexpr data_layout data_layout_mode
Indicates whether the Interleaved Bloom Filter is compressed.
Definition interleaved_bloom_filter.hpp:156
T countl_zero(T... args)
T countr_zero(T... args)
T fill(T... args)
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
data_layout
Determines if the Interleaved Bloom Filter is compressed.
Definition bloom_filter_strong_types.hpp:23
@ uncompressed
The Interleaved Bloom Filter is uncompressed.
Definition bloom_filter_strong_types.hpp:24
@ compressed
The Interleaved Bloom Filter is compressed.
Definition bloom_filter_strong_types.hpp:25
T memcpy(T... args)
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
SeqAn specific customisations in the standard namespace.
A strong type that represents the number of bins for the seqan3::interleaved_bloom_filter.
Definition bloom_filter_strong_types.hpp:31
A strong type that represents the bin index for the seqan3::interleaved_bloom_filter.
Definition bloom_filter_strong_types.hpp:52
A strong type that represents the number of bits for each bin in the seqan3::interleaved_bloom_filter...
Definition bloom_filter_strong_types.hpp:38
A strong type that represents the number of hash functions for the seqan3::interleaved_bloom_filter.
Definition bloom_filter_strong_types.hpp:45
strong_type for seed.
Definition minimiser_hash.hpp:22
T tie(T... args)
T transform(T... args)
Hide me