#pragma once
#include <executorch/runtime/core/named_data_map.h>
namespace executorch {
namespace ET_RUNTIME_NAMESPACE {
namespace internal {
class MergedDataMap final : public NamedDataMap {
public:
static Result<MergedDataMap> load(
const NamedDataMap* first,
const NamedDataMap* second) {
ET_CHECK_OR_RETURN_ERROR(
first != nullptr && second != nullptr,
InvalidArgument,
"Input data map is null.");
for (uint32_t k = 0; k < first->get_num_keys().get(); k++) {
const auto key = first->get_key(k).get();
const auto error = second->get_tensor_layout(key).error();
ET_CHECK_OR_RETURN_ERROR(
error == Error::NotFound || error == Error::NotImplemented,
InvalidArgument,
"Duplicate key %s.",
key);
}
return MergedDataMap(first, second);
}
ET_NODISCARD
Result<const TensorLayout> get_tensor_layout(
std::string_view key) const override {
auto layout = first_->get_tensor_layout(key);
if (layout.ok()) {
return layout.get();
}
if (layout.error() != Error::NotFound) {
return layout.error();
}
return second_->get_tensor_layout(key);
}
ET_NODISCARD
Result<FreeableBuffer> get_data(std::string_view key) const override {
auto data = first_->get_data(key);
if (data.error() != Error::NotFound) {
return data;
}
return second_->get_data(key);
}
ET_NODISCARD Error load_data_into(
ET_UNUSED std::string_view key,
ET_UNUSED void* buffer,
ET_UNUSED size_t size) const override {
return Error::NotImplemented;
}
ET_NODISCARD Result<uint32_t> get_num_keys() const override {
return first_->get_num_keys().get() + second_->get_num_keys().get();
}
ET_NODISCARD Result<const char*> get_key(uint32_t index) const override {
uint32_t total_num_keys = get_num_keys().get();
ET_CHECK_OR_RETURN_ERROR(
index < total_num_keys,
InvalidArgument,
"Index %" PRIu32 " out of range of size %" PRIu32,
index,
total_num_keys);
if (index < first_->get_num_keys().get()) {
return first_->get_key(index);
} else {
return second_->get_key(index - first_->get_num_keys().get());
}
}
MergedDataMap(MergedDataMap&&) noexcept = default;
~MergedDataMap() override = default;
private:
MergedDataMap(const NamedDataMap* first, const NamedDataMap* second)
: first_{first}, second_{second} {}
MergedDataMap(const MergedDataMap& rhs) = delete;
MergedDataMap& operator=(MergedDataMap&& rhs) noexcept = delete;
MergedDataMap& operator=(const MergedDataMap& rhs) = delete;
const NamedDataMap* first_;
const NamedDataMap* second_;
};
} } }