1 /**
2 * @file unit-capi-sparse_real.cc
3 *
4 * @section LICENSE
5 *
6 * The MIT License
7 *
8 * @copyright Copyright (c) 2017-2021 TileDB Inc.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * THE SOFTWARE.
27 *
28 * @section DESCRIPTION
29 *
30 * Tests of C API for sparse arrays with real domains.
31 */
32
33 #include "catch.hpp"
34 #include "test/src/helpers.h"
35 #include "test/src/vfs_helpers.h"
36 #ifdef _WIN32
37 #include "tiledb/sm/filesystem/win.h"
38 #else
39 #include "tiledb/sm/filesystem/posix.h"
40 #endif
41 #include "tiledb/sm/c_api/tiledb.h"
42 #include "tiledb/sm/misc/utils.h"
43
44 #include <iostream>
45 #include <sstream>
46 #include <thread>
47
48 using namespace tiledb::test;
49
50 struct SparseRealFx {
51 // TileDB context
52 tiledb_ctx_t* ctx_;
53 tiledb_vfs_t* vfs_;
54
55 // Vector of supported filsystems
56 const std::vector<std::unique_ptr<SupportedFs>> fs_vec_;
57
58 // Functions
59 SparseRealFx();
60 ~SparseRealFx();
61 void create_temp_dir(const std::string& path);
62 void remove_temp_dir(const std::string& path);
63 void create_sparse_array(const std::string& path);
64 void create_sparse_array_double(const std::string& path);
65 void write_sparse_array(const std::string& path);
66 void write_sparse_array_next_partition_bug(const std::string& path);
67 void read_sparse_array(const std::string& path);
68 void read_sparse_array_next_partition_bug(const std::string& path);
69 static std::string random_name(const std::string& prefix);
70 };
71
SparseRealFx()72 SparseRealFx::SparseRealFx()
73 : fs_vec_(vfs_test_get_fs_vec()) {
74 // Initialize vfs test
75 REQUIRE(vfs_test_init(fs_vec_, &ctx_, &vfs_).ok());
76 }
77
~SparseRealFx()78 SparseRealFx::~SparseRealFx() {
79 // Close vfs test
80 REQUIRE(vfs_test_close(fs_vec_, ctx_, vfs_).ok());
81 tiledb_vfs_free(&vfs_);
82 tiledb_ctx_free(&ctx_);
83 }
84
create_temp_dir(const std::string & path)85 void SparseRealFx::create_temp_dir(const std::string& path) {
86 remove_temp_dir(path);
87 REQUIRE(tiledb_vfs_create_dir(ctx_, vfs_, path.c_str()) == TILEDB_OK);
88 }
89
remove_temp_dir(const std::string & path)90 void SparseRealFx::remove_temp_dir(const std::string& path) {
91 int is_dir = 0;
92 REQUIRE(tiledb_vfs_is_dir(ctx_, vfs_, path.c_str(), &is_dir) == TILEDB_OK);
93 if (is_dir)
94 REQUIRE(tiledb_vfs_remove_dir(ctx_, vfs_, path.c_str()) == TILEDB_OK);
95 }
96
random_name(const std::string & prefix)97 std::string SparseRealFx::random_name(const std::string& prefix) {
98 std::stringstream ss;
99 ss << prefix << "-" << std::this_thread::get_id() << "-"
100 << TILEDB_TIMESTAMP_NOW_MS;
101 return ss.str();
102 }
103
create_sparse_array(const std::string & path)104 void SparseRealFx::create_sparse_array(const std::string& path) {
105 // Create dimensions
106 float dim_domain[] = {-180.0f, 180.0f, -90.0f, 90.0f};
107 float tile_extents[] = {10.1f, 10.1f};
108 tiledb_dimension_t* d1;
109 int rc = tiledb_dimension_alloc(
110 ctx_, "d1", TILEDB_FLOAT32, &dim_domain[0], &tile_extents[0], &d1);
111 CHECK(rc == TILEDB_OK);
112 tiledb_dimension_t* d2;
113 rc = tiledb_dimension_alloc(
114 ctx_, "d2", TILEDB_FLOAT32, &dim_domain[2], &tile_extents[1], &d2);
115 CHECK(rc == TILEDB_OK);
116
117 // Create domain
118 tiledb_domain_t* domain;
119 rc = tiledb_domain_alloc(ctx_, &domain);
120 CHECK(rc == TILEDB_OK);
121 rc = tiledb_domain_add_dimension(ctx_, domain, d1);
122 CHECK(rc == TILEDB_OK);
123 rc = tiledb_domain_add_dimension(ctx_, domain, d2);
124 CHECK(rc == TILEDB_OK);
125
126 // Create attributes
127 tiledb_attribute_t* a;
128 rc = tiledb_attribute_alloc(ctx_, "a", TILEDB_INT32, &a);
129 CHECK(rc == TILEDB_OK);
130 tiledb_filter_t* filter;
131 tiledb_filter_list_t* list;
132 rc = tiledb_filter_alloc(ctx_, TILEDB_FILTER_LZ4, &filter);
133 CHECK(rc == TILEDB_OK);
134 rc = tiledb_filter_list_alloc(ctx_, &list);
135 CHECK(rc == TILEDB_OK);
136 rc = tiledb_filter_list_add_filter(ctx_, list, filter);
137 CHECK(rc == TILEDB_OK);
138 rc = tiledb_attribute_set_filter_list(ctx_, a, list);
139 CHECK(rc == TILEDB_OK);
140
141 // Create array schema
142 tiledb_array_schema_t* array_schema;
143 rc = tiledb_array_schema_alloc(ctx_, TILEDB_SPARSE, &array_schema);
144 CHECK(rc == TILEDB_OK);
145 rc = tiledb_array_schema_set_cell_order(ctx_, array_schema, TILEDB_ROW_MAJOR);
146 CHECK(rc == TILEDB_OK);
147 rc = tiledb_array_schema_set_tile_order(ctx_, array_schema, TILEDB_ROW_MAJOR);
148 CHECK(rc == TILEDB_OK);
149 rc = tiledb_array_schema_set_domain(ctx_, array_schema, domain);
150 CHECK(rc == TILEDB_OK);
151 rc = tiledb_array_schema_add_attribute(ctx_, array_schema, a);
152 CHECK(rc == TILEDB_OK);
153
154 // Check array schema
155 rc = tiledb_array_schema_check(ctx_, array_schema);
156 CHECK(rc == TILEDB_OK);
157
158 // Create array
159 rc = tiledb_array_create(ctx_, path.c_str(), array_schema);
160 CHECK(rc == TILEDB_OK);
161
162 // Clean up
163 tiledb_filter_free(&filter);
164 tiledb_filter_list_free(&list);
165 tiledb_attribute_free(&a);
166 tiledb_dimension_free(&d1);
167 tiledb_dimension_free(&d2);
168 tiledb_domain_free(&domain);
169 tiledb_array_schema_free(&array_schema);
170 }
171
write_sparse_array(const std::string & path)172 void SparseRealFx::write_sparse_array(const std::string& path) {
173 // Open array
174 tiledb_array_t* array;
175 int rc = tiledb_array_alloc(ctx_, path.c_str(), &array);
176 CHECK(rc == TILEDB_OK);
177 rc = tiledb_array_open(ctx_, array, TILEDB_WRITE);
178 CHECK(rc == TILEDB_OK);
179
180 int a[] = {1, 2, 3, 4, 5};
181 uint64_t a_size = sizeof(a);
182 float coords_dim1[] = {-23.5f, 43.56f, 66.2f, -160.1f, 1.0f};
183 float coords_dim2[] = {-20.0f, 80.0f, -0.3f, 89.1f, 1.0f};
184 uint64_t coords_size = sizeof(coords_dim1);
185 tiledb_query_t* query;
186 rc = tiledb_query_alloc(ctx_, array, TILEDB_WRITE, &query);
187 REQUIRE(rc == TILEDB_OK);
188 rc = tiledb_query_set_data_buffer(ctx_, query, "a", a, &a_size);
189 REQUIRE(rc == TILEDB_OK);
190 rc = tiledb_query_set_data_buffer(
191 ctx_, query, "d1", coords_dim1, &coords_size);
192 REQUIRE(rc == TILEDB_OK);
193 rc = tiledb_query_set_data_buffer(
194 ctx_, query, "d2", coords_dim2, &coords_size);
195 REQUIRE(rc == TILEDB_OK);
196 rc = tiledb_query_set_layout(ctx_, query, TILEDB_UNORDERED);
197 REQUIRE(rc == TILEDB_OK);
198 rc = tiledb_query_submit(ctx_, query);
199 REQUIRE(rc == TILEDB_OK);
200 rc = tiledb_query_finalize(ctx_, query);
201 REQUIRE(rc == TILEDB_OK);
202
203 // Close array
204 rc = tiledb_array_close(ctx_, array);
205 CHECK(rc == TILEDB_OK);
206
207 // Clean up
208 tiledb_array_free(&array);
209 tiledb_query_free(&query);
210 }
211
write_sparse_array_next_partition_bug(const std::string & path)212 void SparseRealFx::write_sparse_array_next_partition_bug(
213 const std::string& path) {
214 // Open array
215 tiledb_array_t* array;
216 int rc = tiledb_array_alloc(ctx_, path.c_str(), &array);
217 CHECK(rc == TILEDB_OK);
218 rc = tiledb_array_open(ctx_, array, TILEDB_WRITE);
219 CHECK(rc == TILEDB_OK);
220
221 int a[] = {1, 2};
222 uint64_t a_size = sizeof(a);
223 float coords_dim1[] = {-180.0f, -180.0f};
224 float coords_dim2[] = {1.0f, 2.0f};
225 uint64_t coords_size = sizeof(coords_dim1);
226 tiledb_query_t* query;
227 rc = tiledb_query_alloc(ctx_, array, TILEDB_WRITE, &query);
228 REQUIRE(rc == TILEDB_OK);
229 rc = tiledb_query_set_data_buffer(ctx_, query, "a", a, &a_size);
230 REQUIRE(rc == TILEDB_OK);
231 rc = tiledb_query_set_data_buffer(
232 ctx_, query, "d1", coords_dim1, &coords_size);
233 REQUIRE(rc == TILEDB_OK);
234 rc = tiledb_query_set_data_buffer(
235 ctx_, query, "d2", coords_dim2, &coords_size);
236 REQUIRE(rc == TILEDB_OK);
237 rc = tiledb_query_set_layout(ctx_, query, TILEDB_UNORDERED);
238 REQUIRE(rc == TILEDB_OK);
239 rc = tiledb_query_submit(ctx_, query);
240 REQUIRE(rc == TILEDB_OK);
241 rc = tiledb_query_finalize(ctx_, query);
242 REQUIRE(rc == TILEDB_OK);
243
244 // Close array
245 rc = tiledb_array_close(ctx_, array);
246 CHECK(rc == TILEDB_OK);
247
248 // Clean up
249 tiledb_array_free(&array);
250 tiledb_query_free(&query);
251 }
252
read_sparse_array(const std::string & path)253 void SparseRealFx::read_sparse_array(const std::string& path) {
254 // Open array
255 tiledb_array_t* array;
256 int rc = tiledb_array_alloc(ctx_, path.c_str(), &array);
257 CHECK(rc == TILEDB_OK);
258 rc = tiledb_array_open(ctx_, array, TILEDB_READ);
259 CHECK(rc == TILEDB_OK);
260
261 int a[16];
262 uint64_t a_size = sizeof(a);
263 float coords_dim1[16];
264 float coords_dim2[16];
265 uint64_t coords_size = sizeof(coords_dim1);
266 tiledb_query_t* query;
267 float subarray[] = {-180.0f, 180.0f, -90.0f, 90.0f};
268 rc = tiledb_query_alloc(ctx_, array, TILEDB_READ, &query);
269 REQUIRE(rc == TILEDB_OK);
270 rc = tiledb_query_set_subarray(ctx_, query, subarray);
271 REQUIRE(rc == TILEDB_OK);
272 rc = tiledb_query_set_data_buffer(ctx_, query, "a", a, &a_size);
273 REQUIRE(rc == TILEDB_OK);
274 rc = tiledb_query_set_data_buffer(
275 ctx_, query, "d1", coords_dim1, &coords_size);
276 REQUIRE(rc == TILEDB_OK);
277 rc = tiledb_query_set_data_buffer(
278 ctx_, query, "d2", coords_dim2, &coords_size);
279 REQUIRE(rc == TILEDB_OK);
280 rc = tiledb_query_set_layout(ctx_, query, TILEDB_ROW_MAJOR);
281 REQUIRE(rc == TILEDB_OK);
282 rc = tiledb_query_submit(ctx_, query);
283 REQUIRE(rc == TILEDB_OK);
284 rc = tiledb_query_finalize(ctx_, query);
285 REQUIRE(rc == TILEDB_OK);
286
287 int a_c[] = {4, 1, 5, 2, 3};
288 float coords_c_dim1[] = {-160.1f, -23.5f, 1.0f, 43.56f, 66.2f};
289 float coords_c_dim2[] = {89.1f, -20.0f, 1.0f, 80.0f, -0.3f};
290 CHECK(a_size == sizeof(a_c));
291 CHECK(!memcmp(a, a_c, sizeof(a_c)));
292 CHECK(coords_size == sizeof(coords_c_dim1));
293 CHECK(!memcmp(coords_dim1, coords_c_dim1, sizeof(coords_c_dim1)));
294 CHECK(!memcmp(coords_dim2, coords_c_dim2, sizeof(coords_c_dim2)));
295
296 // Close array
297 rc = tiledb_array_close(ctx_, array);
298 CHECK(rc == TILEDB_OK);
299
300 // Clean up
301 tiledb_array_free(&array);
302 tiledb_query_free(&query);
303 }
304
read_sparse_array_next_partition_bug(const std::string & path)305 void SparseRealFx::read_sparse_array_next_partition_bug(
306 const std::string& path) {
307 // Open array
308 tiledb_array_t* array;
309 int rc = tiledb_array_alloc(ctx_, path.c_str(), &array);
310 CHECK(rc == TILEDB_OK);
311 rc = tiledb_array_open(ctx_, array, TILEDB_READ);
312 CHECK(rc == TILEDB_OK);
313
314 int a[1];
315 uint64_t a_size = sizeof(a);
316 float coords_dim1[4];
317 float coords_dim2[4];
318 uint64_t coords_size = sizeof(coords_dim1);
319 tiledb_query_t* query;
320 float subarray[] = {-180.0f, 180.0f, -90.0f, 90.0f};
321 rc = tiledb_query_alloc(ctx_, array, TILEDB_READ, &query);
322 REQUIRE(rc == TILEDB_OK);
323 rc = tiledb_query_set_subarray(ctx_, query, subarray);
324 REQUIRE(rc == TILEDB_OK);
325 rc = tiledb_query_set_data_buffer(ctx_, query, "a", a, &a_size);
326 REQUIRE(rc == TILEDB_OK);
327 rc = tiledb_query_set_data_buffer(
328 ctx_, query, "d1", coords_dim1, &coords_size);
329 REQUIRE(rc == TILEDB_OK);
330 rc = tiledb_query_set_data_buffer(
331 ctx_, query, "d2", coords_dim2, &coords_size);
332 REQUIRE(rc == TILEDB_OK);
333 rc = tiledb_query_set_layout(ctx_, query, TILEDB_ROW_MAJOR);
334 REQUIRE(rc == TILEDB_OK);
335 rc = tiledb_query_submit(ctx_, query);
336 REQUIRE(rc == TILEDB_OK);
337 rc = tiledb_query_finalize(ctx_, query);
338 REQUIRE(rc == TILEDB_OK);
339
340 CHECK(a_size == sizeof(int));
341 CHECK(a[0] == 1);
342 CHECK(coords_dim1[0] == -180.0f);
343 CHECK(coords_dim2[0] == 1.0f);
344
345 // Close array
346 rc = tiledb_array_close(ctx_, array);
347 CHECK(rc == TILEDB_OK);
348
349 // Clean up
350 tiledb_array_free(&array);
351 tiledb_query_free(&query);
352 }
353
create_sparse_array_double(const std::string & path)354 void SparseRealFx::create_sparse_array_double(const std::string& path) {
355 // Create dimensions
356 double dim_domain[] = {-180.0, 180.0, -90.0, 90.0};
357 double tile_extents[] = {1.0, 1.0};
358 tiledb_dimension_t* d1;
359 int rc = tiledb_dimension_alloc(
360 ctx_, "d1", TILEDB_FLOAT64, &dim_domain[0], &tile_extents[0], &d1);
361 CHECK(rc == TILEDB_OK);
362 tiledb_dimension_t* d2;
363 rc = tiledb_dimension_alloc(
364 ctx_, "d2", TILEDB_FLOAT64, &dim_domain[2], &tile_extents[1], &d2);
365 CHECK(rc == TILEDB_OK);
366
367 // Create domain
368 tiledb_domain_t* domain;
369 rc = tiledb_domain_alloc(ctx_, &domain);
370 CHECK(rc == TILEDB_OK);
371 rc = tiledb_domain_add_dimension(ctx_, domain, d1);
372 CHECK(rc == TILEDB_OK);
373 rc = tiledb_domain_add_dimension(ctx_, domain, d2);
374 CHECK(rc == TILEDB_OK);
375
376 // Create attributes
377 tiledb_attribute_t* a;
378 rc = tiledb_attribute_alloc(ctx_, "a", TILEDB_INT32, &a);
379 CHECK(rc == TILEDB_OK);
380 tiledb_filter_t* filter;
381 tiledb_filter_list_t* list;
382 rc = tiledb_filter_alloc(ctx_, TILEDB_FILTER_LZ4, &filter);
383 CHECK(rc == TILEDB_OK);
384 rc = tiledb_filter_list_alloc(ctx_, &list);
385 CHECK(rc == TILEDB_OK);
386 rc = tiledb_filter_list_add_filter(ctx_, list, filter);
387 CHECK(rc == TILEDB_OK);
388 rc = tiledb_attribute_set_filter_list(ctx_, a, list);
389 CHECK(rc == TILEDB_OK);
390
391 // Create array schema
392 tiledb_array_schema_t* array_schema;
393 rc = tiledb_array_schema_alloc(ctx_, TILEDB_SPARSE, &array_schema);
394 CHECK(rc == TILEDB_OK);
395 rc = tiledb_array_schema_set_cell_order(ctx_, array_schema, TILEDB_ROW_MAJOR);
396 CHECK(rc == TILEDB_OK);
397 rc = tiledb_array_schema_set_tile_order(ctx_, array_schema, TILEDB_ROW_MAJOR);
398 CHECK(rc == TILEDB_OK);
399 rc = tiledb_array_schema_set_domain(ctx_, array_schema, domain);
400 CHECK(rc == TILEDB_OK);
401 rc = tiledb_array_schema_add_attribute(ctx_, array_schema, a);
402 CHECK(rc == TILEDB_OK);
403
404 // Check array schema
405 rc = tiledb_array_schema_check(ctx_, array_schema);
406 CHECK(rc == TILEDB_OK);
407
408 // Create array
409 rc = tiledb_array_create(ctx_, path.c_str(), array_schema);
410 CHECK(rc == TILEDB_OK);
411
412 // Clean up
413 tiledb_filter_free(&filter);
414 tiledb_filter_list_free(&list);
415 tiledb_attribute_free(&a);
416 tiledb_dimension_free(&d1);
417 tiledb_dimension_free(&d2);
418 tiledb_domain_free(&domain);
419 tiledb_array_schema_free(&array_schema);
420 }
421
422 TEST_CASE_METHOD(
423 SparseRealFx,
424 "C API: Test 2d sparse array with real domain",
425 "[capi][sparse-real]") {
426 SupportedFsLocal local_fs;
427 std::string vector_name =
428 local_fs.file_prefix() + local_fs.temp_dir() + "sparse_real";
429 create_temp_dir(local_fs.file_prefix() + local_fs.temp_dir());
430
431 create_sparse_array(vector_name);
432 write_sparse_array(vector_name);
433 read_sparse_array(vector_name);
434
435 remove_temp_dir(local_fs.file_prefix() + local_fs.temp_dir());
436 }
437
438 TEST_CASE_METHOD(
439 SparseRealFx,
440 "C API: Test 2d sparse array with real domain, next subarray partition bug",
441 "[capi][sparse-real][sparse-real-next-partition-bug]") {
442 SupportedFsLocal local_fs;
443 std::string array_name = local_fs.file_prefix() + local_fs.temp_dir() +
444 "sparse_real_next_partition_bug";
445 create_temp_dir(local_fs.file_prefix() + local_fs.temp_dir());
446
447 create_sparse_array(array_name);
448 write_sparse_array_next_partition_bug(array_name);
449 read_sparse_array_next_partition_bug(array_name);
450
451 remove_temp_dir(local_fs.file_prefix() + local_fs.temp_dir());
452 }
453
454 TEST_CASE_METHOD(
455 SparseRealFx,
456 "C API: Test 2d sparse array with real domain, NaN in subarray",
457 "[capi][sparse-real][sparse-real-nan-subarray]") {
458 SupportedFsLocal local_fs;
459 std::string array_name =
460 local_fs.file_prefix() + local_fs.temp_dir() + "sparse_real_nan_subarray";
461 create_temp_dir(local_fs.file_prefix() + local_fs.temp_dir());
462
463 create_sparse_array(array_name);
464 write_sparse_array(array_name);
465
466 // Open array
467 tiledb_array_t* array;
468 int rc = tiledb_array_alloc(ctx_, array_name.c_str(), &array);
469 CHECK(rc == TILEDB_OK);
470 rc = tiledb_array_open(ctx_, array, TILEDB_READ);
471 CHECK(rc == TILEDB_OK);
472
473 tiledb_query_t* query;
474 rc = tiledb_query_alloc(ctx_, array, TILEDB_READ, &query);
475 REQUIRE(rc == TILEDB_OK);
476
477 // Set config for `sm.read_range_oob` = `error`
478 tiledb_config_t* config = nullptr;
479 tiledb_error_t* error = nullptr;
480 REQUIRE(tiledb_config_alloc(&config, &error) == TILEDB_OK);
481 REQUIRE(error == nullptr);
482 rc = tiledb_config_set(config, "sm.read_range_oob", "error", &error);
483 REQUIRE(rc == TILEDB_OK);
484 REQUIRE(error == nullptr);
485 rc = tiledb_query_set_config(ctx_, query, config);
486 REQUIRE(rc == TILEDB_OK);
487
488 // Check Nan
489 float subarray[] = {
490 -180.0f, std::numeric_limits<float>::quiet_NaN(), -90.0f, 90.0f};
491 rc = tiledb_query_set_subarray(ctx_, query, subarray);
492 CHECK(rc == TILEDB_ERR);
493
494 // Check infinity
495 subarray[1] = std::numeric_limits<float>::infinity();
496 rc = tiledb_query_set_subarray(ctx_, query, subarray);
497 CHECK(rc == TILEDB_ERR);
498
499 // Clean up
500 rc = tiledb_array_close(ctx_, array);
501 CHECK(rc == TILEDB_OK);
502 tiledb_array_free(&array);
503 tiledb_config_free(&config);
504 tiledb_query_free(&query);
505
506 remove_temp_dir(local_fs.file_prefix() + local_fs.temp_dir());
507 }
508
509 TEST_CASE_METHOD(
510 SparseRealFx,
511 "C API: Test 2d sparse array with real domain, small gap point-query bug",
512 "[capi][sparse-real][sparse-real-small-gap-point-query-bug]") {
513 SupportedFsLocal local_fs;
514 std::string array_name = local_fs.file_prefix() + local_fs.temp_dir() +
515 "sparse_real_small_gap_point_query_bug";
516 create_temp_dir(local_fs.file_prefix() + local_fs.temp_dir());
517
518 create_sparse_array_double(array_name);
519
520 // Write 2 points with 2*eps<double> gap in the first dimension
521 {
522 tiledb_array_t* array;
523 int rc = tiledb_array_alloc(ctx_, array_name.c_str(), &array);
524 CHECK(rc == TILEDB_OK);
525 rc = tiledb_array_open(ctx_, array, TILEDB_WRITE);
526 CHECK(rc == TILEDB_OK);
527
528 int a[] = {1, 2};
529 uint64_t a_size = sizeof(a);
530 double coords_dim1[] = {-180.0, -179.99999999999997};
531 double coords_dim2[] = {1.0, 0.9999999999999999};
532
533 uint64_t coords_size = sizeof(coords_dim1);
534 tiledb_query_t* query;
535 rc = tiledb_query_alloc(ctx_, array, TILEDB_WRITE, &query);
536 REQUIRE(rc == TILEDB_OK);
537 rc = tiledb_query_set_data_buffer(ctx_, query, "a", a, &a_size);
538 REQUIRE(rc == TILEDB_OK);
539 rc = tiledb_query_set_data_buffer(
540 ctx_, query, "d1", coords_dim1, &coords_size);
541 REQUIRE(rc == TILEDB_OK);
542 rc = tiledb_query_set_data_buffer(
543 ctx_, query, "d2", coords_dim2, &coords_size);
544 REQUIRE(rc == TILEDB_OK);
545 rc = tiledb_query_set_layout(ctx_, query, TILEDB_UNORDERED);
546 REQUIRE(rc == TILEDB_OK);
547 rc = tiledb_query_submit(ctx_, query);
548 REQUIRE(rc == TILEDB_OK);
549 rc = tiledb_query_finalize(ctx_, query);
550 REQUIRE(rc == TILEDB_OK);
551
552 // Close array
553 rc = tiledb_array_close(ctx_, array);
554 CHECK(rc == TILEDB_OK);
555
556 // Clean up
557 tiledb_array_free(&array);
558 tiledb_query_free(&query);
559 }
560
561 // Read back points
562 {
563 tiledb_array_t* array;
564 int rc = tiledb_array_alloc(ctx_, array_name.c_str(), &array);
565 CHECK(rc == TILEDB_OK);
566 rc = tiledb_array_open(ctx_, array, TILEDB_READ);
567 CHECK(rc == TILEDB_OK);
568
569 int a[1];
570 uint64_t a_size = sizeof(a);
571 double coords_dim1[1];
572 double coords_dim2[1];
573 uint64_t coords_size = sizeof(coords_dim1);
574 tiledb_query_t* query;
575 double subarray[] = {-180.0, -180.0, 1.0, 1.0};
576
577 rc = tiledb_query_alloc(ctx_, array, TILEDB_READ, &query);
578 REQUIRE(rc == TILEDB_OK);
579 rc = tiledb_query_set_subarray(ctx_, query, subarray);
580 REQUIRE(rc == TILEDB_OK);
581 rc = tiledb_query_set_data_buffer(ctx_, query, "a", a, &a_size);
582 REQUIRE(rc == TILEDB_OK);
583 rc = tiledb_query_set_data_buffer(
584 ctx_, query, "d1", coords_dim1, &coords_size);
585 REQUIRE(rc == TILEDB_OK);
586 rc = tiledb_query_set_data_buffer(
587 ctx_, query, "d2", coords_dim2, &coords_size);
588 REQUIRE(rc == TILEDB_OK);
589 rc = tiledb_query_set_layout(ctx_, query, TILEDB_ROW_MAJOR);
590 REQUIRE(rc == TILEDB_OK);
591 rc = tiledb_query_submit(ctx_, query);
592 REQUIRE(rc == TILEDB_OK);
593 rc = tiledb_query_finalize(ctx_, query);
594 REQUIRE(rc == TILEDB_OK);
595
596 CHECK(a_size == sizeof(int));
597 CHECK(a[0] == 1);
598 CHECK(coords_dim1[0] == -180.0);
599 CHECK(coords_dim2[0] == 1.0f);
600
601 // Close array
602 rc = tiledb_array_close(ctx_, array);
603 CHECK(rc == TILEDB_OK);
604
605 // Clean up
606 tiledb_array_free(&array);
607 tiledb_query_free(&query);
608 }
609 remove_temp_dir(local_fs.file_prefix() + local_fs.temp_dir());
610 }
611