Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions cpp/src/arrow/util/key_value_metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ Status KeyValueMetadata::Delete(int64_t index) {
}

Status KeyValueMetadata::DeleteMany(std::vector<int64_t> indices) {
if (indices.size() == 1) {
return Delete(indices[0]);
}
std::sort(indices.begin(), indices.end());
const int64_t size = static_cast<int64_t>(keys_.size());
indices.push_back(size);
Expand All @@ -121,11 +124,23 @@ Status KeyValueMetadata::DeleteMany(std::vector<int64_t> indices) {
++shift;
const auto start = indices[i] + 1;
const auto stop = indices[i + 1];
DCHECK_GE(start, 0);
DCHECK_LE(start, size);
DCHECK_GE(stop, 0);
DCHECK_LE(stop, size);

if (ARROW_PREDICT_TRUE(start < 0 || start > size)) {
return Status::IndexError("KeyValueMetadata::DeleteMany: Start index ", start - 1,
" out of bounds for metadata of size ", size);
}
Comment on lines +128 to +131

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Can you use ARROW_PREDICT_FALSE for error branches. (Have not analysed the full code, just caught this.)


if (ARROW_PREDICT_TRUE(stop < 0 || stop > size)) {
return Status::IndexError("KeyValueMetadata::DeleteMany: Stop index ", stop,
" out of bounds for metadata of size ", size);
}

for (int64_t index = start; index < stop; ++index) {
if (ARROW_PREDICT_TRUE(index < shift)) {
return Status::IndexError("KeyValueMetadata::DeleteMany: duplicate index ", index,
" in indices to delete");
}

keys_[index - shift] = std::move(keys_[index]);
values_[index - shift] = std::move(values_[index]);
}
Expand Down
6 changes: 6 additions & 0 deletions cpp/src/arrow/util/key_value_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ class ARROW_EXPORT KeyValueMetadata {
// Note that deleting may invalidate known indices
Status Delete(std::string_view key);
Status Delete(int64_t index);

/// \brief Delete metadata entries at specified index in keys and values array
/// \param indices Vector of distinct indices identifying the entries to
/// remove from the metadata.
/// \return Status indicating success or failure.

Status DeleteMany(std::vector<int64_t> indices);
Status Set(std::string key, std::string value);

Expand Down
41 changes: 41 additions & 0 deletions cpp/src/arrow/util/key_value_metadata_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,47 @@ TEST(KeyValueMetadataTest, Delete) {
ASSERT_OK(metadata.DeleteMany({}));
ASSERT_TRUE(metadata.Equals(KeyValueMetadata({"bb", "dd", "ee"}, {"2", "4", "5"})));
}
{
KeyValueMetadata metadata(keys, values);

std::string expected_error_message =
"Index error: KeyValueMetadata::DeleteMany: Start index -3 out of bounds for "
"metadata of size 7";

ASSERT_RAISES_WITH_MESSAGE(IndexError, expected_error_message,
metadata.DeleteMany({-2, -3}));
}

{
KeyValueMetadata metadata(keys, values);

std::string expected_error_message =
"Index error: KeyValueMetadata::Delete: index -1 is out of bounds for metadata "
"of size 7";

ASSERT_RAISES_WITH_MESSAGE(IndexError, expected_error_message,
metadata.DeleteMany({-1}));
}

{
KeyValueMetadata metadata(keys, values);

std::string expected_error_message =
"Index error: KeyValueMetadata::DeleteMany: Stop index 8 out of bounds for "
"metadata of size 7";

ASSERT_RAISES_WITH_MESSAGE(IndexError, expected_error_message,
metadata.DeleteMany({0, 8}));
}
{
KeyValueMetadata metadata(keys, values);
std::string expected_error_message =
"Index error: KeyValueMetadata::DeleteMany: duplicate index 1 in indices to "
"delete";

ASSERT_RAISES_WITH_MESSAGE(IndexError, expected_error_message,
metadata.DeleteMany({0, 0, 5, 2}));
}
}

} // namespace arrow
Loading