Skip to content

Commit

Permalink
Merge pull request #90 from eseiler/misc/membership_for
Browse files Browse the repository at this point in the history
[MISC] membership_for
  • Loading branch information
eseiler authored Sep 12, 2023
2 parents 50c96cb + 6df61a9 commit 1d15ef5
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 10 deletions.
18 changes: 11 additions & 7 deletions include/hibf/hierarchical_interleaved_bloom_filter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ class hierarchical_interleaved_bloom_filter::membership_agent_type

//!\brief Helper for recursive membership querying.
template <std::ranges::forward_range value_range_t>
void membership_for_impl(value_range_t && values, int64_t const ibf_idx, size_t const threshold)
void membership_for_impl(value_range_t && values, int64_t const ibf_idx, uint16_t const threshold)
{
auto agent = hibf_ptr->ibf_vector[ibf_idx].template counting_agent<uint16_t>();
auto & result = agent.bulk_count(values);
Expand Down Expand Up @@ -229,8 +229,8 @@ class hierarchical_interleaved_bloom_filter::membership_agent_type

public:
/*!\name Constructors, destructor and assignment
* \{
*/
* \{
*/
membership_agent_type() = default; //!< Defaulted.
membership_agent_type(membership_agent_type const &) = default; //!< Defaulted.
membership_agent_type & operator=(membership_agent_type const &) = delete; //!< Deleted. hibf_ptr is const.
Expand All @@ -249,6 +249,12 @@ class hierarchical_interleaved_bloom_filter::membership_agent_type
//!\brief Stores the result of membership_for().
std::vector<int64_t> result_buffer;

//!\brief Sorts the results.
void sort_results()
{
std::ranges::sort(result_buffer);
}

/*!\name Lookup
* \{
*/
Expand Down Expand Up @@ -290,7 +296,7 @@ class hierarchical_interleaved_bloom_filter::membership_agent_type
*/
template <std::ranges::forward_range value_range_t>
[[nodiscard]] std::vector<int64_t> const & membership_for(value_range_t && values,
size_t const threshold) & noexcept
uint16_t const threshold) & noexcept
{
assert(hibf_ptr != nullptr);

Expand All @@ -302,16 +308,14 @@ class hierarchical_interleaved_bloom_filter::membership_agent_type

membership_for_impl(values, 0, threshold);

std::ranges::sort(result_buffer); // TODO: necessary?

return result_buffer;
}

// `membership_for` cannot be called on a temporary, since the object the returned reference points to
// is immediately destroyed.
template <std::ranges::range value_range_t>
[[nodiscard]] std::vector<int64_t> const & membership_for(value_range_t && values,
size_t const threshold) && noexcept = delete;
uint16_t const threshold) && noexcept = delete;
//!\}
};

Expand Down
5 changes: 3 additions & 2 deletions test/snippet/readme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,16 @@ int main()

// query1 hits in user_bin_1 and user_bin_3, which have the IDs 0 and 2, respectively.
for (int64_t hit_user_bin : result1)
std::cout << hit_user_bin << ' '; // 0 2
std::cout << hit_user_bin << ' '; // The results are not sorted: 2 0
std::cout << '\n';

// Another query. A query is simply a range of unsigned integer values, e.g., it does not have to be a vector.
auto query2 = std::views::iota(0u, 15u); // 0,1,2,...,14
auto & result2 = agent.membership_for(query2, 5u);
agent.sort_results(); // Sort the results.

// query2 hits in user_bin_1 and user_bin_2, which have the IDs 0 and 1, respectively.
for (int64_t hit_user_bin : result2)
std::cout << hit_user_bin << ' '; // 0 1
std::cout << hit_user_bin << ' '; // The results are sorted: 0 1
std::cout << '\n';
}
2 changes: 1 addition & 1 deletion test/snippet/readme.out
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
0 2
2 0
0 1
4 changes: 4 additions & 0 deletions test/unit/hibf/hierarchical_interleaved_bloom_filter_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ TEST(hibf_test, small_example_with_direct_hashes)
std::vector<size_t> query{1u, 2u, 3u, 4u, 5u};

auto & result = agent.membership_for(query, 2u);
agent.sort_results();
EXPECT_RANGE_EQ(result, (std::vector<size_t>{0u, 1u}));
}

Expand Down Expand Up @@ -87,6 +88,7 @@ TEST(hibf_test, build_from_layout)
std::vector<size_t> query{1u, 2u, 3u, 4u, 5u};

auto & result = agent.membership_for(query, 2u);
agent.sort_results();
EXPECT_RANGE_EQ(result, (std::vector<size_t>{0u, 1u}));
}

Expand Down Expand Up @@ -122,6 +124,7 @@ TEST(hibf_test, three_level_hibf)
auto unique_query = std::views::iota(start + 5u, start + 9u);

auto & overlap_result = agent.membership_for(overlap_query, 4u); // one overlapping user bin
agent.sort_results();
EXPECT_EQ(overlap_result.size(), 2u);
EXPECT_EQ(overlap_result[0], ub_id);
EXPECT_EQ(overlap_result[1], ub_id + 1u);
Expand Down Expand Up @@ -202,6 +205,7 @@ TEST(hibf_test, evenly_sized_and_highly_similar_user_bins)
auto similar_query = std::views::iota(start, start + 5u);

auto & similar_result = agent.membership_for(similar_query, 5u); // t = 5 results in 6 similar user bins
agent.sort_results();
EXPECT_RANGE_EQ(similar_result, (std::views::iota(ub_id - 6u, ub_id + 1u)));
}
}
Expand Down

1 comment on commit 1d15ef5

@vercel
Copy link

@vercel vercel bot commented on 1d15ef5 Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

hibf – ./

hibf.vercel.app
hibf-seqan.vercel.app
hibf-git-main-seqan.vercel.app

Please sign in to comment.