btllib
counting_bloom_filter.hpp
1#ifndef BTLLIB_COUNTING_BLOOM_FILTER_HPP
2#define BTLLIB_COUNTING_BLOOM_FILTER_HPP
3
4#include "btllib/bloom_filter.hpp"
5#include "btllib/counting_bloom_filter.hpp"
6#include "btllib/nthash.hpp"
7#include "btllib/status.hpp"
8
9#include "cpptoml.h"
10
11#include <atomic>
12#include <cmath>
13#include <cstdint>
14#include <fstream>
15#include <limits>
16#include <memory>
17#include <string>
18#include <vector>
19
20namespace btllib {
21
22// NOLINTNEXTLINE(clang-diagnostic-unneeded-internal-declaration)
23static const char* const COUNTING_BLOOM_FILTER_SIGNATURE =
24 "[BTLCountingBloomFilter_v5]";
25// NOLINTNEXTLINE(clang-diagnostic-unneeded-internal-declaration)
26static const char* const KMER_COUNTING_BLOOM_FILTER_SIGNATURE =
27 "[BTLKmerCountingBloomFilter_v5]";
28
29template<typename T>
30class KmerCountingBloomFilter;
31
37template<typename T>
39{
40
41public:
44
52 CountingBloomFilter(size_t bytes,
53 unsigned hash_num,
54 std::string hash_fn = "");
55
61 explicit CountingBloomFilter(const std::string& path);
62
65
66 CountingBloomFilter& operator=(const CountingBloomFilter&) = delete;
67 CountingBloomFilter& operator=(CountingBloomFilter&&) = delete;
68
75 void insert(const uint64_t* hashes);
76
82 void insert(const std::vector<uint64_t>& hashes) { insert(hashes.data()); }
83
92 T contains(const uint64_t* hashes) const;
93
101 T contains(const std::vector<uint64_t>& hashes) const
102 {
103 return contains(hashes.data());
104 }
105
114 T contains_insert(const uint64_t* hashes);
115
123 T contains_insert(const std::vector<uint64_t>& hashes)
124 {
125 return contains_insert(hashes.data());
126 }
127
137 T insert_contains(const uint64_t* hashes);
138
146 T insert_contains(const std::vector<uint64_t>& hashes)
147 {
148 return insert_contains(hashes.data());
149 }
150
162 T insert_thresh_contains(const uint64_t* hashes, T threshold);
163
175 T insert_thresh_contains(const std::vector<uint64_t>& hashes,
176 const T threshold)
177 {
178 return insert_thresh_contains(hashes.data(), threshold);
179 }
180
192 T contains_insert_thresh(const uint64_t* hashes, T threshold);
193
203 T contains_insert_thresh(const std::vector<uint64_t>& hashes,
204 const T threshold)
205 {
206 return contains_insert_thresh(hashes.data(), threshold);
207 }
208
210 size_t get_bytes() const { return bytes; }
213 uint64_t get_pop_cnt(T threshold = 1) const;
215 double get_occupancy(T threshold = 1) const;
217 unsigned get_hash_num() const { return hash_num; }
224 double get_fpr(T threshold = 1) const;
226 const std::string& get_hash_fn() const { return hash_fn; }
227
233 void save(const std::string& path);
234
240 static bool is_bloom_file(const std::string& path)
241 {
242 return btllib::BloomFilter::check_file_signature(
243 path, COUNTING_BLOOM_FILTER_SIGNATURE);
244 }
245
246private:
247 CountingBloomFilter(const std::shared_ptr<BloomFilterInitializer>& bfi);
248
249 void insert(const uint64_t* hashes, T min_val);
250
251 friend class KmerCountingBloomFilter<T>;
252
253 size_t bytes = 0;
254 size_t array_size = 0;
255 unsigned hash_num = 0;
256 std::string hash_fn;
257 std::unique_ptr<std::atomic<T>[]> array;
258};
259
265template<typename T>
267{
268
269public:
272
280 KmerCountingBloomFilter(size_t bytes, unsigned hash_num, unsigned k);
281
287 explicit KmerCountingBloomFilter(const std::string& path);
288
291
292 KmerCountingBloomFilter& operator=(const KmerCountingBloomFilter&) = delete;
294
301 void insert(const char* seq, size_t seq_len);
302
308 void insert(const std::string& seq) { insert(seq.c_str(), seq.size()); }
309
316 void insert(const uint64_t* hashes) { counting_bloom_filter.insert(hashes); }
317
323 void insert(const std::vector<uint64_t>& hashes)
324 {
325 counting_bloom_filter.insert(hashes);
326 }
327
336 uint64_t contains(const char* seq, size_t seq_len) const;
337
345 uint64_t contains(const std::string& seq) const
346 {
347 return contains(seq.c_str(), seq.size());
348 }
349
358 T contains(const uint64_t* hashes) const
359 {
360 return counting_bloom_filter.contains(hashes);
361 }
362
370 T contains(const std::vector<uint64_t>& hashes) const
371 {
372 return counting_bloom_filter.contains(hashes);
373 }
374
383 T contains_insert(const char* seq, size_t seq_len);
384
392 T contains_insert(const std::string& seq)
393 {
394 return contains_insert(seq.c_str(), seq.size());
395 }
396
405 T contains_insert(const uint64_t* hashes)
406 {
407 return counting_bloom_filter.contains_insert(hashes);
408 }
409
417 T contains_insert(const std::vector<uint64_t>& hashes)
418 {
419 return counting_bloom_filter.contains_insert(hashes);
420 }
421
430 T insert_contains(const char* seq, size_t seq_len);
431
439 T insert_contains(const std::string& seq)
440 {
441 return insert_contains(seq.c_str(), seq.size());
442 }
443
453 T insert_contains(const uint64_t* hashes)
454 {
455 return counting_bloom_filter.insert_contains(hashes);
456 }
457
465 T insert_contains(const std::vector<uint64_t>& hashes)
466 {
467 return counting_bloom_filter.insert_contains(hashes);
468 }
469
480 T insert_thresh_contains(const char* seq, size_t seq_len, T threshold);
481
491 T insert_thresh_contains(const std::string& seq, const T threshold)
492 {
493 return insert_thresh_contains(seq.c_str(), seq.size(), threshold);
494 }
495
507 T insert_thresh_contains(const uint64_t* hashes, const T threshold)
508 {
509 return counting_bloom_filter.insert_thresh_contains(hashes, threshold);
510 }
511
523 T insert_thresh_contains(const std::vector<uint64_t>& hashes,
524 const T threshold)
525 {
526 return counting_bloom_filter.insert_thresh_contains(hashes, threshold);
527 }
528
539 T contains_insert_thresh(const char* seq, size_t seq_len, T threshold);
540
550 T contains_insert_thresh(const std::string& seq, const T threshold)
551 {
552 return contains_insert_thresh(seq.c_str(), seq.size(), threshold);
553 }
554
566 T contains_insert_thresh(const uint64_t* hashes, const T threshold)
567 {
568 return counting_bloom_filter.contains_insert_thresh(hashes, threshold);
569 }
570
580 T contains_insert_thresh(const std::vector<uint64_t>& hashes,
581 const T threshold)
582 {
583 return counting_bloom_filter.contains_insert_thresh(hashes, threshold);
584 }
585
587 size_t get_bytes() const { return counting_bloom_filter.get_bytes(); }
589 uint64_t get_pop_cnt(T threshold = 1) const
590 {
591 return counting_bloom_filter.get_pop_cnt(threshold);
592 }
594 double get_occupancy(T threshold = 1) const
595 {
596 return counting_bloom_filter.get_occupancy(threshold);
597 }
599 unsigned get_hash_num() const { return counting_bloom_filter.get_hash_num(); }
606 double get_fpr(T threshold = 1) const
607 {
608 return counting_bloom_filter.get_fpr(threshold);
609 }
611 unsigned get_k() const { return k; }
613 const std::string& get_hash_fn() const
614 {
615 return counting_bloom_filter.get_hash_fn();
616 }
619 {
620 return counting_bloom_filter;
621 }
622
628 void save(const std::string& path);
629
636 static bool is_bloom_file(const std::string& path)
637 {
638 return btllib::BloomFilter::check_file_signature(
639 path, KMER_COUNTING_BLOOM_FILTER_SIGNATURE);
640 }
641
642private:
643 KmerCountingBloomFilter(const std::shared_ptr<BloomFilterInitializer>& bfi);
644
645 unsigned k = 0;
646 CountingBloomFilter<T> counting_bloom_filter;
647};
648
649using CountingBloomFilter8 = CountingBloomFilter<uint8_t>;
650using CountingBloomFilter16 = CountingBloomFilter<uint16_t>;
651using CountingBloomFilter32 = CountingBloomFilter<uint32_t>;
652
653using KmerCountingBloomFilter8 = KmerCountingBloomFilter<uint8_t>;
654using KmerCountingBloomFilter16 = KmerCountingBloomFilter<uint16_t>;
655using KmerCountingBloomFilter32 = KmerCountingBloomFilter<uint32_t>;
656
657template<typename T>
659 unsigned hash_num,
660 std::string hash_fn)
661 : bytes(
662 size_t(std::ceil(double(bytes) / sizeof(uint64_t)) * sizeof(uint64_t)))
663 , array_size(get_bytes() / sizeof(array[0]))
664 , hash_num(hash_num)
665 , hash_fn(std::move(hash_fn))
666 , array(new std::atomic<T>[array_size])
667{
668 check_error(bytes == 0, "CountingBloomFilter: memory budget must be >0!");
669 check_error(hash_num == 0,
670 "CountingBloomFilter: number of hash values must be >0!");
672 hash_num > MAX_HASH_VALUES,
673 "CountingBloomFilter: number of hash values cannot be over 1024!");
674 check_warning(sizeof(uint8_t) != sizeof(std::atomic<uint8_t>),
675 "Atomic primitives take extra memory. CountingBloomFilter will "
676 "have less than " +
677 std::to_string(bytes) + " for bit array.");
678 std::memset((void*)array.get(), 0, array_size * sizeof(array[0]));
679}
680
681/*
682 * Assumes min_count is not std::numeric_limits<T>::max()
683 */
684template<typename T>
685inline void
686CountingBloomFilter<T>::insert(const uint64_t* hashes, T min_val)
687{
688 // Update flag to track if increment is done on at least one counter
689 bool update_done = false;
690 T new_val, tmp_min_val;
691 while (true) {
692 new_val = min_val + 1;
693 for (size_t i = 0; i < hash_num; ++i) {
694 tmp_min_val = min_val;
695 update_done = array[hashes[i] % array_size].compare_exchange_strong(
696 tmp_min_val, new_val);
697 }
698 if (update_done ||
699 (min_val = contains(hashes)) == std::numeric_limits<T>::max()) {
700 break;
701 }
702 }
703}
704
705template<typename T>
706inline void
707CountingBloomFilter<T>::insert(const uint64_t* hashes)
708{
709 contains_insert(hashes);
710}
711
712template<typename T>
713inline T
714CountingBloomFilter<T>::contains(const uint64_t* hashes) const
715{
716 T min = array[hashes[0] % array_size];
717 for (size_t i = 1; i < hash_num; ++i) {
718 const size_t idx = hashes[i] % array_size;
719 if (array[idx] < min) {
720 min = array[idx];
721 }
722 }
723 return min;
724}
725
726template<typename T>
727inline T
729{
730 const auto count = contains(hashes);
731 if (count < std::numeric_limits<T>::max()) {
732 insert(hashes, count);
733 }
734 return count;
735}
736
737template<typename T>
738inline T
740{
741 const auto count = contains(hashes);
742 if (count < std::numeric_limits<T>::max()) {
743 insert(hashes, count);
744 return count + 1;
745 }
746 return std::numeric_limits<T>::max();
747}
748
749template<typename T>
750inline T
752 const T threshold)
753{
754 const auto count = contains(hashes);
755 if (count < threshold) {
756 insert(hashes, count);
757 return count + 1;
758 }
759 return count;
760}
761
762template<typename T>
763inline T
765 const T threshold)
766{
767 const auto count = contains(hashes);
768 if (count < threshold) {
769 insert(hashes, count);
770 }
771 return count;
772}
773
774template<typename T>
775inline uint64_t
777{
778 uint64_t pop_cnt = 0;
779 // OpenMP make up your mind man. Using default(none) here causes errors on
780 // some compilers and not others.
781 // NOLINTNEXTLINE(openmp-use-default-none,-warnings-as-errors)
782#pragma omp parallel for reduction(+ : pop_cnt)
783 for (size_t i = 0; i < array_size; ++i) {
784 if (array[i] >= threshold) {
785 ++pop_cnt;
786 }
787 }
788 return pop_cnt;
789}
790
791template<typename T>
792inline double
794{
795 return double(get_pop_cnt(threshold)) / double(array_size);
796}
797
798template<typename T>
799inline double
800CountingBloomFilter<T>::get_fpr(const T threshold) const
801{
802 return std::pow(get_occupancy(threshold), double(hash_num));
803}
804
805template<typename T>
806inline CountingBloomFilter<T>::CountingBloomFilter(const std::string& path)
808 std::make_shared<BloomFilterInitializer>(path,
809 COUNTING_BLOOM_FILTER_SIGNATURE))
810{}
811
812template<typename T>
814 const std::shared_ptr<BloomFilterInitializer>& bfi)
815 : bytes(*bfi->table->get_as<decltype(bytes)>("bytes"))
816 , array_size(bytes / sizeof(array[0]))
817 , hash_num(*(bfi->table->get_as<decltype(hash_num)>("hash_num")))
818 , hash_fn(bfi->table->contains("hash_fn")
819 ? *(bfi->table->get_as<decltype(hash_fn)>("hash_fn"))
820 : "")
821 , array(new std::atomic<T>[array_size])
822{
823 check_warning(sizeof(uint8_t) != sizeof(std::atomic<uint8_t>),
824 "Atomic primitives take extra memory. CountingBloomFilter will "
825 "have less than " +
826 std::to_string(bytes) + " for bit array.");
827 const auto loaded_counter_bits =
828 *(bfi->table->get_as<size_t>("counter_bits"));
829 check_error(sizeof(array[0]) * CHAR_BIT != loaded_counter_bits,
830 "CountingBloomFilter" +
831 std::to_string(sizeof(array[0]) * CHAR_BIT) +
832 " tried to load a file of CountingBloomFilter" +
833 std::to_string(loaded_counter_bits));
834 bfi->ifs.read((char*)array.get(),
835 std::streamsize(array_size * sizeof(array[0])));
836}
837
838template<typename T>
839inline void
840CountingBloomFilter<T>::save(const std::string& path)
841{
842 /* Initialize cpptoml root table
843 Note: Tables and fields are unordered
844 Ordering of table is maintained by directing the table
845 to the output stream immediately after completion */
846 auto root = cpptoml::make_table();
847
848 /* Initialize bloom filter section and insert fields
849 and output to ostream */
850 auto header = cpptoml::make_table();
851 header->insert("bytes", get_bytes());
852 header->insert("hash_num", get_hash_num());
853 if (!hash_fn.empty()) {
854 header->insert("hash_fn", hash_fn);
855 }
856 header->insert("counter_bits", size_t(sizeof(array[0]) * CHAR_BIT));
857 std::string header_string = COUNTING_BLOOM_FILTER_SIGNATURE;
858 header_string =
859 header_string.substr(1, header_string.size() - 2); // Remove [ ]
860 root->insert(header_string, header);
861
863 path, *root, (char*)array.get(), array_size * sizeof(array[0]));
864}
865
866template<typename T>
868 unsigned hash_num,
869 unsigned k)
870 : k(k)
871 , counting_bloom_filter(bytes, hash_num, HASH_FN)
872{}
873
874template<typename T>
875inline void
876KmerCountingBloomFilter<T>::insert(const char* seq, size_t seq_len)
877{
878 NtHash nthash(seq, seq_len, get_hash_num(), get_k());
879 while (nthash.roll()) {
880 counting_bloom_filter.insert(nthash.hashes());
881 }
882}
883
884template<typename T>
885inline uint64_t
886KmerCountingBloomFilter<T>::contains(const char* seq, size_t seq_len) const
887{
888 uint64_t sum = 0;
889 NtHash nthash(seq, seq_len, get_hash_num(), get_k());
890 while (nthash.roll()) {
891 sum += counting_bloom_filter.contains(nthash.hashes());
892 }
893 return sum;
894}
895
896template<typename T>
897inline T
898KmerCountingBloomFilter<T>::contains_insert(const char* seq, size_t seq_len)
899{
900 uint64_t sum = 0;
901 NtHash nthash(seq, seq_len, get_hash_num(), get_k());
902 while (nthash.roll()) {
903 sum += counting_bloom_filter.contains_insert(nthash.hashes());
904 }
905 return sum;
906}
907
908template<typename T>
909inline T
910KmerCountingBloomFilter<T>::insert_contains(const char* seq, size_t seq_len)
911{
912 uint64_t sum = 0;
913 NtHash nthash(seq, seq_len, get_hash_num(), get_k());
914 while (nthash.roll()) {
915 sum += counting_bloom_filter.insert_contains(nthash.hashes());
916 }
917 return sum;
918}
919
920template<typename T>
921inline T
923 size_t seq_len,
924 const T threshold)
925{
926 uint64_t sum = 0;
927 NtHash nthash(seq, seq_len, get_hash_num(), get_k());
928 while (nthash.roll()) {
929 sum +=
930 counting_bloom_filter.insert_thresh_contains(nthash.hashes(), threshold);
931 }
932 return sum;
933}
934
935template<typename T>
936inline T
938 size_t seq_len,
939 const T threshold)
940{
941 uint64_t sum = 0;
942 NtHash nthash(seq, seq_len, get_hash_num(), get_k());
943 while (nthash.roll()) {
944 sum +=
945 counting_bloom_filter.contains_insert_thresh(nthash.hashes(), threshold);
946 }
947 return sum;
948}
949
950template<typename T>
952 const std::string& path)
954 std::make_shared<BloomFilterInitializer>(
955 path,
956 KMER_COUNTING_BLOOM_FILTER_SIGNATURE))
957{}
958
959template<typename T>
961 const std::shared_ptr<BloomFilterInitializer>& bfi)
962 : k(*(bfi->table->get_as<decltype(k)>("k")))
963 , counting_bloom_filter(bfi)
964{
965 check_error(counting_bloom_filter.hash_fn != HASH_FN,
966 "KmerCountingBloomFilter: loaded hash function (" +
967 counting_bloom_filter.hash_fn +
968 ") is different from the one used by default (" + HASH_FN +
969 ").");
970}
971
972template<typename T>
973inline void
974KmerCountingBloomFilter<T>::save(const std::string& path)
975{
976 /* Initialize cpptoml root table
977 Note: Tables and fields are unordered
978 Ordering of table is maintained by directing the table
979 to the output stream immediately after completion */
980 auto root = cpptoml::make_table();
981
982 /* Initialize bloom filter section and insert fields
983 and output to ostream */
984 auto header = cpptoml::make_table();
985 header->insert("bytes", get_bytes());
986 header->insert("hash_num", get_hash_num());
987 header->insert("hash_fn", get_hash_fn());
988 header->insert("counter_bits",
989 size_t(sizeof(counting_bloom_filter.array[0]) * CHAR_BIT));
990 header->insert("k", k);
991 std::string header_string = KMER_COUNTING_BLOOM_FILTER_SIGNATURE;
992 header_string =
993 header_string.substr(1, header_string.size() - 2); // Remove [ ]
994 root->insert(header_string, header);
995
997 *root,
998 (char*)counting_bloom_filter.array.get(),
999 counting_bloom_filter.array_size *
1000 sizeof(counting_bloom_filter.array[0]));
1001}
1002
1003} // namespace btllib
1004
1005#endif
void save(const std::string &path)
Definition: counting_bloom_filter.hpp:39
T insert_thresh_contains(const std::vector< uint64_t > &hashes, const T threshold)
Definition: counting_bloom_filter.hpp:175
void insert(const std::vector< uint64_t > &hashes)
Definition: counting_bloom_filter.hpp:82
double get_occupancy(T threshold=1) const
Definition: counting_bloom_filter.hpp:793
const std::string & get_hash_fn() const
Definition: counting_bloom_filter.hpp:226
T contains_insert(const uint64_t *hashes)
Definition: counting_bloom_filter.hpp:728
static bool is_bloom_file(const std::string &path)
Definition: counting_bloom_filter.hpp:240
double get_fpr(T threshold=1) const
Definition: counting_bloom_filter.hpp:800
uint64_t get_pop_cnt(T threshold=1) const
Definition: counting_bloom_filter.hpp:776
T insert_contains(const std::vector< uint64_t > &hashes)
Definition: counting_bloom_filter.hpp:146
void save(const std::string &path)
Definition: counting_bloom_filter.hpp:840
T contains_insert_thresh(const uint64_t *hashes, T threshold)
Definition: counting_bloom_filter.hpp:764
T contains(const std::vector< uint64_t > &hashes) const
Definition: counting_bloom_filter.hpp:101
size_t get_bytes() const
Definition: counting_bloom_filter.hpp:210
unsigned get_hash_num() const
Definition: counting_bloom_filter.hpp:217
T contains(const uint64_t *hashes) const
Definition: counting_bloom_filter.hpp:714
CountingBloomFilter()
Definition: counting_bloom_filter.hpp:43
T insert_contains(const uint64_t *hashes)
Definition: counting_bloom_filter.hpp:739
void insert(const uint64_t *hashes)
Definition: counting_bloom_filter.hpp:707
T contains_insert_thresh(const std::vector< uint64_t > &hashes, const T threshold)
Definition: counting_bloom_filter.hpp:203
T insert_thresh_contains(const uint64_t *hashes, T threshold)
Definition: counting_bloom_filter.hpp:751
T contains_insert(const std::vector< uint64_t > &hashes)
Definition: counting_bloom_filter.hpp:123
Definition: counting_bloom_filter.hpp:267
uint64_t contains(const char *seq, size_t seq_len) const
Definition: counting_bloom_filter.hpp:886
T insert_contains(const std::vector< uint64_t > &hashes)
Definition: counting_bloom_filter.hpp:465
T insert_thresh_contains(const std::vector< uint64_t > &hashes, const T threshold)
Definition: counting_bloom_filter.hpp:523
void save(const std::string &path)
Definition: counting_bloom_filter.hpp:974
CountingBloomFilter< T > & get_counting_bloom_filter()
Definition: counting_bloom_filter.hpp:618
T insert_contains(const char *seq, size_t seq_len)
Definition: counting_bloom_filter.hpp:910
T insert_thresh_contains(const std::string &seq, const T threshold)
Definition: counting_bloom_filter.hpp:491
T contains_insert_thresh(const uint64_t *hashes, const T threshold)
Definition: counting_bloom_filter.hpp:566
T insert_thresh_contains(const char *seq, size_t seq_len, T threshold)
Definition: counting_bloom_filter.hpp:922
T contains(const uint64_t *hashes) const
Definition: counting_bloom_filter.hpp:358
T contains_insert(const uint64_t *hashes)
Definition: counting_bloom_filter.hpp:405
T contains_insert(const std::vector< uint64_t > &hashes)
Definition: counting_bloom_filter.hpp:417
T contains_insert(const std::string &seq)
Definition: counting_bloom_filter.hpp:392
size_t get_bytes() const
Definition: counting_bloom_filter.hpp:587
T contains_insert_thresh(const char *seq, size_t seq_len, T threshold)
Definition: counting_bloom_filter.hpp:937
T insert_thresh_contains(const uint64_t *hashes, const T threshold)
Definition: counting_bloom_filter.hpp:507
T contains_insert_thresh(const std::vector< uint64_t > &hashes, const T threshold)
Definition: counting_bloom_filter.hpp:580
T insert_contains(const std::string &seq)
Definition: counting_bloom_filter.hpp:439
const std::string & get_hash_fn() const
Definition: counting_bloom_filter.hpp:613
void insert(const std::vector< uint64_t > &hashes)
Definition: counting_bloom_filter.hpp:323
void insert(const char *seq, size_t seq_len)
Definition: counting_bloom_filter.hpp:876
double get_occupancy(T threshold=1) const
Definition: counting_bloom_filter.hpp:594
T contains_insert(const char *seq, size_t seq_len)
Definition: counting_bloom_filter.hpp:898
unsigned get_hash_num() const
Definition: counting_bloom_filter.hpp:599
uint64_t get_pop_cnt(T threshold=1) const
Definition: counting_bloom_filter.hpp:589
T insert_contains(const uint64_t *hashes)
Definition: counting_bloom_filter.hpp:453
double get_fpr(T threshold=1) const
Definition: counting_bloom_filter.hpp:606
unsigned get_k() const
Definition: counting_bloom_filter.hpp:611
void insert(const std::string &seq)
Definition: counting_bloom_filter.hpp:308
uint64_t contains(const std::string &seq) const
Definition: counting_bloom_filter.hpp:345
void insert(const uint64_t *hashes)
Definition: counting_bloom_filter.hpp:316
T contains_insert_thresh(const std::string &seq, const T threshold)
Definition: counting_bloom_filter.hpp:550
static bool is_bloom_file(const std::string &path)
Definition: counting_bloom_filter.hpp:636
KmerCountingBloomFilter()
Definition: counting_bloom_filter.hpp:271
T contains(const std::vector< uint64_t > &hashes) const
Definition: counting_bloom_filter.hpp:370
Definition: nthash.hpp:54
Definition: bloom_filter.hpp:16
void check_error(bool condition, const std::string &msg)
void check_warning(bool condition, const std::string &msg)