16 template<
typename array_t>
20 enum perlocation_dir_t {
51 inline void put(
size_t pos,
len_t i) {
65 inline ArrayMaxHeap(array_t& array,
const size_t array_size,
const size_t heap_size)
66 : m_array(&array), m_size(0)
78 DCHECK_EQ(m_pos[i], m_undef) <<
"trying to insert an item that's already in the heap";
80 size_t pos = m_size++;
83 auto lcp_i = (*m_array)[i];
84 while(pos > 0 && lcp_i > (*m_array)[m_heap[parent(pos)]]) {
85 put(pos, m_heap[parent(pos)]);
92 DVLOG(2) <<
"checking heap after insert (size = " << m_size <<
")";
93 check_heap_condition();
98 inline void perlocate_down(
size_t pos,
len_t k) {
99 auto lcp_k = (*m_array)[k];
101 perlocation_dir_t dir = NONE;
103 len_t lcp_lc = (lc(pos) < m_size) ? (*m_array)[m_heap[lc(pos)]] : 0;
104 len_t lcp_rc = (rc(pos) < m_size) ? (*m_array)[m_heap[rc(pos)]] : 0;
107 if(lcp_k < lcp_lc && lcp_k < lcp_rc) {
109 dir = (lcp_lc > lcp_rc) ? LEFT : RIGHT;
110 }
else if(lcp_k < lcp_lc) {
113 }
else if(lcp_k < lcp_rc) {
117 else if(lcp_k == lcp_lc && lcp_k == lcp_rc) {
119 dir = (lc(pos) < rc(pos)) ? LEFT : RIGHT;
120 }
else if(lcp_k == lcp_lc && k > lc(pos)) {
123 }
else if(lcp_k == lcp_rc && k > rc(pos)) {
135 put(pos, m_heap[lc(pos)]);
137 }
else if(dir == RIGHT) {
139 put(pos, m_heap[rc(pos)]);
142 }
while(dir != NONE);
153 size_t pos = m_pos[i];
156 auto k = m_heap[--m_size];
159 perlocate_down(pos, k);
165 DVLOG(2) <<
"checking heap after remove (size = " << m_size <<
")";
166 check_heap_condition();
176 template<typename key_t>
178 (*m_array)[i] = value;
180 size_t pos = m_pos[i];
181 DCHECK_NE(pos, m_undef) <<
"trying to decrease_key on an item that's not in the heap";
185 perlocate_down(pos, i);
189 DVLOG(2) <<
"checking heap after decrease_key (size = " << m_size <<
")";
190 check_heap_condition();
199 return m_pos[i] != m_undef;
216 inline size_t top()
const {
225 return (*m_array)[i];
230 inline void check_heap_condition()
const {
231 for(
size_t i = 0; i < m_size; i++) {
232 auto value = (*m_array)[m_heap[i]];
233 if(lc(i) < m_size) DCHECK(value >= (*m_array)[m_heap[lc(i)]])
234 <<
"heap condition violated for a left child";
235 if(rc(i) < m_size) DCHECK(value >= (*m_array)[m_heap[rc(i)]])
236 <<
"heap condition violated for a right child";
Contains the text compression and encoding framework.
constexpr uint_fast8_t bits_for(size_t n)
Computes the number of bits required to store the given integer value.
A vector over arbitrary unsigned integer types.
bool contains(len_t i) const
Checks whether or not an item is contained in this heap.
size_t top() const
Gets the top (first, maximum) item from the heap.
ArrayMaxHeap(array_t &array, const size_t array_size, const size_t heap_size)
Default constructor.
size_t size() const
Yields the number of items currently stored in the heap.
void insert(len_t i)
Inserts an item into the heap.
len_t key(len_t i) const
Gets an item's key.
fast_t< len_compact_t > len_t
Type to represent an length value.
size_t get_max() const
Gets the first (maximum) item from the heap.
IntVector< dynamic_t > DynamicIntVector
Represents an integer vector with unspecified (dynamic) bit width.
#define IF_PARANOID(x)
x is compiled only in debug builds and when the PARANOID macro is defined.
Represents a binary max heap backed by an external array of keys.
#define IF_DEBUG(x)
x is compiled only in debug builds.
void decrease_key(len_t i, key_t value)
Decreases the key of item in the heap.