diff --git a/test/src/unit-cppapi-array.cc b/test/src/unit-cppapi-array.cc index b97ed9739f13..b1953ae9f168 100644 --- a/test/src/unit-cppapi-array.cc +++ b/test/src/unit-cppapi-array.cc @@ -478,6 +478,42 @@ TEST_CASE( vfs.remove_dir(array_name); } +TEST_CASE( + "C++ API: Consolidation of sequential fragment writes", + "[cppapi], [consolidation-sequential]") { + Context ctx; + VFS vfs(ctx); + const std::string array_name = "cpp_unit_array"; + + if (vfs.is_dir(array_name)) + vfs.remove_dir(array_name); + + Domain domain(ctx); + domain.add_dimension(Dimension::create(ctx, "", {0, 11}, 12)); + + ArraySchema schema(ctx, TILEDB_DENSE); + schema.set_domain(domain).set_order({{TILEDB_ROW_MAJOR, TILEDB_ROW_MAJOR}}); + schema.add_attribute(Attribute::create(ctx, "")); + + tiledb::Array::create(array_name, schema); + auto array_w = tiledb::Array(ctx, array_name, TILEDB_WRITE); + auto query_w = tiledb::Query(ctx, array_w, TILEDB_WRITE); + std::vector data = {0, 1}; + + query_w.set_buffer("", data).set_subarray({0, 1}).submit(); + query_w.set_buffer("", data).set_subarray({2, 3}).submit(); + // this fragment write caused crash during consolidation + // https://github.com/TileDB-Inc/TileDB/issues/1205 + // https://github.com/TileDB-Inc/TileDB/issues/1212 + query_w.set_buffer("", data).set_subarray({3, 4}).submit(); + query_w.finalize(); + array_w.close(); + Array::consolidate(ctx, array_name); + + if (vfs.is_dir(array_name)) + vfs.remove_dir(array_name); +} + TEST_CASE("C++ API: Encrypted array", "[cppapi], [encryption]") { Context ctx; VFS vfs(ctx); diff --git a/tiledb/sm/storage_manager/consolidator.cc b/tiledb/sm/storage_manager/consolidator.cc index 0550b99aee18..673cf22e1ae9 100644 --- a/tiledb/sm/storage_manager/consolidator.cc +++ b/tiledb/sm/storage_manager/consolidator.cc @@ -662,11 +662,12 @@ Status Consolidator::compute_next_to_consolidate( } else if (i + j >= col_num) { // Non-valid entries m_sizes[i][j] = UINT64_MAX; m_union[i][j].clear(); + m_union[i][j].shrink_to_fit(); } else { // Every other row is computed using the previous row auto ratio = (float)fragments[i + j - 1].fragment_size_ / fragments[i + j].fragment_size_; ratio = (ratio <= 1.0f) ? ratio : 1.0f / ratio; - if (ratio >= size_ratio) { + if (ratio >= size_ratio && (m_sizes[i - 1][j] != UINT64_MAX)) { m_sizes[i][j] = m_sizes[i - 1][j] + fragments[i + j].fragment_size_; std::memcpy(&m_union[i][j][0], &m_union[i - 1][j][0], domain_size); utils::geometry::expand_mbr_with_mbr(