From 0bb43975c81308afa4ee9d02a2f9c46fc1eae56c Mon Sep 17 00:00:00 2001 From: LTLA Date: Thu, 26 Sep 2024 08:40:44 -0700 Subject: [PATCH] Check for sortedness of the slabs to populate/reuse before re-sorting. This makes the dense oracular extractor consistent with its sparse counterpart. --- include/tatami_hdf5/DenseMatrix.hpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/include/tatami_hdf5/DenseMatrix.hpp b/include/tatami_hdf5/DenseMatrix.hpp index a779e2e..0654780 100644 --- a/include/tatami_hdf5/DenseMatrix.hpp +++ b/include/tatami_hdf5/DenseMatrix.hpp @@ -308,6 +308,16 @@ class OracularCoreNormal { size_t my_offset = 0; private: + template + static void sort_by_field(std::vector >& indices, Function_ field) { + auto comp = [&field](const std::pair& l, const std::pair& r) -> bool { + return field(l) < field(r); + }; + if (!std::is_sorted(indices.begin(), indices.end(), comp)) { + std::sort(indices.begin(), indices.end(), comp); + } + } + template void fetch_raw([[maybe_unused]] Index_ i, Value_* buffer, size_t non_target_length, Unionize_ unionize) { auto info = my_cache.next( @@ -323,9 +333,7 @@ class OracularCoreNormal { /* populate = */ [&](std::vector >& chunks, std::vector >& to_reuse) { // Defragmenting the existing chunks. We sort by offset to make // sure that we're not clobbering in-use slabs during the copy(). - std::sort(to_reuse.begin(), to_reuse.end(), [](const std::pair& left, const std::pair& right) -> bool { - return left.second->offset < right.second->offset; - }); + sort_by_field(to_reuse, [](const std::pair& x) -> size_t { return x.second->offset; }); auto dest = my_memory_pool.data(); size_t running_offset = 0; @@ -343,7 +351,7 @@ class OracularCoreNormal { // to populate the contiguous memory pool that we made available after // defragmentation; then we just update the slab pointers to refer // to the slices of memory corresponding to each slab. - std::sort(chunks.begin(), chunks.end()); + sort_by_field(chunks, [](const std::pair& x) -> Index_ { return x.first; }); serialize([&]() -> void { auto& components = *my_h5comp;