diff --git a/support/src/indirect_intrusive_heap.h b/support/src/indirect_intrusive_heap.h index c3b4dd5..ec6b0ca 100644 --- a/support/src/indirect_intrusive_heap.h +++ b/support/src/indirect_intrusive_heap.h @@ -294,6 +294,49 @@ namespace crimson { return end(); } + ConstIterator find(const I& ind_item) const { + for (HeapIndex i = 0; i < count; ++i) { + if (data[i] == ind_item) { + return ConstIterator(*this, i); + } + } + return cend(); + } + + // when passing in value we do a comparison via operator== + ConstIterator find(const T& item) const { + for (HeapIndex i = 0; i < count; ++i) { + if (*data[i] == item) { + return ConstIterator(*this, i); + } + } + return cend(); + } + + // reverse find -- start looking from bottom of heap + ConstIterator rfind(const I& ind_item) const { + // HeapIndex is unsigned, so we can't allow to go negative; so + // we'll keep it one more than actual index + for (HeapIndex i = count; i > 0; --i) { + if (data[i-1] == ind_item) { + return ConstIterator(*this, i-1); + } + } + return cend(); + } + + // reverse find -- start looking from bottom of heap + ConstIterator rfind(const T& item) const { + // HeapIndex is unsigned, so we can't allow to go negative; so + // we'll keep it one more than actual index + for (HeapIndex i = count; i > 0; --i) { + if (*data[i-1] == item) { + return ConstIterator(*this, i-1); + } + } + return cend(); + } + void promote(T& item) { sift_up(item.*heap_info); } diff --git a/support/test/test_indirect_intrusive_heap.cc b/support/test/test_indirect_intrusive_heap.cc index 143998a..2d6c4da 100644 --- a/support/test/test_indirect_intrusive_heap.cc +++ b/support/test/test_indirect_intrusive_heap.cc @@ -796,6 +796,63 @@ TEST_F(HeapFixture1, iterator_find_rfind) { } +TEST_F(HeapFixture1, const_iterator_find_rfind) { + const auto& c_heap = heap; + + { + auto it1 = c_heap.find(data7); + EXPECT_NE(c_heap.cend(), it1) << + "find by indirection for included element should succeed"; + EXPECT_EQ(-7, it1->data) << + "find by indirection for included element should result in right value"; + + auto fake_data = std::make_shared(-7); + auto it2 = c_heap.find(fake_data); + EXPECT_EQ(c_heap.cend(), it2) << + "find by indirection for not included element should fail"; + } + + { + auto it1 = c_heap.find(Elem(-7)); + EXPECT_NE(c_heap.cend(), it1) << + "find by value for included element should succeed"; + EXPECT_EQ(-7, it1->data) << + "find by value for included element should result in right value"; + + auto it2 = c_heap.find(Elem(7)); + EXPECT_EQ(c_heap.cend(), it2) << + "find by value for not included element should fail"; + } + + { + auto it1 = c_heap.rfind(data7); + EXPECT_NE(c_heap.cend(), it1) << + "reverse find by indirecton for included element should succeed"; + EXPECT_EQ(-7, it1->data) << + "reverse find by indirection for included element should result " + "in right value"; + + auto fake_data = std::make_shared(-7); + auto it2 = c_heap.rfind(fake_data); + EXPECT_EQ(c_heap.cend(), it2) << + "reverse find by indirection for not included element should fail"; + } + + { + auto it1 = c_heap.rfind(Elem(-7)); + EXPECT_NE(c_heap.cend(), it1) << + "reverse find by value for included element should succeed"; + EXPECT_EQ(-7, it1->data) << + "reverse find by value for included element should result " + "in right value"; + + auto it2 = c_heap.rfind(Elem(7)); + EXPECT_EQ(c_heap.cend(), it2) << + "reverse find by value for not included element should fail"; + } +} + + TEST_F(HeapFixture1, iterator_remove) { auto it1 = heap.find(data7); EXPECT_NE(heap.end(), it1) << "find for included element should succeed";