Skip to content
197 changes: 62 additions & 135 deletions test/src/unit-sparse-global-order-reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ struct FxRun1D {
if (subarray.empty()) {
return true;
} else {
const CoordType coord = fragment.dim_[record];
const CoordType coord = fragment.dimension()[record];
for (const auto& range : subarray) {
if (range.contains(coord)) {
return true;
Expand Down Expand Up @@ -349,7 +349,7 @@ struct FxRun2D {
if (subarray.empty() && !condition.has_value()) {
return true;
} else {
const int r = fragment.d1_[record], c = fragment.d2_[record];
const int r = fragment.d1()[record], c = fragment.d2()[record];
for (const auto& range : subarray) {
if (range.first.has_value() && !range.first->contains(r)) {
continue;
Expand Down Expand Up @@ -723,36 +723,11 @@ void CSparseGlobalOrderFx::write_fragment(
}

CApiArray& array = *existing;
Context cppctx = vfs_test_setup_.ctx();
Array cpparray(cppctx, array, false);

// Create the query.
tiledb_query_t* query;
auto rc = tiledb_query_alloc(context(), array, TILEDB_WRITE, &query);
ASSERTER(rc == TILEDB_OK);
rc = tiledb_query_set_layout(context(), query, TILEDB_UNORDERED);
ASSERTER(rc == TILEDB_OK);

auto field_sizes = templates::query::make_field_sizes<Asserter>(fragment);
templates::query::set_fields<Asserter, Fragment>(
context(),
query,
field_sizes,
fragment,
[](unsigned d) { return "d" + std::to_string(d + 1); },
[](unsigned a) { return "a" + std::to_string(a + 1); });

// Submit query.
rc = tiledb_query_submit(context(), query);
ASSERTER(std::optional<std::string>() == error_if_any(rc));

// check that sizes match what we expect
const uint64_t expect_num_cells = fragment.size();
const uint64_t num_cells =
templates::query::num_cells<Asserter>(fragment, field_sizes);

ASSERTER(num_cells == expect_num_cells);

// Clean up.
tiledb_query_free(&query);
templates::query::write_fragment<Asserter, Fragment>(
fragment, cpparray, TILEDB_UNORDERED);
}

void CSparseGlobalOrderFx::write_1d_fragment_strings(
Expand Down Expand Up @@ -1433,23 +1408,23 @@ void CSparseGlobalOrderFx::instance_fragment_skew(

// Write a fragment F0 with unique coordinates
InstanceType::FragmentType fragment0;
fragment0.dim_.resize(fragment_size);
std::iota(fragment0.dim_.begin(), fragment0.dim_.end(), 1);
fragment0.dimension().resize(fragment_size);
std::iota(fragment0.dimension().begin(), fragment0.dimension().end(), 1);

// Write a fragment F1 with lots of duplicates
// [100,100,100,100,100,101,101,101,101,101,102,102,102,102,102,...]
InstanceType::FragmentType fragment1;
fragment1.dim_.resize(fragment0.dim_.num_cells());
for (size_t i = 0; i < fragment1.dim_.num_cells(); i++) {
fragment1.dim_[i] =
static_cast<int>((i / 10) + (fragment0.dim_.num_cells() / 2));
fragment1.dimension().resize(fragment0.dimension().num_cells());
for (size_t i = 0; i < fragment1.dimension().num_cells(); i++) {
fragment1.dimension()[i] =
static_cast<int>((i / 10) + (fragment0.dimension().num_cells() / 2));
}

// atts are whatever, used just for query condition and correctness check
auto& f0atts = std::get<0>(fragment0.atts_);
f0atts.resize(fragment0.dim_.num_cells());
f0atts.resize(fragment0.dimension().num_cells());
std::iota(f0atts.begin(), f0atts.end(), 0);
for (uint64_t i = 0; i < fragment0.dim_.num_cells(); i++) {
for (uint64_t i = 0; i < fragment0.dimension().num_cells(); i++) {
if ((i * i) % 7 == 0) {
std::get<1>(fragment0.atts_).push_back(std::nullopt);
} else {
Expand All @@ -1462,9 +1437,10 @@ void CSparseGlobalOrderFx::instance_fragment_skew(
}

auto& f1atts = std::get<0>(fragment1.atts_);
f1atts.resize(fragment1.dim_.num_cells());
std::iota(f1atts.begin(), f1atts.end(), int(fragment0.dim_.num_cells()));
for (uint64_t i = 0; i < fragment1.dim_.num_cells(); i++) {
f1atts.resize(fragment1.dimension().num_cells());
std::iota(
f1atts.begin(), f1atts.end(), int(fragment0.dimension().num_cells()));
for (uint64_t i = 0; i < fragment1.dimension().num_cells(); i++) {
if ((i * i) % 11 == 0) {
std::get<1>(fragment1.atts_).push_back(std::nullopt);
} else {
Expand Down Expand Up @@ -1570,25 +1546,25 @@ void CSparseGlobalOrderFx::instance_fragment_interleave(
templates::Fragment1D<int, int> fragment1;

// Write a fragment F0 with tiles [1,3][3,5][5,7][7,9]...
fragment0.dim_.resize(fragment_size);
fragment0.dim_[0] = 1;
for (size_t i = 1; i < fragment0.dim_.num_cells(); i++) {
fragment0.dim_[i] = static_cast<int>(1 + 2 * ((i + 1) / 2));
fragment0.dimension().resize(fragment_size);
fragment0.dimension()[0] = 1;
for (size_t i = 1; i < fragment0.dimension().num_cells(); i++) {
fragment0.dimension()[i] = static_cast<int>(1 + 2 * ((i + 1) / 2));
}

// Write a fragment F1 with tiles [2,4][4,6][6,8][8,10]...
fragment1.dim_.resize(fragment0.dim_.num_cells());
for (size_t i = 0; i < fragment1.dim_.num_cells(); i++) {
fragment1.dim_[i] = fragment0.dim_[i] + 1;
fragment1.dimension().resize(fragment0.dimension().num_cells());
for (size_t i = 0; i < fragment1.dimension().num_cells(); i++) {
fragment1.dimension()[i] = fragment0.dimension()[i] + 1;
}

// atts don't really matter
auto& f0atts = std::get<0>(fragment0.atts_);
f0atts.resize(fragment0.dim_.num_cells());
f0atts.resize(fragment0.dimension().num_cells());
std::iota(f0atts.begin(), f0atts.end(), 0);

auto& f1atts = std::get<0>(fragment1.atts_);
f1atts.resize(fragment1.dim_.num_cells());
f1atts.resize(fragment1.dimension().num_cells());
std::iota(f1atts.begin(), f1atts.end(), int(f0atts.num_cells()));

FxRun1D instance;
Expand Down Expand Up @@ -1694,10 +1670,10 @@ void CSparseGlobalOrderFx::instance_fragment_wide_overlap(

for (size_t f = 0; f < num_fragments; f++) {
templates::Fragment1D<int, int> fragment;
fragment.dim_.resize(fragment_size);
fragment.dimension().resize(fragment_size);
std::iota(
fragment.dim_.begin(),
fragment.dim_.end(),
fragment.dimension().begin(),
fragment.dimension().end(),
instance.array.dimension_.domain.lower_bound + static_cast<int>(f));

auto& atts = std::get<0>(fragment.atts_);
Expand Down Expand Up @@ -1825,10 +1801,10 @@ void CSparseGlobalOrderFx::instance_merge_bound_duplication(

for (size_t f = 0; f < num_fragments; f++) {
templates::Fragment1D<int, int> fragment;
fragment.dim_.resize(fragment_size);
fragment.dimension().resize(fragment_size);
std::iota(
fragment.dim_.begin(),
fragment.dim_.end(),
fragment.dimension().begin(),
fragment.dimension().end(),
static_cast<int>(f * (fragment_size - 1)));

auto& atts = std::get<0>(fragment.atts_);
Expand Down Expand Up @@ -2014,13 +1990,13 @@ void CSparseGlobalOrderFx::instance_out_of_order_mbrs(

for (size_t f = 0; f < num_fragments; f++) {
templates::Fragment2D<int, int, int> fdata;
fdata.d1_.reserve(fragment_size);
fdata.d2_.reserve(fragment_size);
fdata.d1().reserve(fragment_size);
fdata.d2().reserve(fragment_size);
std::get<0>(fdata.atts_).reserve(fragment_size);

for (size_t i = 0; i < fragment_size; i++) {
fdata.d1_.push_back(row(f, i));
fdata.d2_.push_back(col(f, i));
fdata.d1().push_back(row(f, i));
fdata.d2().push_back(col(f, i));
std::get<0>(fdata.atts_)
.push_back(static_cast<int>(f * fragment_size + i));
}
Expand Down Expand Up @@ -2221,34 +2197,34 @@ void CSparseGlobalOrderFx::instance_fragment_skew_2d_merge_bound(
const int tcol = instance.d2.domain.lower_bound +
static_cast<int>(f * instance.d2.extent);
for (int i = 0; i < instance.d1.extent * instance.d2.extent - 2; i++) {
fdata.d1_.push_back(trow + i / instance.d1.extent);
fdata.d2_.push_back(tcol + i % instance.d1.extent);
fdata.d1().push_back(trow + i / instance.d1.extent);
fdata.d2().push_back(tcol + i % instance.d1.extent);
std::get<0>(fdata.atts_).push_back(att++);
}

// then some sparse coords in the next space tile,
// fill the data tile (if the capacity is 4), we'll call it T
fdata.d1_.push_back(trow);
fdata.d2_.push_back(tcol + instance.d2.extent);
fdata.d1().push_back(trow);
fdata.d2().push_back(tcol + instance.d2.extent);
std::get<0>(fdata.atts_).push_back(att++);
fdata.d1_.push_back(trow + instance.d1.extent - 1);
fdata.d2_.push_back(tcol + instance.d2.extent + 2);
fdata.d1().push_back(trow + instance.d1.extent - 1);
fdata.d2().push_back(tcol + instance.d2.extent + 2);
std::get<0>(fdata.atts_).push_back(att++);

// then begin a new data tile "Tnext" which straddles the bounds of that
// space tile. this will have a low MBR.
fdata.d1_.push_back(trow + instance.d1.extent - 1);
fdata.d2_.push_back(tcol + instance.d2.extent + 3);
fdata.d1().push_back(trow + instance.d1.extent - 1);
fdata.d2().push_back(tcol + instance.d2.extent + 3);
std::get<0>(fdata.atts_).push_back(att++);
fdata.d1_.push_back(trow);
fdata.d2_.push_back(tcol + 2 * instance.d2.extent);
fdata.d1().push_back(trow);
fdata.d2().push_back(tcol + 2 * instance.d2.extent);
std::get<0>(fdata.atts_).push_back(att++);

// then add a point P which is less than the lower bound of Tnext's MBR,
// and also between the last two coordinates of T
FxRun2D::FragmentType fpoint;
fpoint.d1_.push_back(trow + instance.d1.extent - 1);
fpoint.d2_.push_back(tcol + instance.d1.extent + 1);
fpoint.d1().push_back(trow + instance.d1.extent - 1);
fpoint.d2().push_back(tcol + instance.d1.extent + 1);
std::get<0>(fpoint.atts_).push_back(att++);

instance.fragments.push_back(fdata);
Expand Down Expand Up @@ -2370,13 +2346,13 @@ void CSparseGlobalOrderFx::instance_fragment_full_copy_1d(
for (size_t f = 0; f < num_fragments; f++) {
FxRunType::FragmentType fragment;

fragment.dim_.resize(fragment_size);
fragment.dimension().resize(fragment_size);
std::iota(
fragment.dim_.begin(),
fragment.dim_.end(),
fragment.dimension().begin(),
fragment.dimension().end(),
dimension.domain.lower_bound);

std::get<0>(fragment.atts_).resize(fragment.dim_.num_cells());
std::get<0>(fragment.atts_).resize(fragment.dimension().num_cells());
std::iota(
std::get<0>(fragment.atts_).begin(),
std::get<0>(fragment.atts_).end(),
Expand Down Expand Up @@ -3324,8 +3300,8 @@ void CSparseGlobalOrderFx::instance_repeatable_read_submillisecond(
for (uint64_t t = 0; t < fragment_same_timestamp_runs.size(); t++) {
for (uint64_t f = 0; f < fragment_same_timestamp_runs[t]; f++) {
FxRun2D::FragmentType fragment;
fragment.d1_ = {1, 2 + static_cast<int>(t)};
fragment.d2_ = {1, 2 + static_cast<int>(f)};
fragment.d1() = {1, 2 + static_cast<int>(t)};
fragment.d2() = {1, 2 + static_cast<int>(f)};
std::get<0>(fragment.atts_) = std::vector<int>{
static_cast<int>(instance.fragments.size()),
static_cast<int>(instance.fragments.size())};
Expand Down Expand Up @@ -3448,64 +3424,15 @@ TEST_CASE_METHOD(
*/
template <typename Asserter, InstanceType Instance>
void CSparseGlobalOrderFx::create_array(const Instance& instance) {
const auto dimensions = instance.dimensions();
const auto attributes = instance.attributes();

std::vector<std::string> dimension_names;
std::vector<tiledb_datatype_t> dimension_types;
std::vector<void*> dimension_ranges;
std::vector<void*> dimension_extents;
auto add_dimension = [&]<Datatype D>(
const templates::Dimension<D>& dimension) {
using CoordType = templates::Dimension<D>::value_type;
dimension_names.push_back("d" + std::to_string(dimension_names.size() + 1));
dimension_types.push_back(static_cast<tiledb_datatype_t>(D));
dimension_ranges.push_back(
const_cast<CoordType*>(&dimension.domain.lower_bound));
dimension_extents.push_back(const_cast<CoordType*>(&dimension.extent));
};
std::apply(
[&]<Datatype... Ds>(const templates::Dimension<Ds>&... dimension) {
(add_dimension(dimension), ...);
},
dimensions);

std::vector<std::string> attribute_names;
std::vector<tiledb_datatype_t> attribute_types;
std::vector<uint32_t> attribute_cell_val_nums;
std::vector<bool> attribute_nullables;
std::vector<std::pair<tiledb_filter_type_t, int>> attribute_compressors;
auto add_attribute = [&](Datatype datatype,
uint32_t cell_val_num,
bool nullable) {
attribute_names.push_back("a" + std::to_string(attribute_names.size() + 1));
attribute_types.push_back(static_cast<tiledb_datatype_t>(datatype));
attribute_cell_val_nums.push_back(cell_val_num);
attribute_nullables.push_back(nullable);
attribute_compressors.push_back(std::make_pair(TILEDB_FILTER_NONE, -1));
};
for (const auto& [datatype, cell_val_num, nullable] : attributes) {
add_attribute(datatype, cell_val_num, nullable);
}

tiledb::test::create_array(
context(),
templates::ddl::create_array(
array_name_,
TILEDB_SPARSE,
dimension_names,
dimension_types,
dimension_ranges,
dimension_extents,
attribute_names,
attribute_types,
attribute_cell_val_nums,
attribute_compressors,
Context(context(), false),
instance.dimensions(),
instance.attributes(),
instance.tile_order(),
instance.cell_order(),
instance.tile_capacity(),
instance.allow_duplicates(),
false,
{attribute_nullables});
instance.allow_duplicates());
}

/**
Expand Down Expand Up @@ -4128,11 +4055,11 @@ void show<FxRun2D>(const FxRun2D& instance, std::ostream& os) {
os << "\t\t{" << std::endl;
os << "\t\t\t\"d1\": [" << std::endl;
os << "\t\t\t\t";
show(fragment.d1_, os);
show(fragment.d1(), os);
os << std::endl;
os << "\t\t\t\"d2\": [" << std::endl;
os << "\t\t\t\t";
show(fragment.d2_, os);
show(fragment.d2(), os);
os << std::endl;
os << "\t\t\t], " << std::endl;
os << "\t\t\t\"atts\": [" << std::endl;
Expand Down
Loading
Loading