diff --git a/src/hdf5_reader.hpp b/src/hdf5_reader.hpp index 6d1b73a4..d3ccfa89 100644 --- a/src/hdf5_reader.hpp +++ b/src/hdf5_reader.hpp @@ -28,12 +28,7 @@ class Hdf5PluginRead1DDefault: virtual public Hdf5PluginRead1DInterface public: std::vector readSelection(const HighFive::DataSet& dset, const Selection& selection) const override { - if (selection.ranges().empty()) { - return {}; - } - - return dset.select(detail::_makeHyperslab(selection.ranges())) - .template read>(); + return detail::readCanonicalSelection(dset, selection); } }; diff --git a/src/read_canonical_selection.hpp b/src/read_canonical_selection.hpp index d9526e44..8d89e3fc 100644 --- a/src/read_canonical_selection.hpp +++ b/src/read_canonical_selection.hpp @@ -9,25 +9,26 @@ namespace bbp { namespace sonata { namespace detail { -template -HighFive::HyperSlab make_hyperslab(const std::vector& ranges) { - HighFive::HyperSlab slab; - for (const auto& range : ranges) { - size_t i_begin = std::get<0>(range); - size_t i_end = std::get<1>(range); - slab |= HighFive::RegularHyperSlab({i_begin}, {i_end - i_begin}); - } - - return slab; -} - template std::vector readCanonicalSelection(const HighFive::DataSet& dset, const Selection& selection) { if (selection.empty()) { return {}; } - return dset.select(make_hyperslab(selection.ranges())).template read>(); + constexpr size_t min_gap_size = SONATA_PAGESIZE / sizeof(T); + constexpr size_t max_aggregated_block_size = 1 * min_gap_size; + + auto readBlock = [&](auto& buffer, const auto& range) { + size_t i_begin = std::get<0>(range); + size_t i_end = std::get<1>(range); + dset.select({i_begin}, {i_end - i_begin}).read(buffer); + }; + + return bulk_read::bulkRead([&readBlock](auto& buffer, + const auto& range) { readBlock(buffer, range); }, + selection.ranges(), + min_gap_size, + max_aggregated_block_size); } template