Skip to content

Commit

Permalink
Add tiledb_array_has_metadata_key function and C++ API
Browse files Browse the repository at this point in the history
- Add history entry
- Also add entry for #1438.
  • Loading branch information
ihnorton committed Nov 26, 2019
1 parent 0323f97 commit 93fd276
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 0 deletions.
18 changes: 18 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
# In Progress

## New features

## Improvements

* Added support for indicating zero-value metadata by returning `value_num` == 1 from the `_get_metadatata` and `Array::get_metadata` APIs [#1438](https://github.com/TileDB-Inc/TileDB/pull/1438) (this is a non-breaking change, as the documented return of `value == nullptr` to indicate missing keys does not change)`

## Deprecations

## Bug fixes

## API additions

* Added C API function `tiledb_array_has_metadata_key` and C++ API function `Array::has_metadata_key` [#1439](https://github.com/TileDB-Inc/TileDB/pull/1439)

## API removals

# TileDB v1.7.0 Release Notes

TileDB 1.7.0 contains the new feature of array metadata, and numerous bugfixes.
Expand Down
16 changes: 16 additions & 0 deletions test/src/unit-capi-metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,22 @@ TEST_CASE_METHOD(
CHECK(key_len == strlen("bb"));
CHECK(!strncmp(key, "bb", strlen("bb")));

// Check has_key
int32_t has_key = 0;
rc = tiledb_array_has_metadata_key(ctx_, array, "bb", &v_type, &has_key);
CHECK(rc == TILEDB_OK);
CHECK(v_type == TILEDB_FLOAT32);
CHECK(has_key == 1);

// Check not has_key
v_type = (tiledb_datatype_t)std::numeric_limits<int32_t>::max();
rc = tiledb_array_has_metadata_key(
ctx_, array, "non-existent-key", &v_type, &has_key);
CHECK(rc == TILEDB_OK);
// The API does not touch v_type when no key is found.
CHECK((int32_t)v_type == std::numeric_limits<int32_t>::max());
CHECK(has_key == 0);

// Close array
rc = tiledb_array_close(ctx_, array);
REQUIRE(rc == TILEDB_OK);
Expand Down
13 changes: 13 additions & 0 deletions test/src/unit-cppapi-metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,19 @@ TEST_CASE_METHOD(
CHECK(key.size() == strlen("bb"));
CHECK(!strncmp(key.data(), "bb", strlen("bb")));

// Check has_key
bool has_key;
v_type = (tiledb_datatype_t)std::numeric_limits<int32_t>::max();
has_key = array.has_metadata("bb", &v_type);
CHECK(has_key == true);
CHECK(v_type == TILEDB_FLOAT32);

// Check not has_key
v_type = (tiledb_datatype_t)std::numeric_limits<int32_t>::max();
has_key = array.has_metadata("non-existent-key", &v_type);
CHECK(has_key == false);
CHECK(v_type == std::numeric_limits<int32_t>::max());

// Close array
array.close();
}
Expand Down
23 changes: 23 additions & 0 deletions tiledb/sm/array/array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,29 @@ Status Array::get_metadata_num(uint64_t* num) const {
return Status::Ok();
}

Status Array::has_metadata_key(
const char* key, Datatype* value_type, bool* has_key) {
// Check if array is open
if (!is_open_)
return LOG_STATUS(
Status::ArrayError("Cannot get metadata; Array is not open"));

// Check mode
if (query_type_ != QueryType::READ)
return LOG_STATUS(
Status::ArrayError("Cannot get metadata; Array was "
"not opened in read mode"));

// Check if key is null
if (key == nullptr)
return LOG_STATUS(
Status::ArrayError("Cannot get metadata; Key cannot be null"));

RETURN_NOT_OK(metadata_.has_key(key, value_type, has_key));

return Status::Ok();
}

Metadata* Array::metadata() {
return &metadata_;
}
Expand Down
3 changes: 3 additions & 0 deletions tiledb/sm/array/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ class Array {
/** Returns the number of array metadata items. */
Status get_metadata_num(uint64_t* num) const;

/** Sets has_key == 1 and corresponding value_type if the array has key. */
Status has_metadata_key(const char* key, Datatype* value_type, bool* has_key);

/** Returns the array metadata object. */
Metadata* metadata();

Expand Down
23 changes: 23 additions & 0 deletions tiledb/sm/c_api/tiledb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3385,6 +3385,29 @@ int32_t tiledb_array_get_metadata_from_index(
return TILEDB_OK;
}

int32_t tiledb_array_has_metadata_key(
tiledb_ctx_t* ctx,
tiledb_array_t* array,
const char* key,
tiledb_datatype_t* value_type,
int32_t* has_key) {
if (sanity_check(ctx) == TILEDB_ERR || sanity_check(ctx, array) == TILEDB_ERR)
return TILEDB_ERR;

// Check whether metadata has_key
bool has_the_key;
tiledb::sm::Datatype type;
if (SAVE_ERROR_CATCH(
ctx, array->array_->has_metadata_key(key, &type, &has_the_key)))
return TILEDB_ERR;

*has_key = has_the_key ? 1 : 0;
if (has_the_key) {
*value_type = static_cast<tiledb_datatype_t>(type);
}
return TILEDB_OK;
}

int32_t tiledb_array_consolidate_metadata(
tiledb_ctx_t* ctx, const char* array_uri, tiledb_config_t* config) {
return tiledb_array_consolidate_metadata_with_key(
Expand Down
20 changes: 20 additions & 0 deletions tiledb/sm/c_api/tiledb.h
Original file line number Diff line number Diff line change
Expand Up @@ -4118,6 +4118,26 @@ TILEDB_EXPORT int32_t tiledb_array_get_metadata_from_index(
uint32_t* value_num,
const void** value);

/**
* Checks whether a key exists in metadata from an open array. The array must
* be opened in READ mode, otherwise the function will error out.
*
* @param ctx The TileDB context.
* @param array An array opened in READ mode.
* @param key The key to be checked. UTF-8 encoding are acceptable.
* @param value_type The datatype of the value, if any.
* @param has_key Set to `1` if the metadata with given key exists, else `0`.
* @return `TILEDB_OK` for success and `TILEDB_ERR` for error.
*
* @note If the key does not exist, then `value` will be NULL.
*/
TILEDB_EXPORT int32_t tiledb_array_has_metadata_key(
tiledb_ctx_t* ctx,
tiledb_array_t* array,
const char* key,
tiledb_datatype_t* value_type,
int32_t* has_key);

/**
* Consolidates the array metadata into a single array metadata file.
*
Expand Down
20 changes: 20 additions & 0 deletions tiledb/sm/cpp_api/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,26 @@ class Array {
c_ctx, array_.get(), key.c_str(), value_type, value_num, value));
}

/**
* Checks if key exists in metadata from an open array. The array must
* be opened in READ mode, otherwise the function will error out.
*
* @param key The key of the metadata item to be retrieved. UTF-8 encodings
* are acceptable.
* @param value_type The datatype of the value associated with the key (if
* any).
* @return true if the key exists, else false.
* @note If the key does not exist, then `value_type` will not be modified.
*/
bool has_metadata(const std::string& key, tiledb_datatype_t* value_type) {
auto& ctx = ctx_.get();
tiledb_ctx_t* c_ctx = ctx.ptr().get();
int32_t has_key;
ctx.handle_error(tiledb_array_has_metadata_key(
c_ctx, array_.get(), key.c_str(), value_type, &has_key));
return has_key == 1;
}

/**
* Returns then number of metadata items in an open array. The array must
* be opened in READ mode, otherwise the function will error out.
Expand Down
18 changes: 18 additions & 0 deletions tiledb/sm/metadata/metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,24 @@ Status Metadata::get(
return Status::Ok();
}

Status Metadata::has_key(const char* key, Datatype* value_type, bool* has_key) {
assert(key != nullptr);

auto it = metadata_map_.find(key);
if (it == metadata_map_.end()) {
// Key not found
*has_key = false;
return Status::Ok();
}

// Key found
auto& value_struct = it->second;
*value_type = static_cast<Datatype>(value_struct.type_);
*has_key = true;

return Status::Ok();
}

uint64_t Metadata::num() const {
return metadata_map_.size();
}
Expand Down
11 changes: 11 additions & 0 deletions tiledb/sm/metadata/metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,17 @@ class Metadata {
/** Returns the number of metadata items. */
uint64_t num() const;

/**
* Checks if metadata has specified key.
*
* @param key The metadata key.
* @param value_type The datatype of the value.
* @param value Set to `1` if the array metadata has a key of the
* given name, else `0`.
* @return Status
*/
Status has_key(const char* key, Datatype* value_type, bool* has_key);

/**
* Sets the URIs of the metadata files that have been loaded
* to this object.
Expand Down

0 comments on commit 93fd276

Please sign in to comment.