MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
StandardSorter.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "UniversalSorter.hpp"
4
5/**
6 * @file StandardSorter.hpp
7 * @brief Example concrete implementation of UniversalSorter
8 *
9 * Demonstrates how to implement a concrete sorter that works with the modern
10 * concept-based architecture. This sorter handles standard comparison-based
11 * sorting for various data types.
12 */
13
14namespace MayaFlux::Yantra {
15
16/**
17 * @struct StandardSorterConfig
18 * @brief Initial settings for standard sorting.
19 *
20 * Pass this aggregate with designated initializers to the config constructor.
21 * Named parameters are applied after the typed settings.
22 */
24 /** Sorting algorithm to use. */
25 SortingAlgorithm algorithm { SortingAlgorithm::STANDARD };
26 /** Order of the sorted result. */
27 SortingDirection direction { SortingDirection::ASCENDING };
28 /** How the input is handled during sorting. */
30 /** Level at which values are sorted. */
32 /** Number of elements per chunk for chunked sorting. */
33 size_t chunk_size { 1024 };
34 /** Sort keys and their relative weights. */
35 std::vector<SortKey> keys;
36 /** Additional named parameters applied last. */
37 std::map<std::string, std::any> parameters;
38};
39
40/**
41 * @class StandardSorter
42 * @brief Concrete implementation for standard comparison-based sorting
43 *
44 * This sorter handles most common sorting scenarios using standard algorithms
45 * and comparators. It supports:
46 * - Numeric containers (vector<double>, vector<float>, etc.)
47 * - DataVariant sorting with type dispatch
48 * - Region-based sorting by coordinates/duration
49 * - Eigen matrix/vector sorting
50 * - Complex number sorting by magnitude
51 * - Multi-key sorting with configurable weights
52 */
53template <ComputeData InputType = Kakshya::DataVariant, ComputeData OutputType = InputType>
54class StandardSorter : public UniversalSorter<InputType, OutputType> {
55public:
59
60 /**
61 * @brief Constructor with default configuration
62 */
64 {
65 this->set_direction(SortingDirection::ASCENDING);
68 }
69
70 /**
71 * @brief Construct and configure a standard sorter in one step.
72 * @param config Initial sorting settings.
73 */
74 explicit StandardSorter(const StandardSorterConfig& config)
76 {
78 this->set_direction(config.direction);
79 this->set_strategy(config.strategy);
80 this->set_granularity(config.granularity);
81 this->set_sort_keys(config.keys);
82 this->set_parameter("chunk_size", config.chunk_size);
83
84 for (const auto& [name, value] : config.parameters) {
85 this->set_parameter(name, value);
86 }
87 }
88
89 /**
90 * @brief Get sorting type category
91 */
92 [[nodiscard]] SortingType get_sorting_type() const override
93 {
95 }
96
97 /**
98 * @brief Configure sorting algorithm
99 */
100 void set_algorithm(SortingAlgorithm algorithm) { m_algorithm = algorithm; }
101 [[nodiscard]] SortingAlgorithm get_algorithm() const { return m_algorithm; }
102
103protected:
104 /**
105 * @brief Get sorter name
106 */
107 [[nodiscard]] std::string get_sorter_name() const override
108 {
109 return "StandardSorter";
110 }
111
112 /**
113 * @brief Main sorting implementation with type dispatch
114 */
116 {
117 switch (this->get_strategy()) {
119 return sort_in_place(input);
121 return sort_copy(input);
123 return sort_indices_only(input);
125 return sort_partial(input);
127 return sort_chunked(input);
129 return sort_parallel(input);
130 default:
131 return sort_copy(input);
132 }
133 }
134
135 /**
136 * @brief Input validation
137 */
138 bool validate_sorting_input(const input_type& input) const override
139 {
140 return validate_input_type(input.data);
141 }
142
143 /**
144 * @brief Custom parameter handling
145 */
146 void set_sorting_parameter(const std::string& name, std::any value) override
147 {
148 if (name == "algorithm") {
149 if (auto alg_result = safe_any_cast<SortingAlgorithm>(value)) {
150 m_algorithm = *alg_result.value;
151 return;
152 }
153 if (auto str_result = safe_any_cast<std::string>(value)) {
154 auto algorithm_enum = Reflect::string_to_enum_case_insensitive<SortingAlgorithm>(*str_result.value);
155 if (algorithm_enum) {
156 m_algorithm = *algorithm_enum;
157 return;
158 }
159 }
160 }
161 if (name == "chunk_size") {
162 if (auto size_result = safe_any_cast<size_t>(value)) {
163 m_chunk_size = *size_result.value;
164 return;
165 }
166 }
168 }
169
170 [[nodiscard]] std::any get_sorting_parameter(const std::string& name) const override
171 {
172 if (name == "algorithm") {
173 return m_algorithm;
174 }
175 if (name == "chunk_size") {
176 return m_chunk_size;
177 }
179 }
180
181private:
182 SortingAlgorithm m_algorithm = SortingAlgorithm::STANDARD;
183 size_t m_chunk_size = 1024;
184
185 /**
186 * @brief Copy-based sorting (preserves input)
187 */
189 {
190 try {
191 std::vector<std::vector<double>> working_buffer;
192 auto [working_spans, structure_info] = OperationHelper::setup_operation_buffer(
193 const_cast<input_type&>(input), working_buffer);
194
195 Kinesis::Discrete::sort_channels(working_spans, this->get_direction(), m_algorithm);
196
197 output_type result = this->convert_result(working_buffer, structure_info);
198 result.metadata = input.metadata;
199 result.container = input.container;
200 result.metadata["sort_type"] = "copy";
201
202 return result;
203
204 } catch (const std::exception& e) {
205 output_type error_result;
206 error_result.metadata = input.metadata;
207 error_result.container = input.container;
208 error_result.metadata["error"] = std::string("Sorting failed: ") + e.what();
209 return error_result;
210 }
211 }
212
213 /**
214 * @brief In-place sorting (modifies input)
215 */
217 {
218 if constexpr (std::same_as<InputType, OutputType>) {
219 auto result = input;
220 sort_data_in_place(result);
221 return result;
222 } else {
223 return sort_copy(input);
224 }
225 }
226
227 /**
228 * @brief Generate sort indices only
229 */
231 {
232 if constexpr (std::same_as<OutputType, std::vector<size_t>>) {
233 auto result = output_type {};
234 result.data = generate_compute_data_indices(input, this->get_direction());
235 result.metadata = input.metadata;
236 result.metadata["sort_type"] = "indices_only";
237 return result;
238 } else {
239 // If output type is not vector<size_t>, fall back to copy sort
240 return sort_copy(input);
241 }
242 }
243
244 /**
245 * @brief Partial sorting (top-K elements)
246 */
248 {
249 auto result = input;
250 if constexpr (std::same_as<InputType, OutputType>) {
251 result.data = sort_data_partial(input);
252 return result;
253 } else {
254 return convert_and_sort(input);
255 }
256 }
257
258 /**
259 * @brief Parallel sorting
260 */
262 {
263 auto old_algorithm = m_algorithm;
264 m_algorithm = SortingAlgorithm::PARALLEL;
265 auto result = sort_copy(input);
266 m_algorithm = old_algorithm;
267 result.metadata["sort_type"] = "parallel";
268 return result;
269 }
270
271 // ===== Type-specific sorting implementations =====
272
273 /**
274 * @brief Sort data with copy semantics
275 */
276 InputType sort_data_copy(const input_type& data)
277 {
278 return sort_compute_data_extract(data, this->get_direction(), m_algorithm);
279 }
280
281 /**
282 * @brief Sort data in-place
283 */
285 {
286 sort_compute_data_inplace(data, this->get_direction(), m_algorithm);
287 }
288
289 /**
290 * @brief Partial sorting implementation
291 */
292 InputType sort_data_partial(const input_type& data)
293 {
294 auto old_algorithm = m_algorithm;
295 m_algorithm = SortingAlgorithm::PARTIAL;
296 auto result = sort_compute_data_extract(data, this->get_direction(), m_algorithm);
297 m_algorithm = old_algorithm;
298 return result;
299 }
300
301 std::vector<InputType> extract_chunked_data(std::vector<std::span<double>> channels, DataStructureInfo info)
302 {
303 std::vector<InputType> chunks;
304
305 for (size_t start = 0; start < channels[0].size(); start += m_chunk_size) {
306 std::vector<std::vector<double>> chunk_data;
307 chunk_data.resize(channels.size());
308
309 for (size_t ch = 0; ch < channels.size(); ++ch) {
310 size_t end = std::min(start + m_chunk_size, channels[ch].size());
311 auto chunk_span = channels[ch].subspan(start, end - start);
312
313 chunk_data[ch].assign(chunk_span.begin(), chunk_span.end());
314 Kinesis::Discrete::sort_span(std::span<double>(chunk_data[ch]), this->get_direction(), m_algorithm);
315 }
316
317 chunks.push_back(OperationHelper::reconstruct_from_double<InputType>(chunk_data, info));
318 }
319
320 return chunks;
321 }
322
323 /**
324 * @brief Chunked sorting implementation
325 */
327 {
328 try {
329 auto [data_span, structure_info] = OperationHelper::extract_structured_double(
330 const_cast<input_type&>(data));
331 return merge_chunks_to_result(extract_chunked_data(data_span, structure_info), data, structure_info);
332
333 } catch (...) {
334 return { sort_data_copy(data) };
335 }
336 }
337
338 /**
339 * @brief Merge chunks back to single result
340 */
341 output_type merge_chunks_to_result(const std::vector<InputType>& chunks, const input_type& original_input, DataStructureInfo info)
342 {
343 output_type result {};
344 result.metadata = original_input.metadata;
345 result.metadata["sort_type"] = "chunked_merged";
346
347 if constexpr (std::same_as<InputType, OutputType>) {
348 if (chunks.empty()) {
349 return result;
350 }
351
352 try {
353 std::vector<std::vector<double>> merged_channels;
354
355 for (const auto& chunk : chunks) {
356 auto chunk_channels = OperationHelper::extract_numeric_data(chunk);
357
358 if (merged_channels.empty()) {
359 merged_channels.resize(chunk_channels.size());
360 }
361
362 for (size_t ch = 0; ch < chunk_channels.size() && ch < merged_channels.size(); ++ch) {
363 merged_channels[ch].insert(merged_channels[ch].end(),
364 chunk_channels[ch].begin(), chunk_channels[ch].end());
365 }
366 }
367
368 result = this->convert_result(merged_channels, info);
369 result.metadata = original_input.metadata;
370 result.metadata["sort_type"] = "chunked_merged";
371
372 } catch (...) {
373 result.data = chunks[0];
374 }
375 }
376
377 return result;
378 }
379
380 /**
381 * @brief Handle type conversion scenarios
382 */
384 {
385 std::vector<std::vector<double>> working_buffer;
386 auto [working_spans, structure_info] = OperationHelper::setup_operation_buffer(
387 const_cast<input_type&>(input), working_buffer);
388
389 Kinesis::Discrete::sort_channels(working_spans, this->get_direction(), SortingAlgorithm::PARTIAL);
390 return this->convert_result(working_buffer, structure_info);
391 }
392
393 /**
394 * @brief Validate input type for sorting
395 */
396 bool validate_input_type(const input_type& data) const
397 {
398 if constexpr (RequiresContainer<InputType>) {
399 return data.has_container();
400 }
401 return true;
402 }
403};
404
405// ===== Convenience Specializations =====
406
407/// Standard sorter for DataVariant
409
410/// Standard sorter for numeric vectors (DataVariant contains these)
411template <typename T>
413
414/// Standard sorter for region groups (proper way to handle multiple regions)
416
417/// Standard sorter for region segments
419
420/// Standard sorter for Eigen matrices
422
423/// Standard sorter for Eigen vectors
425
426/// Standard sorter that generates indices
427template <ComputeData InputType = std::vector<Kakshya::DataVariant>>
429
430} // namespace MayaFlux::Yantra
Core::GlobalInputConfig input
Definition Config.cpp:42
bool size
Modern, digital-first universal sorting framework for Maya Flux.
glm::vec3 value
std::string name
Definition VKDevice.cpp:123
uint32_t channels
output_type convert_result(std::vector< std::vector< double > > &result_data, DataStructureInfo &metadata)
Convert processed double data back to OutputType using metadata and optional callback.
static auto setup_operation_buffer(T &input, std::vector< std::vector< double > > &working_buffer)
Setup operation buffer from Datum or ComputeData type.
static std::span< double > extract_numeric_data(const T &compute_data)
extract numeric data from single-variant types
static std::tuple< std::vector< std::span< double > >, DataStructureInfo > extract_structured_double(T &compute_data)
Extract structured double data from Datum container or direct ComputeData with automatic container ha...
void set_algorithm(SortingAlgorithm algorithm)
Configure sorting algorithm.
output_type sort_parallel(const input_type &input)
Parallel sorting.
output_type sort_indices_only(const input_type &input)
Generate sort indices only.
InputType sort_data_partial(const input_type &data)
Partial sorting implementation.
output_type sort_chunked(const input_type &data)
Chunked sorting implementation.
output_type sort_partial(const input_type &input)
Partial sorting (top-K elements)
StandardSorter()
Constructor with default configuration.
InputType sort_data_copy(const input_type &data)
Sort data with copy semantics.
output_type sort_implementation(const input_type &input) override
Main sorting implementation with type dispatch.
output_type sort_in_place(const input_type &input)
In-place sorting (modifies input)
typename base_type::input_type input_type
void set_sorting_parameter(const std::string &name, std::any value) override
Custom parameter handling.
std::any get_sorting_parameter(const std::string &name) const override
StandardSorter(const StandardSorterConfig &config)
Construct and configure a standard sorter in one step.
bool validate_sorting_input(const input_type &input) const override
Input validation.
output_type sort_copy(const input_type &input)
Copy-based sorting (preserves input)
SortingAlgorithm get_algorithm() const
bool validate_input_type(const input_type &data) const
Validate input type for sorting.
std::string get_sorter_name() const override
Get sorter name.
SortingType get_sorting_type() const override
Get sorting type category.
output_type merge_chunks_to_result(const std::vector< InputType > &chunks, const input_type &original_input, DataStructureInfo info)
Merge chunks back to single result.
void sort_data_in_place(input_type &data)
Sort data in-place.
output_type convert_and_sort(const input_type &input)
Handle type conversion scenarios.
std::vector< InputType > extract_chunked_data(std::vector< std::span< double > > channels, DataStructureInfo info)
typename base_type::output_type output_type
Concrete implementation for standard comparison-based sorting.
void set_sort_keys(const std::vector< SortKey > &keys)
Add multi-key sorting capability.
virtual std::any get_sorting_parameter(const std::string &name) const
SortingStrategy get_strategy() const
virtual void set_sorting_parameter(const std::string &name, std::any value)
Sorting-specific parameter handling (override for custom parameters)
void set_strategy(SortingStrategy strategy)
Configure sorting strategy.
void set_granularity(SortingGranularity granularity)
Configure output granularity.
void set_parameter(const std::string &name, std::any value) override
Type-safe parameter management with sorting-specific defaults.
void set_direction(SortingDirection direction)
Configure sorting direction.
SortingDirection get_direction() const
Template-flexible sorter base with instance-defined I/O types.
Types that need an associated SignalSourceContainer to extract data.
Definition DataSpec.hpp:110
void sort_span(std::span< double > data, SortingDirection direction, SortingAlgorithm algorithm)
Sort a single span in-place.
Definition Sort.cpp:5
void sort_channels(std::vector< std::span< double > > &channels, SortingDirection direction, SortingAlgorithm algorithm)
Sort all channels in-place.
Definition Sort.cpp:19
SortingAlgorithm
Available sorting algorithm backends.
Definition Sort.hpp:41
SortingDirection
Ascending or descending sort order.
Definition Sort.hpp:30
std::vector< std::vector< size_t > > generate_compute_data_indices(const Datum< T > &data, SortingDirection direction)
Generate sort indices for any ComputeData type.
SortingStrategy
Sorting execution strategies.
@ PARTIAL_SORT
Sort only top-K elements.
@ IN_PLACE
Sort data in-place (modifies input)
@ COPY_SORT
Create sorted copy (preserves input)
@ CHUNKED_SORT
Sort in chunks for large datasets.
@ PARALLEL_SORT
Parallel/concurrent sorting.
@ INDEX_ONLY
Generate sort indices only.
SortingType
Categories of sorting operations for discovery and organization.
@ STANDARD
Traditional comparison-based sorting.
void sort_compute_data_inplace(Datum< T > &data, SortingDirection direction, SortingAlgorithm algorithm)
Universal sort function - handles extraction/conversion internally.
T sort_compute_data_extract(const T &data, SortingDirection direction, SortingAlgorithm algorithm)
Universal sort function - returns sorted copy.
SortingGranularity
Output granularity control for sorting results.
Dimensions, modality, source type, and optional Composite field schema.
std::vector< SortKey > keys
Sort keys and their relative weights.
SortingStrategy strategy
How the input is handled during sorting.
std::map< std::string, std::any > parameters
Additional named parameters applied last.
SortingGranularity granularity
Level at which values are sorted.
SortingAlgorithm algorithm
Sorting algorithm to use.
SortingDirection direction
Order of the sorted result.
size_t chunk_size
Number of elements per chunk for chunked sorting.
Initial settings for standard sorting.