compact_heap-inl.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #ifndef COMPACT_HEAP_INL_H_
  2. #error "Direct inclusion of this file is not allowed, include compact_heap.h"
  3. // For the sake of sane code completion.
  4. #include "compact_heap.h"
  5. #endif
  6. #include <library/cpp/yt/assert/assert.h>
  7. #include <algorithm>
  8. namespace NYT {
  9. ////////////////////////////////////////////////////////////////////////////////
  10. template <class T, size_t N, class C>
  11. TCompactHeap<T, N, C>::TCompactHeap(C comparator) noexcept
  12. : Comparator_(TReverseComparator(std::move(comparator)))
  13. { }
  14. template <class T, size_t N, class C>
  15. void TCompactHeap<T, N, C>::push(T value)
  16. {
  17. bool wasInline = IsInline();
  18. Heap_.push_back(std::move(value));
  19. if (Y_UNLIKELY(!IsInline())) {
  20. if (wasInline) {
  21. std::make_heap(Heap_.begin(), Heap_.end(), Comparator_);
  22. } else {
  23. std::push_heap(Heap_.begin(), Heap_.end(), Comparator_);
  24. }
  25. }
  26. }
  27. template <class T, size_t N, class C>
  28. void TCompactHeap<T, N, C>::pop()
  29. {
  30. YT_ASSERT(!empty());
  31. if (Y_LIKELY(IsInline())) {
  32. auto minIt = std::max_element(Heap_.begin(), Heap_.end(), Comparator_);
  33. std::swap(*minIt, Heap_.back());
  34. Heap_.pop_back();
  35. } else {
  36. std::pop_heap(Heap_.begin(), Heap_.end(), Comparator_);
  37. Heap_.pop_back();
  38. }
  39. }
  40. template <class T, size_t N, class C>
  41. auto TCompactHeap<T, N, C>::get_min() const -> const_reference
  42. {
  43. YT_ASSERT(!empty());
  44. if (Y_LIKELY(IsInline())) {
  45. return *std::max_element(Heap_.begin(), Heap_.end(), Comparator_);
  46. } else {
  47. return Heap_.front();
  48. }
  49. }
  50. template <class T, size_t N, class C>
  51. auto TCompactHeap<T, N, C>::extract_min() -> value_type
  52. {
  53. YT_ASSERT(!empty());
  54. if (Y_LIKELY(IsInline())) {
  55. auto minIt = std::max_element(Heap_.begin(), Heap_.end(), Comparator_);
  56. std::swap(*minIt, Heap_.back());
  57. auto value = Heap_.back();
  58. Heap_.pop_back();
  59. return value;
  60. } else {
  61. std::pop_heap(Heap_.begin(), Heap_.end(), Comparator_);
  62. auto value = std::move(Heap_.back());
  63. Heap_.pop_back();
  64. return value;
  65. }
  66. }
  67. template <class T, size_t N, class C>
  68. auto TCompactHeap<T, N, C>::begin() const -> const_iterator
  69. {
  70. return Heap_.begin();
  71. }
  72. template <class T, size_t N, class C>
  73. auto TCompactHeap<T, N, C>::end() const -> const_iterator
  74. {
  75. return Heap_.end();
  76. }
  77. template <class T, size_t N, class C>
  78. void TCompactHeap<T, N, C>::swap(TCompactHeap<T, N, C>& other)
  79. {
  80. Heap_.swap(other.Heap_);
  81. std::swap(Comparator_, other.Comparator_);
  82. }
  83. template <class T, size_t N, class C>
  84. size_t TCompactHeap<T, N, C>::size() const
  85. {
  86. return Heap_.size();
  87. }
  88. template <class T, size_t N, class C>
  89. size_t TCompactHeap<T, N, C>::capacity() const
  90. {
  91. return Heap_.capacity();
  92. }
  93. template <class T, size_t N, class C>
  94. size_t TCompactHeap<T, N, C>::max_size() const
  95. {
  96. return Heap_.max_size();
  97. }
  98. template <class T, size_t N, class C>
  99. bool TCompactHeap<T, N, C>::empty() const
  100. {
  101. return Heap_.empty();
  102. }
  103. template <class T, size_t N, class C>
  104. void TCompactHeap<T, N, C>::shrink_to_small()
  105. {
  106. Heap_.shrink_to_small();
  107. }
  108. template <class T, size_t N, class C>
  109. bool TCompactHeap<T, N, C>::IsInline() const
  110. {
  111. return Heap_.capacity() == N;
  112. }
  113. ////////////////////////////////////////////////////////////////////////////////
  114. template <class T, size_t N, class C>
  115. TCompactHeap<T, N, C>::TReverseComparator::TReverseComparator(C underlying)
  116. : Underlying_(std::move(underlying))
  117. { }
  118. template <class T, size_t N, class C>
  119. bool TCompactHeap<T, N, C>::TReverseComparator::operator()(const T& lhs, const T& rhs) const
  120. {
  121. return Underlying_(rhs, lhs);
  122. }
  123. ////////////////////////////////////////////////////////////////////////////////
  124. } // namespace NYT