Advanced Chunk Processing Library 0.2.0
A comprehensive C++ library for advanced data chunking strategies and processing operations
Loading...
Searching...
No Matches
data_structures.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deque>
4#include <functional>
5#include <memory>
6#include <stdexcept>
7#include <vector>
8
9// Circular Buffer - useful for sliding window operations
10template <typename T>
12private:
13 std::vector<T> buffer_;
14 size_t head_ = 0;
15 size_t tail_ = 0;
16 size_t size_ = 0;
17 size_t capacity_;
18
19public:
21 if (capacity == 0)
22 throw std::invalid_argument("Capacity must be positive");
23 }
24
25 void push(const T& item) {
26 buffer_[tail_] = item;
27 tail_ = (tail_ + 1) % capacity_;
28 if (size_ < capacity_) {
29 ++size_;
30 } else {
31 head_ = (head_ + 1) % capacity_;
32 }
33 }
34
35 T pop() {
36 if (empty())
37 throw std::runtime_error("Buffer is empty");
38 T item = buffer_[head_];
39 head_ = (head_ + 1) % capacity_;
40 --size_;
41 return item;
42 }
43
44 bool empty() const {
45 return size_ == 0;
46 }
47 bool full() const {
48 return size_ == capacity_;
49 }
50 size_t size() const {
51 return size_;
52 }
53 size_t capacity() const {
54 return capacity_;
55 }
56
57 std::vector<T> to_vector() const {
58 std::vector<T> result;
59 result.reserve(size_);
60 size_t current = head_;
61 for (size_t i = 0; i < size_; ++i) {
62 result.push_back(buffer_[current]);
63 current = (current + 1) % capacity_;
64 }
65 return result;
66 }
67};
68
69// Priority Queue with custom comparator - useful for chunk prioritization
70template <typename T, typename Compare = std::less<T>>
72private:
73 std::vector<T> heap_;
74 Compare comp_;
75
76 void heapify_up(size_t index) {
77 while (index > 0) {
78 size_t parent = (index - 1) / 2;
79 if (comp_(heap_[parent], heap_[index])) {
80 std::swap(heap_[parent], heap_[index]);
81 index = parent;
82 } else {
83 break;
84 }
85 }
86 }
87
88 void heapify_down(size_t index) {
89 while (true) {
90 size_t largest = index;
91 size_t left = 2 * index + 1;
92 size_t right = 2 * index + 2;
93
94 if (left < heap_.size() && comp_(heap_[largest], heap_[left])) {
95 largest = left;
96 }
97 if (right < heap_.size() && comp_(heap_[largest], heap_[right])) {
98 largest = right;
99 }
100
101 if (largest == index) {
102 break;
103 }
104
105 std::swap(heap_[index], heap_[largest]);
106 index = largest;
107 }
108 }
109
110public:
111 void push(const T& item) {
112 heap_.push_back(item);
113 heapify_up(heap_.size() - 1);
114 }
115
116 T pop() {
117 if (empty())
118 throw std::runtime_error("Queue is empty");
119 T result = heap_[0];
120 heap_[0] = heap_.back();
121 heap_.pop_back();
122 if (!empty()) {
123 heapify_down(0);
124 }
125 return result;
126 }
127
128 bool empty() const {
129 return heap_.empty();
130 }
131 size_t size() const {
132 return heap_.size();
133 }
134};
135
136// Sliding Window - useful for moving average calculations
137template <typename T>
139private:
140 std::deque<T> window_;
141 size_t max_size_;
142 T sum_ = T();
143
144public:
145 explicit SlidingWindow(size_t size) : max_size_(size) {
146 if (size == 0)
147 throw std::invalid_argument("Window size must be positive");
148 }
149
150 void push(const T& value) {
151 window_.push_back(value);
152 sum_ += value;
153
154 if (window_.size() > max_size_) {
155 sum_ -= window_.front();
156 window_.pop_front();
157 }
158 }
159
160 T average() const {
161 if (window_.empty())
162 throw std::runtime_error("Window is empty");
163 return sum_ / static_cast<T>(window_.size());
164 }
165
166 const std::deque<T>& window() const {
167 return window_;
168 }
169 size_t size() const {
170 return window_.size();
171 }
172 bool empty() const {
173 return window_.empty();
174 }
175 T sum() const {
176 return sum_;
177 }
178};
179
180// Chunk Node for building chunk-based data structures
181template <typename T>
182struct ChunkNode {
183 std::vector<T> data;
184 std::shared_ptr<ChunkNode<T>> next;
185 std::shared_ptr<ChunkNode<T>> prev;
186
187 explicit ChunkNode(const std::vector<T>& chunk_data) : data(chunk_data) {}
188};
189
190// Doubly Linked Chunk List - useful for chunk manipulation
191template <typename T>
193private:
194 std::shared_ptr<ChunkNode<T>> head_;
195 std::shared_ptr<ChunkNode<T>> tail_;
196 size_t size_ = 0;
197
198public:
199 void append_chunk(const std::vector<T>& chunk_data) {
200 auto new_node = std::make_shared<ChunkNode<T>>(chunk_data);
201 if (!head_) {
202 head_ = tail_ = new_node;
203 } else {
204 new_node->prev = tail_;
205 tail_->next = new_node;
206 tail_ = new_node;
207 }
208 ++size_;
209 }
210
211 void prepend_chunk(const std::vector<T>& chunk_data) {
212 auto new_node = std::make_shared<ChunkNode<T>>(chunk_data);
213 if (!head_) {
214 head_ = tail_ = new_node;
215 } else {
216 new_node->next = head_;
217 head_->prev = new_node;
218 head_ = new_node;
219 }
220 ++size_;
221 }
222
223 std::vector<T> flatten() const {
224 std::vector<T> result;
225 auto current = head_;
226 while (current) {
227 result.insert(result.end(), current->data.begin(), current->data.end());
228 current = current->next;
229 }
230 return result;
231 }
232
233 size_t size() const {
234 return size_;
235 }
236 bool empty() const {
237 return size_ == 0;
238 }
239
240 void clear() {
241 head_ = tail_ = nullptr;
242 size_ = 0;
243 }
244};
std::shared_ptr< ChunkNode< T > > tail_
std::vector< T > flatten() const
std::shared_ptr< ChunkNode< T > > head_
size_t size() const
void prepend_chunk(const std::vector< T > &chunk_data)
void append_chunk(const std::vector< T > &chunk_data)
bool empty() const
std::vector< T > to_vector() const
bool full() const
void push(const T &item)
size_t size() const
bool empty() const
std::vector< T > buffer_
size_t capacity() const
CircularBuffer(size_t capacity)
void push(const T &item)
std::vector< T > heap_
void heapify_down(size_t index)
bool empty() const
void heapify_up(size_t index)
size_t size() const
size_t size() const
void push(const T &value)
bool empty() const
const std::deque< T > & window() const
std::deque< T > window_
SlidingWindow(size_t size)
ChunkNode(const std::vector< T > &chunk_data)
std::vector< T > data
std::shared_ptr< ChunkNode< T > > next
std::shared_ptr< ChunkNode< T > > prev