Skip to content

Commit 485dace

Browse files
committed
Array schema load changes.
1 parent 87db931 commit 485dace

File tree

4 files changed

+154
-49
lines changed

4 files changed

+154
-49
lines changed

tiledb/sm/array_schema/array_schema_operations.cc

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@
3636
#include "tiledb/sm/array_schema/dimension_label.h"
3737
#include "tiledb/sm/array_schema/domain.h"
3838
#include "tiledb/sm/array_schema/enumeration.h"
39+
#include "tiledb/sm/config/config.h"
40+
#include "tiledb/sm/crypto/encryption_key.h"
3941
#include "tiledb/sm/filesystem/uri.h"
4042
#include "tiledb/sm/misc/integral_type_casts.h"
43+
#include "tiledb/sm/rest/rest_client.h"
44+
#include "tiledb/sm/storage_manager/context.h"
4145
#include "tiledb/sm/storage_manager/context_resources.h"
4246
#include "tiledb/sm/tile/generic_tile_io.h"
4347
#include "tiledb/sm/tile/tile.h"
@@ -227,4 +231,61 @@ void store_array_schema(
227231
}
228232
}
229233

234+
shared_ptr<ArraySchema> load_array_schema(
235+
const Context& ctx, const URI& uri, const Config& config) {
236+
// Check array name
237+
if (uri.is_invalid()) {
238+
throw std::runtime_error("Failed to load array schema; Invalid array URI");
239+
}
240+
241+
if (uri.is_tiledb()) {
242+
auto& rest_client = ctx.rest_client();
243+
auto&& [st, array_schema_response] =
244+
rest_client.get_array_schema_from_rest(uri);
245+
throw_if_not_ok(st);
246+
return std::move(array_schema_response.value());
247+
} else {
248+
// Create key
249+
tiledb::sm::EncryptionKey key;
250+
throw_if_not_ok(
251+
key.set_key(tiledb::sm::EncryptionType::NO_ENCRYPTION, nullptr, 0));
252+
253+
// Load URIs from the array directory
254+
optional<tiledb::sm::ArrayDirectory> array_dir;
255+
array_dir.emplace(
256+
ctx.resources(),
257+
uri,
258+
0,
259+
UINT64_MAX,
260+
tiledb::sm::ArrayDirectoryMode::SCHEMA_ONLY);
261+
262+
auto tracker = ctx.resources().ephemeral_memory_tracker();
263+
// Load latest array schema
264+
auto&& array_schema_latest =
265+
array_dir->load_array_schema_latest(key, tracker);
266+
267+
// Load enumerations if config option is set.
268+
bool incl_enums = config.get<bool>(
269+
"rest.load_enumerations_on_array_open", Config::must_find);
270+
if (incl_enums) {
271+
std::vector<std::string> enmr_paths_to_load;
272+
auto enmr_names = array_schema_latest->get_enumeration_names();
273+
for (auto& name : enmr_names) {
274+
if (!array_schema_latest->is_enumeration_loaded(name)) {
275+
auto& path = array_schema_latest->get_enumeration_path_name(name);
276+
enmr_paths_to_load.emplace_back(path);
277+
}
278+
}
279+
280+
auto enmrs_loaded = array_dir->load_enumerations_from_paths(
281+
enmr_paths_to_load, key, tracker);
282+
for (auto& enmr : enmrs_loaded) {
283+
array_schema_latest->store_enumeration(enmr);
284+
}
285+
}
286+
287+
return std::move(array_schema_latest);
288+
}
289+
}
290+
230291
} // namespace tiledb::sm

tiledb/sm/array_schema/array_schema_operations.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,11 @@ using namespace tiledb::common;
4141
namespace tiledb::sm {
4242

4343
class ArraySchema;
44+
class Config;
45+
class Context;
4446
class ContextResources;
4547
class EncryptionKey;
48+
class URI;
4649

4750
/* ********************************* */
4851
/* API */
@@ -76,6 +79,16 @@ void store_array_schema(
7679
const shared_ptr<ArraySchema>& array_schema,
7780
const EncryptionKey& encryption_key);
7881

82+
/**
83+
* Handles loading an array schema from a URI.
84+
*
85+
* @param ctx TileDB Context.
86+
* @param uri The URI of the array to load schema.
87+
* @param config TileDB Config. If null, the context config will be used.
88+
*/
89+
shared_ptr<ArraySchema> load_array_schema(
90+
const Context& ctx, const URI& uri, const Config& config);
91+
7992
} // namespace tiledb::sm
8093

8194
#endif // TILEDB_ARRAY_SCHEMA_OPERATIONS_H

tiledb/sm/c_api/tiledb.cc

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include "tiledb/common/memory_tracker.h"
5757
#include "tiledb/sm/array/array.h"
5858
#include "tiledb/sm/array_schema/array_schema.h"
59+
#include "tiledb/sm/array_schema/array_schema_operations.h"
5960
#include "tiledb/sm/array_schema/dimension_label.h"
6061
#include "tiledb/sm/c_api/api_argument_validator.h"
6162
#include "tiledb/sm/config/config.h"
@@ -455,64 +456,51 @@ int32_t tiledb_array_schema_load(
455456
const char* array_uri,
456457
tiledb_array_schema_t** array_schema) {
457458
// Create array schema
459+
ensure_context_is_valid(ctx);
460+
ensure_output_pointer_is_valid(array_schema);
458461
*array_schema = new (std::nothrow) tiledb_array_schema_t;
459462
if (*array_schema == nullptr) {
460-
auto st = Status_Error("Failed to allocate TileDB array schema object");
461-
LOG_STATUS_NO_RETURN_VALUE(st);
462-
save_error(ctx, st);
463-
return TILEDB_OOM;
463+
throw CAPIStatusException("Failed to allocate TileDB array schema object");
464464
}
465465

466-
// Check array name
467-
tiledb::sm::URI uri(array_uri);
468-
if (uri.is_invalid()) {
469-
auto st = Status_Error("Failed to load array schema; Invalid array URI");
470-
LOG_STATUS_NO_RETURN_VALUE(st);
471-
save_error(ctx, st);
472-
return TILEDB_ERR;
466+
try {
467+
// Use a default constructed config to load the schema with default options.
468+
(*array_schema)->array_schema_ =
469+
load_array_schema(ctx->context(), sm::URI(array_uri), sm::Config());
470+
} catch (...) {
471+
delete *array_schema;
472+
throw;
473473
}
474474

475-
if (uri.is_tiledb()) {
476-
auto& rest_client = ctx->context().rest_client();
477-
auto&& [st, array_schema_rest] =
478-
rest_client.get_array_schema_from_rest(uri);
479-
if (!st.ok()) {
480-
LOG_STATUS_NO_RETURN_VALUE(st);
481-
save_error(ctx, st);
482-
delete *array_schema;
483-
return TILEDB_ERR;
484-
}
485-
(*array_schema)->array_schema_ = array_schema_rest.value();
486-
} else {
487-
// Create key
488-
tiledb::sm::EncryptionKey key;
489-
throw_if_not_ok(
490-
key.set_key(tiledb::sm::EncryptionType::NO_ENCRYPTION, nullptr, 0));
475+
return TILEDB_OK;
476+
}
491477

492-
// Load URIs from the array directory
493-
optional<tiledb::sm::ArrayDirectory> array_dir;
494-
try {
495-
array_dir.emplace(
496-
ctx->resources(),
497-
uri,
498-
0,
499-
UINT64_MAX,
500-
tiledb::sm::ArrayDirectoryMode::SCHEMA_ONLY);
501-
} catch (const std::logic_error& le) {
502-
auto st = Status_ArrayDirectoryError(le.what());
503-
LOG_STATUS_NO_RETURN_VALUE(st);
504-
save_error(ctx, st);
505-
delete *array_schema;
506-
return TILEDB_ERR;
507-
}
478+
int32_t tiledb_array_schema_load_with_options(
479+
tiledb_ctx_t* ctx,
480+
tiledb_config_t* config,
481+
const char* array_uri,
482+
tiledb_array_schema_t** array_schema) {
483+
ensure_context_is_valid(ctx);
484+
ensure_config_is_valid(config);
485+
ensure_output_pointer_is_valid(array_schema);
508486

509-
auto tracker = ctx->resources().ephemeral_memory_tracker();
487+
// Create array schema
488+
*array_schema = new (std::nothrow) tiledb_array_schema_t;
489+
if (*array_schema == nullptr) {
490+
throw CAPIStatusException("Failed to allocate TileDB array schema object");
491+
}
510492

511-
// Load latest array schema
512-
auto&& array_schema_latest =
513-
array_dir->load_array_schema_latest(key, tracker);
514-
(*array_schema)->array_schema_ = array_schema_latest;
493+
try {
494+
// Use passed config or context config to load the schema with set options.
495+
(*array_schema)->array_schema_ = load_array_schema(
496+
ctx->context(),
497+
sm::URI(array_uri),
498+
config ? config->config() : ctx->config());
499+
} catch (...) {
500+
delete *array_schema;
501+
throw;
515502
}
503+
516504
return TILEDB_OK;
517505
}
518506

@@ -5011,6 +4999,16 @@ CAPI_INTERFACE(
50114999
ctx, array_uri, array_schema);
50125000
}
50135001

5002+
CAPI_INTERFACE(
5003+
array_schema_load_with_options,
5004+
tiledb_ctx_t* ctx,
5005+
tiledb_config_t* config,
5006+
const char* array_uri,
5007+
tiledb_array_schema_t** array_schema) {
5008+
return api_entry<tiledb::api::tiledb_array_schema_load_with_options>(
5009+
ctx, config, array_uri, array_schema);
5010+
}
5011+
50145012
CAPI_INTERFACE(
50155013
array_schema_get_array_type,
50165014
tiledb_ctx_t* ctx,

tiledb/sm/c_api/tiledb.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ TILEDB_EXPORT int32_t tiledb_array_schema_check(
604604

605605
/**
606606
* Retrieves the schema of an array from the disk, creating an array schema
607-
* struct.
607+
* struct. The schema retrieved will always be the latest schema for the array.
608608
*
609609
* **Example:**
610610
*
@@ -624,6 +624,39 @@ TILEDB_EXPORT int32_t tiledb_array_schema_load(
624624
const char* array_uri,
625625
tiledb_array_schema_t** array_schema) TILEDB_NOEXCEPT;
626626

627+
/**
628+
* Retrieves the schema of an array, creating an array schema struct. Options to
629+
* load additional features are read from the provided tiledb_config_t*
630+
* instance. If the provided config is nullptr, the config from `ctx` is used
631+
* instead.
632+
*
633+
* Currently supported options to be read from the config:
634+
* - rest.load_enumerations_on_array_open - boolean
635+
*
636+
* **Example:**
637+
*
638+
* @code{.c}
639+
* tiledb_array_schema_t* array_schema;
640+
* tiledb_array_schema_load_with_options(
641+
* ctx,
642+
* config,
643+
* "s3://tiledb_bucket/my_array",
644+
* &array_schema);
645+
* // Make sure to free the array schema in the end
646+
* @endcode
647+
*
648+
* @param ctx The TileDB context.
649+
* @param config The TileDB config.
650+
* @param array_uri The array whose schema will be retrieved.
651+
* @param array_schema The array schema to be retrieved, or `NULL` upon error.
652+
* @return `TILEDB_OK` for success and `TILEDB_OOM` or `TILEDB_ERR` for error.
653+
*/
654+
TILEDB_EXPORT int32_t tiledb_array_schema_load_with_options(
655+
tiledb_ctx_t* ctx,
656+
tiledb_config_t* config,
657+
const char* array_uri,
658+
tiledb_array_schema_t** array_schema) TILEDB_NOEXCEPT;
659+
627660
/**
628661
* Retrieves the array type.
629662
*

0 commit comments

Comments
 (0)