@@ -68,6 +68,7 @@ struct CSparseUnorderedWithDupsFx {
6868 std::string partial_tile_offsets_loading_;
6969
7070 void create_default_array_1d ();
71+ void create_large_domain_array_1d ();
7172 void create_default_array_1d_string (int tile_extent = 2 , int capacity = 2 );
7273 void write_1d_fragment (
7374 int * coords, uint64_t * coords_size, int * data, uint64_t * data_size);
@@ -236,6 +237,27 @@ void CSparseUnorderedWithDupsFx::create_default_array_1d() {
236237 true ); // allows dups.
237238}
238239
240+ void CSparseUnorderedWithDupsFx::create_large_domain_array_1d () {
241+ int domain[] = {1 , 20000 };
242+ int tile_extent = 2 ;
243+ create_array (
244+ ctx_,
245+ array_name_,
246+ TILEDB_SPARSE,
247+ {" d" },
248+ {TILEDB_INT32},
249+ {domain},
250+ {&tile_extent},
251+ {" a" },
252+ {TILEDB_INT32},
253+ {1 },
254+ {tiledb::test::Compressor (TILEDB_FILTER_NONE, -1 )},
255+ TILEDB_ROW_MAJOR,
256+ TILEDB_ROW_MAJOR,
257+ 2 ,
258+ true ); // allows dups.
259+ }
260+
239261void CSparseUnorderedWithDupsFx::create_default_array_1d_string (
240262 int tile_extent, int capacity) {
241263 int domain[] = {1 , 20 };
@@ -914,76 +936,158 @@ TEST_CASE_METHOD(
914936
915937TEST_CASE_METHOD (
916938 CSparseUnorderedWithDupsFx,
917- " Sparse unordered with dups reader: tile offsets forcing multiple "
918- " iterations" ,
939+ " Sparse unordered with dups reader: tile offsets partial loading" ,
919940 " [sparse-unordered-with-dups][tile-offsets][multiple-iterations]" ) {
920- bool set_subarray = GENERATE (true , false );
941+ bool enable_partial_tile_offsets_loading = GENERATE (true , false );
921942
922943 // Create default array.
923944 reset_config ();
924- create_default_array_1d ();
925-
926- // Write two fragments.
927- std::vector<int > coords (100 );
928- std::iota (coords.begin (), coords.end (), 1 );
929- uint64_t coords_size = coords.size () * sizeof (int );
945+ create_large_domain_array_1d ();
946+ bool one_frag = false ;
930947
931- std::vector<int > data (100 );
932- std::iota (data.begin (), data.end (), 1 );
933- uint64_t data_size = data.size () * sizeof (int );
948+ SECTION (" - One fragment" ) {
949+ one_frag = true ;
950+ }
951+ SECTION (" - Multiple fragments" ) {
952+ one_frag = false ;
953+ }
934954
935- write_1d_fragment (coords.data (), &coords_size, data.data (), &data_size);
955+ // Write fragments.
956+ if (one_frag) {
957+ std::vector<int > coords (100 );
958+ std::iota (coords.begin (), coords.end (), 1 );
959+ uint64_t coords_size = coords.size () * sizeof (int );
936960
937- std::vector<int > coords2 (100 );
938- std::iota (coords2 .begin (), coords2 .end (), 101 );
939- uint64_t coords2_size = coords .size () * sizeof (int );
961+ std::vector<int > data (100 );
962+ std::iota (data .begin (), data .end (), 1 );
963+ uint64_t data_size = data .size () * sizeof (int );
940964
941- std::vector<int > data2 (100 );
942- std::iota (data2.begin (), data2.end (), 101 );
943- uint64_t data2_size = data.size () * sizeof (int );
944- write_1d_fragment (coords2.data (), &coords2_size, data2.data (), &data2_size);
965+ write_1d_fragment (coords.data (), &coords_size, data.data (), &data_size);
966+ } else {
967+ std::vector<int > coords (100 );
968+ std::iota (coords.begin (), coords.end (), 1 );
969+ uint64_t coords_size = coords.size () * sizeof (int );
970+
971+ std::vector<int > data (100 );
972+ std::iota (data.begin (), data.end (), 1 );
973+ uint64_t data_size = data.size () * sizeof (int );
974+
975+ write_1d_fragment (coords.data (), &coords_size, data.data (), &data_size);
976+
977+ std::vector<int > coords2 (1000 );
978+ std::iota (coords2.begin (), coords2.end (), 101 );
979+ uint64_t coords2_size = coords2.size () * sizeof (int );
980+
981+ std::vector<int > data2 (1000 );
982+ std::iota (data2.begin (), data2.end (), 101 );
983+ uint64_t data2_size = data2.size () * sizeof (int );
984+ write_1d_fragment (coords2.data (), &coords2_size, data2.data (), &data2_size);
985+
986+ std::vector<int > coords3 (5000 );
987+ std::iota (coords3.begin (), coords3.end (), 1101 );
988+ uint64_t coords3_size = coords3.size () * sizeof (int );
989+
990+ std::vector<int > data3 (5000 );
991+ std::iota (data3.begin (), data3.end (), 1101 );
992+ uint64_t data3_size = data3.size () * sizeof (int );
993+ write_1d_fragment (coords3.data (), &coords3_size, data3.data (), &data3_size);
994+
995+ std::vector<int > coords4 (10000 );
996+ std::iota (coords4.begin (), coords4.end (), 6101 );
997+ uint64_t coords4_size = coords4.size () * sizeof (int );
998+
999+ std::vector<int > data4 (10000 );
1000+ std::iota (data4.begin (), data4.end (), 6101 );
1001+ uint64_t data4_size = data4.size () * sizeof (int );
1002+ write_1d_fragment (coords4.data (), &coords4_size, data4.data (), &data4_size);
1003+ }
9451004
946- total_budget_ = " 1900000 " ;
947- tile_upper_memory_limit_ = " 100000 " ;
948- ratio_array_data_ = set_subarray ? " 0.003 " : " 0.002 " ;
949- partial_tile_offsets_loading_ = " true" ;
1005+ total_budget_ = " 3000000 " ;
1006+ ratio_array_data_ = " 0.002 " ;
1007+ partial_tile_offsets_loading_ =
1008+ enable_partial_tile_offsets_loading ? " true" : " false " ;
9501009 update_config ();
9511010
9521011 tiledb_array_t * array = nullptr ;
9531012 tiledb_query_t * query = nullptr ;
9541013
955- // Try to read.
956- int coords_r[200 ];
957- int data_r[200 ];
1014+ int coords_r[16100 ];
1015+ int data_r[16100 ];
9581016 uint64_t coords_r_size = sizeof (coords_r);
9591017 uint64_t data_r_size = sizeof (data_r);
960- auto rc = read (
961- set_subarray,
962- 0 ,
963- coords_r,
964- &coords_r_size,
965- data_r,
966- &data_r_size,
967- &query,
968- &array);
969- CHECK (rc == TILEDB_OK);
1018+ auto rc = 0 ;
1019+
1020+ // Case 1: Read only one frag. Should be ok for both cases of partial tile
1021+ // loading Case 2: Read multiple fragments with partial tile offset loading.
1022+ // Should be ok
1023+ if (enable_partial_tile_offsets_loading || one_frag) {
1024+ rc = read (
1025+ false ,
1026+ 0 ,
1027+ coords_r,
1028+ &coords_r_size,
1029+ data_r,
1030+ &data_r_size,
1031+ &query,
1032+ &array);
1033+ CHECK (rc == TILEDB_OK);
9701034
971- // Validate the results.
972- for (int i = 0 ; i < 200 ; i++) {
973- CHECK (coords_r[i] == i + 1 );
974- CHECK (data_r[i] == i + 1 );
975- }
1035+ // Validate the results.
1036+ int elements_to_check;
1037+ if (one_frag) {
1038+ elements_to_check = 100 ;
1039+ } else {
1040+ elements_to_check = 16100 ;
1041+ }
9761042
977- // Check the internal loop count against expected value.
978- auto stats =
979- ((SparseUnorderedWithDupsReader<uint8_t >*)query->query_ ->strategy ())
980- ->stats ();
981- REQUIRE (stats != nullptr );
982- auto counters = stats->counters ();
983- REQUIRE (counters != nullptr );
984- auto loop_num =
985- counters->find (" Context.StorageManager.Query.Reader.internal_loop_num" );
986- CHECK (2 == loop_num->second );
1043+ for (int i = 0 ; i < elements_to_check; i++) {
1044+ CHECK (coords_r[i] == i + 1 );
1045+ CHECK (data_r[i] == i + 1 );
1046+ }
1047+
1048+ // Check the internal loop count against expected value.
1049+ auto stats =
1050+ ((SparseUnorderedWithDupsReader<uint8_t >*)query->query_ ->strategy ())
1051+ ->stats ();
1052+ REQUIRE (stats != nullptr );
1053+ auto counters = stats->counters ();
1054+ REQUIRE (counters != nullptr );
1055+ auto loop_num =
1056+ counters->find (" Context.StorageManager.Query.Reader.internal_loop_num" );
1057+
1058+ if (one_frag) {
1059+ CHECK (1 == loop_num->second );
1060+ } else {
1061+ CHECK (9 == loop_num->second );
1062+ }
1063+
1064+ // Try to read multiple frags without partial tile offset reading. Should
1065+ // fail
1066+ } else {
1067+ rc = read (
1068+ false ,
1069+ 0 ,
1070+ coords_r,
1071+ &coords_r_size,
1072+ data_r,
1073+ &data_r_size,
1074+ &query,
1075+ &array);
1076+ CHECK (rc == TILEDB_ERR);
1077+
1078+ tiledb_error_t * error = NULL ;
1079+ rc = tiledb_ctx_get_last_error (ctx_, &error);
1080+ CHECK (rc == TILEDB_OK);
1081+
1082+ const char * msg;
1083+ rc = tiledb_error_message (error, &msg);
1084+ CHECK (rc == TILEDB_OK);
1085+
1086+ std::string error_str (msg);
1087+ CHECK (
1088+ error_str.find (" Cannot load tile offsets, computed size" ) !=
1089+ std::string::npos);
1090+ }
9871091
9881092 // Clean up.
9891093 rc = tiledb_array_close (ctx_, array);
0 commit comments