From 1a9c42640cc904d40b76bd56c6af565c91281271 Mon Sep 17 00:00:00 2001 From: LTLA Date: Mon, 20 May 2024 14:28:32 -0700 Subject: [PATCH] Avoid a divide by zero. --- include/tatami_hdf5/sparse_secondary.hpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/include/tatami_hdf5/sparse_secondary.hpp b/include/tatami_hdf5/sparse_secondary.hpp index 78226c4..20ccd50 100644 --- a/include/tatami_hdf5/sparse_secondary.hpp +++ b/include/tatami_hdf5/sparse_secondary.hpp @@ -23,18 +23,28 @@ class MyopicSecondaryCore { public: MyopicSecondaryCore( const MatrixDetails& details, - bool, // oracle: for consistency with the oracular constructor. + MaybeOracle, // oracle, for consistency with the oracular constructor. Index_ extract_length, bool needs_value, bool needs_index) : my_pointers(details.pointers), my_secondary_dim_stats( details.secondary_dim, - std::max( - static_cast(1), - // The general strategy here is to allocate a single giant slab based on what the 'cache_size' can afford. - static_cast(details.slab_cache_size / (CompressedSparseMatrix_internal::size_of_cached_element(needs_value, needs_index) * extract_length)) - ) + [&]() -> size_t { + // The general strategy here is to allocate a single giant slab based on what the 'cache_size' can afford. + size_t elsize = CompressedSparseMatrix_internal::size_of_cached_element(needs_value, needs_index); + size_t denom = elsize * static_cast(extract_length); + if (denom == 0) { + return details.secondary_dim; // caching the entire secondary dimension, if possible. + } + + size_t primary_chunkdim = details.slab_cache_size / denom; + if (primary_chunkdim < 1) { + return 1; + } + + return std::min(primary_chunkdim, static_cast(details.secondary_dim)); + }() ), my_extract_length(extract_length), my_needs_value(needs_value),