ritsuko
Helper utilities for ArtifactDB C++ code
Loading...
Searching...
No Matches
Stream1dStringDataset.hpp
Go to the documentation of this file.
1#ifndef RITSUKO_HDF5_STREAM_1D_STRING_DATASET_HPP
2#define RITSUKO_HDF5_STREAM_1D_STRING_DATASET_HPP
3
4#include <vector>
5#include <string>
6#include <stdexcept>
7#include <cassert>
8#include <type_traits>
9#include <algorithm>
10
11#include "H5Cpp.h"
13
14#include "ReclaimVlsMemory.hpp"
15#include "../utils.hpp"
16#include "../strnlen.hpp"
17#include "../itoa.hpp"
18
24namespace ritsuko {
25
26namespace hdf5 {
27
38
47template<class DataSetPointer_ = const H5::DataSet*>
49public:
58 Stream1dStringDataset(DataSetPointer_ data_ptr, hsize_t length, const Stream1dStringDatasetOptions& options) :
59 my_data_ptr(std::move(data_ptr)),
60 my_full_length(length),
61 my_block_size([&]{
62 assert(my_data_ptr->getSpace().getSimpleExtentNdims() == 1);
63 hsize_t output;
64 const auto& plist = my_data_ptr->getCreatePlist();
65 if (plist.getLayout() == H5D_CHUNKED) {
66 plist.getChunk(1, &output);
67 } else {
68 output = std::min(length, options.contiguous_chunk_size);
69 }
70 return output;
71 }()),
72 my_mspace(1, &my_block_size),
73 my_fspace(1, &my_full_length),
74 my_dtype(my_data_ptr->getDataType()),
75 my_is_variable(my_dtype.isVariableStr())
76 {
77 assert(my_dtype.getClass() == H5T_STRING);
78 if (my_is_variable) {
79 sanisizer::resize(my_var_buffer, my_block_size);
80 } else {
81 my_fixed_length = my_dtype.getSize();
82 my_fix_buffer.resize(sanisizer::product<I<decltype(my_fix_buffer.size())> >(my_fixed_length, my_block_size));
83 }
84 }
85
86public:
90 hsize_t chunk_size() const {
91 return my_block_size;
92 }
93
104 hsize_t load(std::string* buffer) {
105 my_last_loaded += my_available;
106 my_available = sanisizer::min(my_full_length - my_last_loaded, my_block_size);
107 if (my_available == 0) {
108 return 0;
109 }
110
111 constexpr hsize_t zero = 0;
112 my_mspace.selectHyperslab(H5S_SELECT_SET, &my_available, &zero);
113 my_fspace.selectHyperslab(H5S_SELECT_SET, &my_available, &my_last_loaded);
114
115 if (my_is_variable) {
116 my_data_ptr->read(my_var_buffer.data(), my_dtype, my_mspace, my_fspace);
117 const auto& plist = H5::DSetMemXferPropList::DEFAULT;
118 [[maybe_unused]] ReclaimVlsMemory deletor(&my_dtype, &my_mspace, &plist, my_var_buffer.data());
119 for (hsize_t i = 0; i < my_available; ++i) {
120 if (my_var_buffer[i] == NULL) {
121 throw std::runtime_error("detected a NULL pointer for a variable length string at position " + itoa(start() + i));
122 }
123 auto& curstr = buffer[i];
124 curstr.clear();
125 curstr.insert(0, my_var_buffer[i]);
126 }
127
128 } else {
129 my_data_ptr->read(my_fix_buffer.data(), my_dtype, my_mspace, my_fspace);
130 for (I<decltype(my_available)> i = 0; i < my_available; ++i) {
131 auto& curstr = buffer[i];
132 curstr.clear();
133 auto bptr = my_fix_buffer.data() + sanisizer::product_unsafe<std::size_t>(i, my_fixed_length);
134 curstr.insert(curstr.end(), bptr, bptr + strnlen(bptr, my_fixed_length));
135 }
136 }
137
138 return my_available;
139 }
140
148 hsize_t start() const {
149 return my_last_loaded;
150 }
151
152private:
153 DataSetPointer_ my_data_ptr;
154 hsize_t my_full_length, my_block_size;
155 H5::DataSpace my_mspace;
156 H5::DataSpace my_fspace;
157
158 H5::DataType my_dtype;
159 bool my_is_variable;
160 std::vector<char*> my_var_buffer;
161 std::size_t my_fixed_length = 0;
162 std::vector<char> my_fix_buffer;
163
164 hsize_t my_last_loaded = 0;
165 hsize_t my_available = 0;
166
167 static_assert(std::is_base_of<H5::DataSet, I<decltype(*my_data_ptr)> >::value);
168};
169
170}
171
172}
173
174#endif
Reclaim memory allocated to HDF5's variable length strings.
Reclaim memory for HDF5's variable length strings.
Definition ReclaimVlsMemory.hpp:38
Stream a 1-dimensional HDF5 string dataset into memory.
Definition Stream1dStringDataset.hpp:48
Stream1dStringDataset(DataSetPointer_ data_ptr, hsize_t length, const Stream1dStringDatasetOptions &options)
Definition Stream1dStringDataset.hpp:58
hsize_t load(std::string *buffer)
Definition Stream1dStringDataset.hpp:104
hsize_t start() const
Definition Stream1dStringDataset.hpp:148
hsize_t chunk_size() const
Definition Stream1dStringDataset.hpp:90
Convert an integer to a string.
Helper functions for ArtifactDB parsing and validation.
Definition Pointer.hpp:22
std::size_t strnlen(const char *ptr, std::size_t max)
Definition strnlen.hpp:23
void itoa(Integer_ x, std::string &output)
Definition itoa.hpp:26
void resize(Container_ &container, Value_ x, Args_ &&... args)
constexpr Dest_ product_unsafe(First_ first, Args_... more)
constexpr auto min(First_ first, Second_ second)
constexpr Dest_ cap(Value_ x)
constexpr Dest_ product(First_ first, Args_... more)
Determine the length of a fixed-size string.
Options for Stream1dStringDataset.
Definition Stream1dStringDataset.hpp:31
hsize_t contiguous_chunk_size
Definition Stream1dStringDataset.hpp:36