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
10#include "H5Cpp.h"
11
12#include "get_name.hpp"
13#include "strnlen.hpp"
14#include "ReclaimVlsMemory.hpp"
15
21namespace ritsuko {
22
23namespace hdf5 {
24
33template<class DataSetPointer_ = const H5::DataSet*>
35public:
44 Stream1dStringDataset(DataSetPointer_ data_ptr, hsize_t length) :
45 my_data_ptr(std::move(data_ptr)),
46 my_full_length(length),
47 my_block_size([&]{
48 assert(my_data_ptr->getSpace().getSimpleExtentNdims() == 1);
49 hsize_t output;
50 const auto& plist = my_data_ptr->getCreatePlist();
51 if (plist.getLayout() == H5D_CHUNKED) {
52 plist.getChunk(1, &output);
53 } else {
54 // Hard-coding the mock chunk size for contiguous datasets,
55 // not worth complicating the constructor with an extra argument.
56 output = sanisizer::min(length, 10000);
57 }
58 return output;
59 }()),
60 my_mspace(1, &my_block_size),
61 my_fspace(1, &my_full_length),
62 my_dtype(my_data_ptr->getDataType()),
63 my_is_variable(my_dtype.isVariableStr())
64 {
65 assert(my_dtype.getClass() == H5T_STRING);
66 if (my_is_variable) {
67 sanisizer::resize(my_var_buffer, my_block_size);
68 } else {
69 my_fixed_length = my_dtype.getSize();
70 my_fix_buffer.resize(sanisizer::product<I<decltype(my_fix_buffer.size())> >(my_fixed_length, my_block_size));
71 }
72 }
73
74public:
78 hsize_t chunk_size() const {
79 return my_block_size;
80 }
81
92 hsize_t load(std::string* buffer) {
93 my_last_loaded += my_available;
94 my_available = sanisizer::min(my_full_length - my_last_loaded, my_block_size);
95 if (my_available == 0) {
96 return 0;
97 }
98
99 constexpr hsize_t zero = 0;
100 my_mspace.selectHyperslab(H5S_SELECT_SET, &my_available, &zero);
101 my_fspace.selectHyperslab(H5S_SELECT_SET, &my_available, &my_last_loaded);
102
103 if (my_is_variable) {
104 my_data_ptr->read(my_var_buffer.data(), my_dtype, my_mspace, my_fspace);
105 const auto& plist = H5::DSetMemXferPropList::DEFAULT;
106 [[maybe_unused]] ReclaimVlsMemory deletor(&my_dtype, &my_mspace, &plist, my_var_buffer.data());
107 for (hsize_t i = 0; i < my_available; ++i) {
108 if (my_var_buffer[i] == NULL) {
109 throw std::runtime_error("detected a NULL pointer for a variable length string in '" + get_name(*my_data_ptr) + "'");
110 }
111 auto& curstr = buffer[i];
112 curstr.clear();
113 curstr.insert(0, my_var_buffer[i]);
114 }
115
116 } else {
117 my_data_ptr->read(my_fix_buffer.data(), my_dtype, my_mspace, my_fspace);
118 for (I<decltype(my_available)> i = 0; i < my_available; ++i) {
119 auto& curstr = buffer[i];
120 curstr.clear();
121 auto bptr = my_fix_buffer.data() + sanisizer::product_unsafe<std::size_t>(i, my_fixed_length);
122 curstr.insert(curstr.end(), bptr, bptr + strnlen(bptr, my_fixed_length));
123 }
124 }
125
126 return my_available;
127 }
128
136 hsize_t start() const {
137 return my_last_loaded;
138 }
139
140private:
141 DataSetPointer_ my_data_ptr;
142 hsize_t my_full_length, my_block_size;
143 H5::DataSpace my_mspace;
144 H5::DataSpace my_fspace;
145
146 H5::DataType my_dtype;
147 bool my_is_variable;
148 std::vector<char*> my_var_buffer;
149 std::size_t my_fixed_length = 0;
150 std::vector<char> my_fix_buffer;
151
152 hsize_t my_last_loaded = 0;
153 hsize_t my_available = 0;
154
155 static_assert(std::is_base_of<H5::DataSet, I<decltype(*my_data_ptr)> >::value);
156};
157
158}
159
160}
161
162#endif
Reclaim memory allocated to HDF5's variable length strings.
Reclaim memory for HDF5's variable length strings.
Definition ReclaimVlsMemory.hpp:36
Stream a 1-dimensional HDF5 string dataset into memory.
Definition Stream1dStringDataset.hpp:34
hsize_t load(std::string *buffer)
Definition Stream1dStringDataset.hpp:92
hsize_t start() const
Definition Stream1dStringDataset.hpp:136
Stream1dStringDataset(DataSetPointer_ data_ptr, hsize_t length)
Definition Stream1dStringDataset.hpp:44
hsize_t chunk_size() const
Definition Stream1dStringDataset.hpp:78
Get the name of a HDF5 object.
std::string get_name(const Object_ &obj)
Definition get_name.hpp:29
std::size_t strnlen(const char *ptr, std::size_t max)
Definition strnlen.hpp:25
Helper functions for ArtifactDB parsing and validation.
Definition Pointer.hpp:21
Determine the length of a fixed-size string.