12 SmartMalloc() :
data(nullptr) {}
13 ~SmartMalloc() { this->freeData(); }
14 operator bool() {
return data !=
nullptr; }
30 throw std::bad_alloc{};
38 throw std::bad_alloc{};
43 void SmartMalloc::freeData() {
72 errMsg =
"Target and source datasets hold different types.";
77 H5::DataSpace targetSpace =
target.getSpace();
78 H5::DataSpace sourceSpace =
source.getSpace();
79 if (!targetSpace.isSimple() || !sourceSpace.isSimple() ) {
80 errMsg =
"Only simple dataspaces are understood.";
85 int nDims = targetSpace.getSimpleExtentNdims();
86 if (nDims != sourceSpace.getSimpleExtentNdims() ) {
87 errMsg =
"Target and source dataspaces have different dimensions, " +
89 std::to_string(sourceSpace.getSimpleExtentNdims() ) +
" respectively";
94 if (nDims <=
static_cast<int>(mergeAxis)) {
96 " is not compatible with the merge axis " +
102 std::vector<hsize_t> targetDims(nDims, 0);
103 std::vector<hsize_t> maxTargetDims(nDims, 0);
104 targetSpace.getSimpleExtentDims(targetDims.data(), maxTargetDims.data() );
105 std::vector<hsize_t> sourceDims(nDims, 0);
106 sourceSpace.getSimpleExtentDims(sourceDims.data() );
108 for (
int ii = 0; ii < nDims; ++ii) {
110 if (ii ==
static_cast<int>(mergeAxis) )
112 if (targetDims.at(ii) != sourceDims.at(ii) ) {
113 errMsg =
"Target and source databases dimensions differ on axis " +
121 if (maxTargetDims.at(mergeAxis) < (
122 targetDims.at(mergeAxis) + sourceDims.at(mergeAxis) ) ) {
123 errMsg =
"Merged dataset will not fit into target dataset";
132 const H5::DataSet&
source,
134 std::size_t bufferSize)
138 throw std::invalid_argument(errMsg);
141 H5::DataSpace targetSpace =
target.getSpace();
142 H5::DataSpace sourceSpace =
source.getSpace();
143 int nDims = targetSpace.getSimpleExtentNdims();
146 std::vector<hsize_t> targetDims(nDims, 0);
147 targetSpace.getSimpleExtentDims(targetDims.data() );
148 std::vector<hsize_t> sourceDims(nDims, 0);
149 sourceSpace.getSimpleExtentDims(sourceDims.data() );
152 std::vector<hsize_t> newDims = targetDims;
153 newDims.at(mergeAxis) += sourceDims.at(mergeAxis);
154 target.extend(newDims.data() );
155 targetSpace.setExtentSimple(newDims.size(), newDims.data() );
161 std::size_t nRowsBuffer = bufferSize / rowSize;
162 if (nRowsBuffer == 0)
163 throw std::invalid_argument(
164 "Allocated buffer is smaller than a single row! Merging is impossible.");
174 std::vector<hsize_t> targetOffset(nDims, 0);
176 targetOffset.at(mergeAxis) = targetDims.at(mergeAxis);
180 std::size_t nSourceRows = sourceDims.at(mergeAxis);
181 for (std::size_t iRow = 0; iRow < nSourceRows; iRow += nRowsBuffer) {
183 std::vector<hsize_t> sourceOffset(nDims, 0);
184 sourceOffset.at(mergeAxis) = iRow;
186 std::size_t nRowsToWrite =
std::min(nSourceRows-iRow, nRowsBuffer);
187 std::vector<hsize_t> sourceSize(sourceDims);
188 sourceSize.at(mergeAxis) = nRowsToWrite;
190 sourceSpace.selectNone();
191 sourceSpace.selectHyperslab(
194 sourceOffset.data() );
197 targetSpace.selectNone();
198 targetSpace.selectHyperslab(
201 targetOffset.data() );
203 H5::DataSpace memorySpace(sourceSize.size(), sourceSize.data() );
204 memorySpace.selectAll();
207 buffer.allocate(nRowsToWrite*rowSize);
213 targetOffset.at(mergeAxis) += nRowsToWrite;
217 if (targetOffset.at(mergeAxis) != newDims.at(mergeAxis) )
218 throw std::logic_error(
219 "Target dataset was not filled! This indicates a logic error in the code!");
223 H5::H5Location& targetLocation,
224 const H5::DataSet&
source,
229 H5::DataSpace sourceSpace =
source.getSpace();
231 std::vector<hsize_t> DSExtent(sourceSpace.getSimpleExtentNdims(), 0);
232 sourceSpace.getSimpleExtentDims(DSExtent.data() );
234 DSExtent.at(mergeAxis) = 0;
235 std::vector<hsize_t> maxDSExtent = DSExtent;
236 maxDSExtent.at(mergeAxis) = mergeExtent;
239 H5::DSetCreatPropList cList =
source.getCreatePlist();
241 std::vector<hsize_t> chunks = DSExtent;
243 cList.setChunk(chunks.size(), chunks.data() );
247 H5::DataSpace space(DSExtent.size(), DSExtent.data(), maxDSExtent.data());
250 return targetLocation.createDataSet(
251 source.getObjName(),
source.getDataType(), space, cList);
256 std::size_t eleSize =
ds.getDataType().getSize();
259 H5::DataSpace space =
ds.getSpace();
260 std::vector<hsize_t> spaceDims(space.getSimpleExtentNdims(), 0);
261 space.getSimpleExtentDims(spaceDims.data() );
263 std::size_t nRowElements = 1;
264 for (std::size_t ii = 0; ii < spaceDims.size(); ++ii)
266 nRowElements *= spaceDims.at(ii);
269 if (std::size_t(-1) / nRowElements < eleSize)
270 throw std::overflow_error(
"The size of one row would overflow the register!");
272 return eleSize * nRowElements;