-
Notifications
You must be signed in to change notification settings - Fork 200
perf: [sc-60446] Enumerations loaded from schema execute generate_value_map in a background task
#5501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
perf: [sc-60446] Enumerations loaded from schema execute generate_value_map in a background task
#5501
Changes from all commits
28f97ce
dfac5cb
1e7324d
a80da79
1bacdaf
f266e07
344112a
881e63f
e1cbd6d
d6b70f1
620eb61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -33,6 +33,7 @@ | |||||||||||||||||||||||||||||||
| #include <iostream> | ||||||||||||||||||||||||||||||||
| #include <sstream> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| #include "tiledb/common/logger.h" | ||||||||||||||||||||||||||||||||
| #include "tiledb/common/memory_tracker.h" | ||||||||||||||||||||||||||||||||
| #include "tiledb/common/random/random_label.h" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
@@ -49,6 +50,7 @@ class EnumerationException : public StatusException { | |||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| Enumeration::Enumeration( | ||||||||||||||||||||||||||||||||
| const ContextResources& resources, | ||||||||||||||||||||||||||||||||
| const std::string& name, | ||||||||||||||||||||||||||||||||
| const std::string& path_name, | ||||||||||||||||||||||||||||||||
| Datatype type, | ||||||||||||||||||||||||||||||||
|
|
@@ -58,8 +60,10 @@ Enumeration::Enumeration( | |||||||||||||||||||||||||||||||
| uint64_t data_size, | ||||||||||||||||||||||||||||||||
| const void* offsets, | ||||||||||||||||||||||||||||||||
| uint64_t offsets_size, | ||||||||||||||||||||||||||||||||
| bool async, | ||||||||||||||||||||||||||||||||
| shared_ptr<MemoryTracker> memory_tracker) | ||||||||||||||||||||||||||||||||
| : memory_tracker_(memory_tracker) | ||||||||||||||||||||||||||||||||
| : resources_(resources) | ||||||||||||||||||||||||||||||||
| , memory_tracker_(memory_tracker) | ||||||||||||||||||||||||||||||||
| , name_(name) | ||||||||||||||||||||||||||||||||
| , path_name_(path_name) | ||||||||||||||||||||||||||||||||
| , type_(type) | ||||||||||||||||||||||||||||||||
|
|
@@ -94,6 +98,7 @@ Enumeration::Enumeration( | |||||||||||||||||||||||||||||||
| if (data_empty && offsets_empty) { | ||||||||||||||||||||||||||||||||
| // This is an empty enumeration so we're done checking for argument | ||||||||||||||||||||||||||||||||
| // validity. | ||||||||||||||||||||||||||||||||
| value_map_status_.emplace(Status::Ok()); | ||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
@@ -191,11 +196,36 @@ Enumeration::Enumeration( | |||||||||||||||||||||||||||||||
| throw_if_not_ok(offsets_.write(offsets, 0, offsets_size)); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| generate_value_map(); | ||||||||||||||||||||||||||||||||
| if (async) { | ||||||||||||||||||||||||||||||||
| tiledb::common::ThreadPool::Task value_map_future = | ||||||||||||||||||||||||||||||||
| resources.compute_tp().async( | ||||||||||||||||||||||||||||||||
| [](std::reference_wrapper<Enumeration> enumeration) { | ||||||||||||||||||||||||||||||||
| enumeration.get().generate_value_map(); | ||||||||||||||||||||||||||||||||
| return Status::Ok(); | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| std::reference_wrapper<Enumeration>(*this)); | ||||||||||||||||||||||||||||||||
| value_map_future_ = std::move(value_map_future); | ||||||||||||||||||||||||||||||||
|
Comment on lines
+200
to
+207
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
(and format) |
||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||
| generate_value_map(); | ||||||||||||||||||||||||||||||||
| value_map_status_.emplace(Status::Ok()); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| Enumeration::~Enumeration() { | ||||||||||||||||||||||||||||||||
| if (value_map_future_.valid()) { | ||||||||||||||||||||||||||||||||
| auto st = value_map_future_.wait(); | ||||||||||||||||||||||||||||||||
| if (!st.ok()) { | ||||||||||||||||||||||||||||||||
| tiledb::common::global_logger().warn( | ||||||||||||||||||||||||||||||||
| "Enumeration::~Enumeration(): Error computing value map: " + | ||||||||||||||||||||||||||||||||
| st.to_string()); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+214
to
223
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't log the warning; it's not important to tell the user that an operation they did not care for failed. |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| shared_ptr<const Enumeration> Enumeration::deserialize( | ||||||||||||||||||||||||||||||||
| Deserializer& deserializer, shared_ptr<MemoryTracker> memory_tracker) { | ||||||||||||||||||||||||||||||||
| const ContextResources& resources, | ||||||||||||||||||||||||||||||||
| Deserializer& deserializer, | ||||||||||||||||||||||||||||||||
| shared_ptr<MemoryTracker> memory_tracker) { | ||||||||||||||||||||||||||||||||
| auto disk_version = deserializer.read<uint32_t>(); | ||||||||||||||||||||||||||||||||
| if (disk_version > constants::enumerations_version) { | ||||||||||||||||||||||||||||||||
| throw EnumerationException( | ||||||||||||||||||||||||||||||||
|
|
@@ -233,6 +263,7 @@ shared_ptr<const Enumeration> Enumeration::deserialize( | |||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| return create( | ||||||||||||||||||||||||||||||||
| resources, | ||||||||||||||||||||||||||||||||
| name, | ||||||||||||||||||||||||||||||||
| path_name, | ||||||||||||||||||||||||||||||||
| static_cast<Datatype>(type), | ||||||||||||||||||||||||||||||||
|
|
@@ -242,6 +273,7 @@ shared_ptr<const Enumeration> Enumeration::deserialize( | |||||||||||||||||||||||||||||||
| data_size, | ||||||||||||||||||||||||||||||||
| offsets, | ||||||||||||||||||||||||||||||||
| offsets_size, | ||||||||||||||||||||||||||||||||
| true, | ||||||||||||||||||||||||||||||||
| memory_tracker); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
@@ -326,6 +358,7 @@ shared_ptr<const Enumeration> Enumeration::extend( | |||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| return create( | ||||||||||||||||||||||||||||||||
| resources_, | ||||||||||||||||||||||||||||||||
| name_, | ||||||||||||||||||||||||||||||||
| "", | ||||||||||||||||||||||||||||||||
| type_, | ||||||||||||||||||||||||||||||||
|
|
@@ -335,6 +368,7 @@ shared_ptr<const Enumeration> Enumeration::extend( | |||||||||||||||||||||||||||||||
| new_data.size(), | ||||||||||||||||||||||||||||||||
| new_offsets_ptr, | ||||||||||||||||||||||||||||||||
| new_offsets_size, | ||||||||||||||||||||||||||||||||
| false, | ||||||||||||||||||||||||||||||||
| memory_tracker_); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
@@ -413,15 +447,36 @@ void Enumeration::serialize(Serializer& serializer) const { | |||||||||||||||||||||||||||||||
| uint64_t Enumeration::index_of(const void* data, uint64_t size) const { | ||||||||||||||||||||||||||||||||
| std::string_view value_view(static_cast<const char*>(data), size); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| auto iter = value_map_.find(value_view); | ||||||||||||||||||||||||||||||||
| if (iter == value_map_.end()) { | ||||||||||||||||||||||||||||||||
| const auto& values = value_map(); | ||||||||||||||||||||||||||||||||
| auto iter = values.find(value_view); | ||||||||||||||||||||||||||||||||
| if (iter == values.end()) { | ||||||||||||||||||||||||||||||||
| return constants::enumeration_missing_value; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| return iter->second; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||
| * Add a value to a value map. Checks for duplicates. | ||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||
| * @param sv A string view of the data to add. | ||||||||||||||||||||||||||||||||
| * @param index The index of the data in the Enumeration. | ||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||
| static void add_value_to_map( | ||||||||||||||||||||||||||||||||
| Enumeration::EnumerationValueMap& value_map, | ||||||||||||||||||||||||||||||||
| std::string_view& sv, | ||||||||||||||||||||||||||||||||
| uint64_t index) { | ||||||||||||||||||||||||||||||||
| const auto res = value_map.emplace(sv, index); | ||||||||||||||||||||||||||||||||
| if (!res.second) { | ||||||||||||||||||||||||||||||||
| throw EnumerationException( | ||||||||||||||||||||||||||||||||
| "Invalid duplicated value in enumeration '" + std::string(sv) + "'"); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| void Enumeration::generate_value_map() { | ||||||||||||||||||||||||||||||||
| auto timer = | ||||||||||||||||||||||||||||||||
| resources_.stats().start_timer("Enumeration::generate_value_map"); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| auto char_data = data_.data_as<char>(); | ||||||||||||||||||||||||||||||||
| if (var_size()) { | ||||||||||||||||||||||||||||||||
| auto offsets = offsets_.data_as<uint64_t>(); | ||||||||||||||||||||||||||||||||
|
|
@@ -438,7 +493,7 @@ void Enumeration::generate_value_map() { | |||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| auto sv = std::string_view(char_data + offsets[i], length); | ||||||||||||||||||||||||||||||||
| add_value_to_map(sv, i); | ||||||||||||||||||||||||||||||||
| add_value_to_map(value_map_, sv, i); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||
| uint64_t i = 0; | ||||||||||||||||||||||||||||||||
|
|
@@ -448,20 +503,12 @@ void Enumeration::generate_value_map() { | |||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| while (i * stride < data_.size()) { | ||||||||||||||||||||||||||||||||
| auto sv = std::string_view(char_data + i * stride, stride); | ||||||||||||||||||||||||||||||||
| add_value_to_map(sv, i); | ||||||||||||||||||||||||||||||||
| add_value_to_map(value_map_, sv, i); | ||||||||||||||||||||||||||||||||
| i += 1; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| void Enumeration::add_value_to_map(std::string_view& sv, uint64_t index) { | ||||||||||||||||||||||||||||||||
| const auto res = value_map_.emplace(sv, index); | ||||||||||||||||||||||||||||||||
| if (!res.second) { | ||||||||||||||||||||||||||||||||
| throw EnumerationException( | ||||||||||||||||||||||||||||||||
| "Invalid duplicated value in enumeration '" + std::string(sv) + "'"); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| } // namespace tiledb::sm | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| std::ostream& operator<<( | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like a "data class" like
Enumerationusing a "behavior class" likeContextResources; it will make removing theContextdependency on the C API harder.