ritsuko
Helper utilities for ArtifactDB C++ code
Loading...
Searching...
No Matches
IterateChunks.hpp
Go to the documentation of this file.
1#ifndef RITSUKO_HDF5_ITERATE_CHUNKS_HPP
2#define RITSUKO_HDF5_ITERATE_CHUNKS_HPP
3
4#include "H5Cpp.h"
5
6#include <vector>
7#include <algorithm>
8#include <cmath>
9
10#include "../utils.hpp"
11#include "../itoa.hpp"
12
18namespace ritsuko {
19
20namespace hdf5 {
21
36 IterateChunks(std::vector<hsize_t> data_dimensions, std::vector<hsize_t> chunk_dimensions) :
37 my_data_extent(std::move(data_dimensions)),
38 my_chunk_extent(std::move(chunk_dimensions)),
39 my_starts(my_data_extent.size()), // no need to sanisizer::cast as the types are the same.
40 my_counts(my_data_extent.size())
41 {
42 const auto ndims = my_data_extent.size();
43 assert(ndims == my_chunk_extent.size());
44
45 I<decltype(ndims)> num_empty = 0;
46 for (I<decltype(ndims)> d = 0; d < ndims; ++d) {
47 my_chunk_extent[d] = std::min(my_data_extent[d], my_chunk_extent[d]);
48 my_counts[d] = my_chunk_extent[d];
49 num_empty += (my_chunk_extent[d] == 0);
50 }
51
52 if (ndims == 0 || num_empty) {
53 my_finished = true;
54 } else {
55 // Ensure that the first advance() call has no effect.
56 my_counts.back() = 0;
57 }
58 }
59
67 bool advance() {
68 if (my_finished) {
69 return false;
70 }
71
72 // Prioritizing the last dimension as this is the fastest-changing.
73 const auto ndims = my_data_extent.size();
74 for (auto i = ndims; i > 0; --i) {
75 const auto d = i - 1;
76 my_starts[d] += my_counts[d];
77 if (my_starts[d] < my_data_extent[d]) {
78 my_counts[d] = std::min(my_data_extent[d] - my_starts[d], my_chunk_extent[d]);
79 return true;
80 }
81
82 my_starts[d] = 0;
83 my_counts[d] = my_chunk_extent[d];
84 }
85
86 my_finished = true;
87 return false;
88 }
89
90public:
96 const std::vector<hsize_t>& starts () const {
97 return my_starts;
98 }
99
107 const std::vector<hsize_t>& counts () const {
108 return my_counts;
109 }
110
114 const std::vector<hsize_t>& data_dimensions() const {
115 return my_data_extent;
116 }
117
123 const std::vector<hsize_t>& chunk_dimensions() const {
124 return my_chunk_extent;
125 }
126
127private:
128 std::vector<hsize_t> my_data_extent, my_chunk_extent;
129 std::vector<hsize_t> my_starts, my_counts;
130 bool my_finished = false;
131};
132
136inline std::string emit_coordinates_as_string(hsize_t position, hsize_t chunk_size, const std::vector<hsize_t>& starts, const std::vector<hsize_t>& counts) {
137 std::string msg;
138 const auto ndim = starts.size();
139 for (I<decltype(ndim)> d = 0; d < ndim; ++d) {
140 if (d != 0) {
141 msg += ", ";
142 }
143 chunk_size /= counts[d];
144 msg += itoa(starts[d] + position / chunk_size);
145 position %= chunk_size;
146 }
147 return "(" + msg + ")";
148}
153}
154
155}
156
157#endif
Convert an integer to a string.
Helper functions for ArtifactDB parsing and validation.
Definition Pointer.hpp:22
void itoa(Integer_ x, std::string &output)
Definition itoa.hpp:26
Iterate through an high-dimensional dataspace by chunk.
Definition IterateChunks.hpp:29
const std::vector< hsize_t > & chunk_dimensions() const
Definition IterateChunks.hpp:123
const std::vector< hsize_t > & data_dimensions() const
Definition IterateChunks.hpp:114
bool advance()
Definition IterateChunks.hpp:67
const std::vector< hsize_t > & starts() const
Definition IterateChunks.hpp:96
const std::vector< hsize_t > & counts() const
Definition IterateChunks.hpp:107
IterateChunks(std::vector< hsize_t > data_dimensions, std::vector< hsize_t > chunk_dimensions)
Definition IterateChunks.hpp:36