- Add arena allocator for zero-allocation hot paths - Add thread pool for parallel operations - Add mmap utilities for memory-mapped I/O - Implement queue_index with heap-based priority queue - Implement dataset_hash with SIMD support (SHA-NI, ARMv8) - Add runtime SIMD detection for cross-platform correctness - Add comprehensive tests and benchmarks
92 lines
2.5 KiB
C++
92 lines
2.5 KiB
C++
#include "binary_heap.h"
|
|
#include "../index/priority_queue.h"
|
|
#include <algorithm>
|
|
|
|
template<typename T, typename Comparator>
|
|
void BinaryHeap<T, Comparator>::sift_up(size_t idx) {
|
|
while (idx > 0) {
|
|
size_t parent = (idx - 1) / 2;
|
|
if (comp_(heap_[idx], heap_[parent], items_)) {
|
|
std::swap(heap_[idx], heap_[parent]);
|
|
idx = parent;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename T, typename Comparator>
|
|
void BinaryHeap<T, Comparator>::sift_down(size_t idx) {
|
|
const size_t n = heap_.size();
|
|
while (true) {
|
|
size_t smallest = idx;
|
|
size_t left = 2 * idx + 1;
|
|
size_t right = 2 * idx + 2;
|
|
|
|
if (left < n && comp_(heap_[left], heap_[smallest], items_)) {
|
|
smallest = left;
|
|
}
|
|
if (right < n && comp_(heap_[right], heap_[smallest], items_)) {
|
|
smallest = right;
|
|
}
|
|
|
|
if (smallest != idx) {
|
|
std::swap(heap_[idx], heap_[smallest]);
|
|
idx = smallest;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename T, typename Comparator>
|
|
BinaryHeap<T, Comparator>::BinaryHeap(const std::vector<T>& items, Comparator comp)
|
|
: items_(items), comp_(comp) {}
|
|
|
|
template<typename T, typename Comparator>
|
|
void BinaryHeap<T, Comparator>::build(const std::vector<size_t>& indices) {
|
|
heap_ = indices;
|
|
|
|
// Heapify from bottom up
|
|
for (int i = static_cast<int>(heap_.size()) / 2 - 1; i >= 0; --i) {
|
|
sift_down(static_cast<size_t>(i));
|
|
}
|
|
}
|
|
|
|
template<typename T, typename Comparator>
|
|
size_t BinaryHeap<T, Comparator>::pop() {
|
|
if (heap_.empty()) {
|
|
return SIZE_MAX;
|
|
}
|
|
|
|
size_t result = heap_[0];
|
|
heap_[0] = heap_.back();
|
|
heap_.pop_back();
|
|
|
|
if (!heap_.empty()) {
|
|
sift_down(0);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
template<typename T, typename Comparator>
|
|
std::vector<size_t> BinaryHeap<T, Comparator>::sorted() const {
|
|
std::vector<size_t> result = heap_;
|
|
std::vector<size_t> sorted_result;
|
|
sorted_result.reserve(result.size());
|
|
|
|
// Create a copy to use for sifting
|
|
std::vector<T> items_copy(items_);
|
|
BinaryHeap<T, Comparator> temp_heap(items_copy, comp_);
|
|
temp_heap.build(result);
|
|
|
|
while (!temp_heap.empty()) {
|
|
sorted_result.push_back(temp_heap.pop());
|
|
}
|
|
|
|
return sorted_result;
|
|
}
|
|
|
|
// Explicit instantiation for IndexEntry type used in priority queue
|
|
template class BinaryHeap<IndexEntry, EntryComparator>;
|