#ifndef COMPACT_HEAP_INL_H_ #error "Direct inclusion of this file is not allowed, include compact_heap.h" // For the sake of sane code completion. #include "compact_heap.h" #endif #include #include namespace NYT { //////////////////////////////////////////////////////////////////////////////// template TCompactHeap::TCompactHeap(C comparator) noexcept : Comparator_(TReverseComparator(std::move(comparator))) { } template void TCompactHeap::push(T value) { bool wasInline = IsInline(); Heap_.push_back(std::move(value)); if (Y_UNLIKELY(!IsInline())) { if (wasInline) { std::make_heap(Heap_.begin(), Heap_.end(), Comparator_); } else { std::push_heap(Heap_.begin(), Heap_.end(), Comparator_); } } } template void TCompactHeap::pop() { YT_ASSERT(!empty()); if (Y_LIKELY(IsInline())) { auto minIt = std::max_element(Heap_.begin(), Heap_.end(), Comparator_); std::swap(*minIt, Heap_.back()); Heap_.pop_back(); } else { std::pop_heap(Heap_.begin(), Heap_.end(), Comparator_); Heap_.pop_back(); } } template auto TCompactHeap::get_min() const -> const_reference { YT_ASSERT(!empty()); if (Y_LIKELY(IsInline())) { return *std::max_element(Heap_.begin(), Heap_.end(), Comparator_); } else { return Heap_.front(); } } template auto TCompactHeap::extract_min() -> value_type { YT_ASSERT(!empty()); if (Y_LIKELY(IsInline())) { auto minIt = std::max_element(Heap_.begin(), Heap_.end(), Comparator_); std::swap(*minIt, Heap_.back()); auto value = Heap_.back(); Heap_.pop_back(); return value; } else { std::pop_heap(Heap_.begin(), Heap_.end(), Comparator_); auto value = std::move(Heap_.back()); Heap_.pop_back(); return value; } } template auto TCompactHeap::begin() const -> const_iterator { return Heap_.begin(); } template auto TCompactHeap::end() const -> const_iterator { return Heap_.end(); } template void TCompactHeap::swap(TCompactHeap& other) { Heap_.swap(other.Heap_); std::swap(Comparator_, other.Comparator_); } template size_t TCompactHeap::size() const { return Heap_.size(); } template size_t TCompactHeap::capacity() const { return Heap_.capacity(); } template size_t TCompactHeap::max_size() const { return Heap_.max_size(); } template bool TCompactHeap::empty() const { return Heap_.empty(); } template void TCompactHeap::shrink_to_small() { Heap_.shrink_to_small(); } template bool TCompactHeap::IsInline() const { return Heap_.capacity() == N; } //////////////////////////////////////////////////////////////////////////////// template TCompactHeap::TReverseComparator::TReverseComparator(C underlying) : Underlying_(std::move(underlying)) { } template bool TCompactHeap::TReverseComparator::operator()(const T& lhs, const T& rhs) const { return Underlying_(rhs, lhs); } //////////////////////////////////////////////////////////////////////////////// } // namespace NYT